笔试题两道

    昨天师兄去参加笔试,回来和我探讨了几题蛮有意思的,现在贴上来两题分享一下。

第一题

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          是一个指向struct类型的指针,其指针值为 0,所以其作用就是把从地址 0 开始的存储空间映射为一个 struct 类型的对象。

   2.(&((struct*)0)->e)   表示取结构体指针(struc*)0的成员e的地址

   3.强制转换为 unsigned int型。

    由于上面提到0是可以改变的所以还有一种方法:(unsigned int)(&((SStudent*)1000)->mobile_number) - (unsigned int)((SStudent*)1000);//(1000是任意取得)

 

总结:c/c++还有很多机制让我去发现,昨天真的有多了解了一点。其实考题并不难,知道一点就稍微能作对一点,所以应付这种题目,还是要好好看书。


2015.12.12

今天看了《c和指针》这本书里面提到了计算结构体的偏移量可以使用下面这个函数

offsetof(type,member);/*这个函数,必须包含stddef.h头文件*/

然后试了一下确实和我们上面提到的表达式计算结果是一样的,然后我无聊翻了翻文件里面的stddef.h这个头文件打开吓我一大跳。

#define offsetof(s,m)   (size_t)&(((s *)0)->m)

上面是其中一个定义,仔细看和我们上面的如出一辙,所以以后我们有两种方法来计算偏移量,直接利用库函数,或者利用他的定义来。

 

   

posted on 2015-10-30 10:39  延长比赛  阅读(206)  评论(3编辑  收藏  举报

导航