C/C++易错难点笔记03

悠悠 2022-08-04 10:56 218阅读 0赞

在做C++各类题目的过程中,有很多题目看似,却有点难(对于我来说~~),所以我将这些题目积累慢慢积累下来,并记录。

1. 在32 bit系统中函数foo(2^31-3)的值是:

  1. int foo(int x)
  2. {
  3. return x&-x;
  4. }

解析:2^31是异或的意思,x的值是1010,x&-x的意思是x与-x,负x的二进制表示是:绝对值取反加1。所以最后的值是2。

2. unsigned char和char

下面代码输出结果;

  1. unsigned char ui= 0x80;
  2. printf("0x%x\n", ~ui>>3+1);
  3. char i= 0x80;
  4. printf("0x%x\n", ~i>>3+1);

解析:先取反,然后在加,最后移位操作。**取反前字符数据会自动转换成整形**unsigned char –> unsigned int;char –> int。所以ui转成了0x00000080,i转成了0xffffff80(因为i为有符号型字符变量,且符号位为1,转成整形时,高位补1)。
答案:0xfffffff7,0x7

3. union问题

  1. union
  2. {
  3. int i;
  4. char x[2];
  5. }a;
  6. int _tmain(int argc, _TCHAR* argv[])
  7. {
  8. a.x[0] = 10;
  9. a.x[1] = 1;
  10. printf("%d",a.i);
  11. system("pause");
  12. return 0;
  13. }

解析:联合占4字节,第一字节为10(0000 1010),第二字节为1(0000 0001),所以i的值就是:0x10A。
答案:266

4. 类成员函数调用

下面成员函数调用会报错吗?

  1. class A {
  2. public:
  3. int m;
  4. void print() { cout << "A\n"; }
  5. };
  6. A *pa = 0;
  7. pa->print();

答:不会,与程序员面试宝典的P147页那题一样的原理。并不是类没有初始化就不能调用类的成员函数,如果成员函数没有调用类的成员变量就不会报错。

5. 变量在内存中存放问题

下面输出结果是多少?

  1. struct data
  2. {
  3. int a;
  4. unsigned short b;
  5. };
  6. int main(void)
  7. {
  8. data mData;
  9. mData.b = 0x0102;
  10. char *pData = (char *)&mData;
  11. printf("%d %d", sizeof(pData), (int)(*(pData + 4)));
  12. return 0;
  13. }

答:4 2 。第一个是指针,第二个设计到变量在内存中的存放问题。
解析:结构体的成员在内存中顺序存放,所占内存地址依次增高,第一个成员处于低地址处,最后一个成员处于最高地址处, 。
这里写图片描述
注意:数据变量不论是结构体,类,还是基本变量,在内存中的存储方式是一致的,这与变量是存放在栈、堆、全局区是没有关系的。下面以一个变量在内存中的形式来说明.
这里写图片描述
上图说明了一个int类型在内存中占4个字节,每个字节中是如何存放变量的哪一位的。更清晰用下图表示。
这里写图片描述
总结:一个int型变量在内存中是这样存放的:首先变量指向它所占4字节的低地址位置,接下来4字节的地址都属于这个变量,而每一个字节存放的内容是从高往低的,也就是说高地址存放变量的高位数据。

6. 返回值加const

下面两种写法有区别吗?

  1. int GetInt(void)
  2. const int GetInt(void)

下面呢?

  1. A GetA(void)
  2. const A GetA(void)

在看

  1. A* GetA(void)
  2. const A* GetA(void)

答:无区别,无区别,有区别。
解析:一言蔽之,函数返回值采用值传递的方式时加不加const是没有区别的。但是以指针传递是有区别的,这能防止返回值为左值。

发表评论

表情:
评论列表 (有 0 条评论,218人围观)

还没有评论,来说两句吧...

相关阅读