昨天师兄去参加笔试,回来和我探讨了几题蛮有意思的,现在贴上来两题分享一下。
第一题
char c = 0xff; // 1111 1111 printf("%d",c); //以整数形式输出
有人直接写出是255,其实这是没有深入去研究,我也会经常犯这种错误;
下面我们仔细来探讨下,char是八位的有符号的,所以他的大小范围是在 -128~127 ,然本体我们说255必然是错的了;如果换位unsigned char的话,那么输出255肯定是对的。
下面我们探讨答案是多少,有些人可能直接转化为负数 -127,这些人是木有搞懂存放机制,负数在内存在是以补码的形式出现的。
所以这题真正的答案是 -1。
在这里提一下补码——》数值的转化有两种:
1)减一取反(这是逆向思维,因为得到补码是取反加一);
2)加一取反
第二种方法我们要讲一下。
参考:http://blog.csdn.net/studyvcmfc/article/details/7606292
有:源码=【【源码】补码】补码
这种方法在计算上会避免调用一些进位,会省掉很多事情,虽然前一中也很简单,但还是推荐这种。
注:这种方法其实是师兄力荐的,我开始是反对的,后来被说服了。
第二题:
描述:我们知道有一个存储学生信息的结构体,但我们不知道结构体内具体包含哪些信息,尽管如此,我们了解到学生信息结合体重包含了一个电话号码字段,如下
struct student { .... int mobile_number; .... }SStudent;
请用c++表达式计算出mobile_number在SStudent中的偏移量。
首先我们要了解偏移量,计算机汇编语言中的偏移量定义为:把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为“有效地址或偏移量”。
了解之后我们就可以写出代码了,其实代码很简单。
(unsigned int)(&((SStudent*)0)->mobile_number);
这一行代码就可以实现出来,下面我们来进行解释。参考其他大神的解释。
引用:http://blog.csdn.net/niu91/article/details/17881773
1.(struct*)0 表示将常量0强制转化为struc*型指针所指向的地址,这里0位起始地址的值,如果换成其他数值,后面的也相应改变。已测过。为了更好地算出偏移量,取0是很好的方法
2.&(((struct*)0)->e) 表示取结构体指针(struc*)0的成员e的地址
3.强制转换为 unsigned int型。
由于上面提到0是可以改变的所以还有一种方法:(unsigned int)(&((SStudent*)1000)->mobile_number) - (unsigned int)((SStudent*)1000);//(1000是任意取得)
总结:c/c++还有很多机制让我去发现,昨天真的有多了解了一点。其实考题并不难,知道一点就稍微能作对一点,所以应付这种题目,还是要好好看书。