天天看点

C++进阶

1、

<a href="http://my.oschina.net/jacedy/blog/343692#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<code>#include &lt;iostream&gt;</code>

<code>using</code> <code>namespace</code> <code>std;</code>

<code>struct</code> <code>simpletype</code>

<code>{</code>

<code>    </code><code>double</code> <code>db;</code>

<code>    </code><code>char</code> <code>sz;</code>

<code>    </code><code>int</code> <code>n;</code>

<code>};</code>

<code>void</code> <code>main()</code>

<code>    </code><code>simpletype a;</code>

<code>    </code><code>int</code> <code>nsize = </code><code>sizeof</code><code>(a);</code>

<code>    </code><code>cout&lt;&lt;nsize&lt;&lt;endl;</code>

<code>}</code>

<code>//输出:nsize = 16</code>

解析:这里nsize的值并非13,而是16。这设计结构体的字节对齐问题。编译器在为结构体变量分配空间时,保证下一个成员的偏移量应为该成员数据类型长度的整数倍。首先为db 成员分配空间,假设起始偏移位置从0开始,db 成员将占用0,1,2,3,4,5,6,7共8字节。接下来为成员变量sz 分配空间,由于char 类型占用1字节,sz 将占据8的位置,因为当前位置8与1是整除的。最后为n 成员分配空间,该成员为int 类型,占用4字节。当前偏移位置为9,并不是4的整数倍,因此需要空出3字节(9、10、11),n 从12的位置开始分配4字节的空间。这样就导致了实际分配的大小与“理论上”的大小不一致。

2、

19

<code>void</code> <code>outputstring(</code><code>char</code> <code>data[])</code>

<code>    </code><code>int</code> <code>isize = </code><code>sizeof</code><code>(data);</code>

<code>    </code><code>cout&lt;&lt;</code><code>"isize = "</code><code>&lt;&lt;isize&lt;&lt;endl;</code>

<code>    </code><code>int</code> <code>ilen = </code><code>sizeof</code><code>(</code><code>"家园"</code><code>);</code>

<code>    </code><code>cout&lt;&lt;</code><code>"'家园'的大小为:"</code><code>&lt;&lt;ilen&lt;&lt;endl;</code>

<code>    </code><code>outputstring(</code><code>"家园"</code><code>);</code>

<code>//输出:</code>

<code>//'家园'的大小为:5</code>

<code>//isize = 4</code>

解析:作为参数传递的数组其实是以指针的形式传递的,所以在使用sizeof获得数组参数的长度时是4,而不是数字长度。

3、

<code>    </code><code>int</code> <code>i = 2;</code>

<code>    </code><code>cout&lt;&lt;(i = 3 * 5, 2 * 4)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;i&lt;&lt;endl;</code>

<code>    </code><code>int</code> <code>x = 9, y = 7;</code>

<code>    </code><code>int</code> <code>n = x &gt; y ? (x-y):(x+y);    </code><code>//三目元表达式</code>

<code>    </code><code>cout&lt;&lt;n&lt;&lt;endl;</code>

<code>//8</code>

<code>//15</code>

<code>//2</code>

解析:因为赋值运算符的优先级比逗号运算符的优先级高,所以在上面的代码中,会先计算赋值表达式的值,也就是i=3*5,然后再计算逗号表达式的值,所以 i 的值为15,而逗号表达式的值却是8.

又因为条件运算符的优先级高于赋值运算符,所以会先计算 x&gt;y 的值,然后执行符合条件的表达式(x-y),最后将结果赋值给n。

4、x=x+1、x+=1、++ x 、x ++哪一个的效率最高?

解答:x=x+1最低,因为它的的执行过程为:

(1)读取右x的地址;

(2)x+1;

(3)读取左x的地址;

(4)将右值传给左边的x(编译器并不认为左右x的地址相同)。

其次,x+=1,执行过程如下:

(1)读取左x的地址;

(3)将得到的值传给x(因为x的地址已经读出)。

x ++ 相当于下列代码 :

(1)y = x;

(2)x += 1;

(3)return y;

++ x 的效率最高,其执行过程为:

(2)x自增1。

5、

<code>int</code> <code>i=1, j=2, k=3, d=4;</code>

<code>cout&lt;&lt;i+++j&lt;&lt;endl;            </code><code>//输出:3,先(i++),再(+j),++比+优先级高</code>

<code>cout&lt;&lt;(++k)*(++k)&lt;&lt;endl;        </code><code>//输出:20,先k自加1等于4,再k自加1等于5,然后4*5=20</code>

<code>(d++)*(d++);</code>

<code>cout&lt;&lt;d&lt;&lt;endl;            </code><code>//输出:6</code>

<code>!i &amp;&amp; j++;</code>

<code>cout&lt;&lt;i&lt;&lt;endl&lt;&lt;j&lt;&lt;endl;  </code><code>//输出:2   3,因为!i运算结束后,整个表达式已肯定为假,所以不必再去计算后面的式子</code>

6、if("a" == a) 比 if(a == "a") 更好,因为如果把”==“误写成”=“,编译器就能检查到错误,因为编译器不允许对常量进行赋值。

7、自动转换遵循以下规则:

1)若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2)转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。

     a.若两种类型的字节数不同,转换成字节数高的类型

     b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型

3)所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4)char型和short型参与运算时,必须先转换成int型。

5)在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。

 扩展:

       (1). 在表达式中,char 和 short 类型的值,无论有符号还是无符号,都会自动转换成 int 或者 unsigned int(如果 short 的大小和 int 一样,unsigned short 的表示范围就大于 int,在这种情况下,unsigned short 被转换成 unsigned int)。因为它们被转换成表示范围更大的类型,故而把这种转换称为“升级(promotion)”。 

      (2). 按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们应该已经被升级成了 int 或者 unsigned int。 

      (3). 在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。 

      (4). 在赋值语句中,= 右边的值在赋予 = 左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。 

      5. 作为参数传递给函数时,char 和 short 会被转换成 int,float 会被转换成 double。使用函数原型可以避免这种自动升级。

8、交换两个数:

<code>//方法一:</code>

<code>temp = a;</code>

<code>a = b;</code>

<code>b = temp;</code>

<code>//方式二:</code>

<code>a = a + b;</code>

<code>b = a - b;</code>

<code>a = a - b;</code>

<code>//方式三:(推荐)</code>

<code>a = a ^ b;</code>

<code>b = a ^ b;</code>

9、在c++中调用被c编译器编译后的函数,为什么要加 extern "c"?

答:c++语言支持函数重载,c语言不支持函数重载,函数被c++编译后在库中的名字与c语言的不同。假设某个函数的名称为:void fun(int x, int y),该函数被c编译器编译后在库中的名字为_fun,而c++编译器则会产生像_fun_int_int之类的名字。c++提供了c连接交换指定符号extern ”c“解决名字匹配问题。

10、

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

<code>#include &lt;cstring&gt;</code>

<code>class</code> <code>a</code>

<code>    </code> 

<code>class</code> <code>b</code>

<code>    </code><code>char</code> <code>a, b;</code>

<code>    </code><code>b();</code>

<code>    </code><code>~b();</code>

<code>struct</code> <code>c</code>

<code>struct</code> <code>d</code>

<code>    </code><code>int</code> <code>a;</code>

<code>    </code><code>char</code> <code>b;</code>

<code>struct</code> <code>e</code>

<code>    </code><code>long</code> <code>a1;</code>

<code>    </code><code>short</code> <code>a2;</code>

<code>struct</code> <code>f</code>

<code>    </code><code>static</code> <code>int</code> <code>b;</code>

<code>int</code> <code>main()</code>

<code>    </code><code>a *p1= </code><code>new</code> <code>a();</code>

<code>    </code><code>a p2;</code>

<code>    </code><code>a *p3;</code>

<code>    </code><code>char</code> <code>*ss1 = </code><code>"0123456789"</code><code>;</code>

<code>    </code><code>char</code> <code>ss2[] = </code><code>"0123456789"</code><code>;</code>

<code>    </code><code>char</code> <code>ss3[100] = </code><code>"0123456789"</code><code>;</code>

<code>    </code><code>int</code> <code>ss4[100];</code>

<code>    </code><code>char</code> <code>q1[] = </code><code>"abcdef"</code><code>;</code>

<code>    </code><code>char</code> <code>q2[] = </code><code>"a\n"</code><code>;</code>

<code>    </code><code>char</code> <code>*q3 = </code><code>"a\n"</code><code>;</code>

<code>    </code><code>string x[] = {</code><code>"aaa"</code><code>, </code><code>"bbb"</code><code>, </code><code>"ccc"</code><code>};</code>

<code>    </code><code>void</code> <code>*i;</code>

<code>    </code><code>char</code> <code>*str1 = (</code><code>char</code> <code>*)</code><code>malloc</code><code>(100);</code>

<code>    </code><code>void</code> <code>*str2 = (</code><code>void</code> <code>*)</code><code>malloc</code><code>(100);</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(p1): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(p1)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(p2): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(p2)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(p3): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(p3)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(ss1): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(ss1)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(*ss1): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(*ss1)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(ss2): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(ss2)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(ss3): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(ss3)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(ss4): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(ss4)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(q1): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(q1)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(q2): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(q2)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(q3): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(q3)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(x): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(x)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(a): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(a)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(b): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(b)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(c): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(c)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(d): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(d)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(e): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(e)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(f): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(f)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(str1): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(str1)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(str2): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(str2)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof("</code><code>"): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(</code><code>""</code><code>)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(\"明\"): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(</code><code>"明"</code><code>)&lt;&lt;endl;</code>

<code>    </code><code>cout&lt;&lt;</code><code>"sizeof(i): "</code><code>&lt;&lt;</code><code>sizeof</code><code>(i)&lt;&lt;endl;</code>

<code>/*输出:</code>

<code>sizeof(p1): 4</code>

<code>sizeof(p2): 1</code>

<code>sizeof(p3): 4</code>

<code>sizeof(ss1): 4</code>

<code>sizeof(*ss1): 1</code>

<code>sizeof(ss2): 11</code>

<code>sizeof(ss3): 100</code>

<code>sizeof(ss4): 400</code>

<code>sizeof(q1): 7</code>

<code>sizeof(q2): 3</code>

<code>sizeof(q3): 4</code>

<code>sizeof(x): 48</code>

<code>sizeof(a): 1</code>

<code>sizeof(b): 2</code>

<code>sizeof(c): 1</code>

<code>sizeof(d): 8</code>

<code>sizeof(e): 8</code>

<code>sizeof(f): 4</code>

<code>sizeof(str1): 4</code>

<code>sizeof(str2): 4</code>

<code>sizeof(): 1</code>

<code>sizeof("明"): 3</code>

<code>sizeof(i): 4</code>

<code>*/</code>

解析:

        空类所占空间为1,单一继承的空类也为1,多继承的空类还是1,但虚继承涉及到虚表(虚指针),其所占空间为4.

11、类中的this指针有以下特点:

(1)this只能在成员函数中使用,在全局函数、静态函数中都不能使用this;

(2)this在成员函数的开始前构造,在成员函数结束后清除;

12、c++中有了malloc/free,为什么还要new/delete?

答:malloc和free是c++/c语言的标准库函数,new和delete是c++的运算符。对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于new/delete。因此c++需要一个能够完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的delete。

13、

<code>public</code><code>:</code>

<code>    </code><code>virtual</code> <code>f()</code>

<code>    </code><code>{</code>

<code>        </code><code>cout&lt;&lt;</code><code>"a"</code><code>&lt;&lt;endl;</code>

<code>    </code><code>}</code>

<code>class</code> <code>b : </code><code>public</code> <code>a</code>

<code>        </code><code>cout&lt;&lt;</code><code>"b"</code><code>&lt;&lt;endl;</code>

<code>    </code><code>a* pa = </code><code>new</code> <code>a();</code>

<code>    </code><code>pa-&gt;f();</code>

<code>    </code><code>b* pb = (b *)pa;</code>

<code>    </code><code>pb-&gt;f();</code>

<code>    </code><code>delete</code> <code>pa, pb;</code>

<code>    </code><code>pa = </code><code>new</code> <code>b();</code>

<code>    </code><code>pb = (b *)pa;</code>

<code>a</code>

<code>b</code>

C++进阶

14、

<code>#include&lt;iostream&gt;</code>

<code>    </code><code>char</code> <code>a[3];</code>

<code>    </code><code>virtual</code> <code>void</code> <code>aa() {};</code>

<code> </code> 

<code> </code><code>class</code> <code>b : </code><code>virtual</code> <code>public</code> <code>a</code>

<code> </code><code>{</code>

<code>   </code><code>char</code> <code>b[3];</code>

<code>   </code><code>virtual</code> <code>void</code> <code>bb() {};</code>

<code> </code><code>};</code>

<code> </code><code>class</code> <code>c : </code><code>public</code> <code>a</code>

<code>   </code><code>char</code> <code>c[3];</code>

<code>   </code><code>virtual</code> <code>void</code> <code>cc() {};</code>

<code>   </code><code>a a;</code>

<code>   </code><code>b b;</code>

<code>   </code><code>c c;</code>

<code>   </code><code>cout&lt;&lt;</code><code>sizeof</code><code>(a)&lt;&lt;endl;</code>

<code>   </code><code>cout&lt;&lt;</code><code>sizeof</code><code>(b)&lt;&lt;endl;</code>

<code>   </code><code>cout&lt;&lt;</code><code>sizeof</code><code>(c)&lt;&lt;endl; </code>

<code>   </code><code>return</code> <code>0;</code>

<code> </code><code>}</code>

<code></code>

继续阅读