闲来无事看两个好玩的C语言面试题

Posted ksiwnhiwhs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闲来无事看两个好玩的C语言面试题相关的知识,希望对你有一定的参考价值。

昨天最后一天工作日,让我碰到了两个有意思的C语言编程问题,周末前权当轻松一下,挺有意思就过去了,因为今晚雨夜通宵,就把它们记录了下来。

事件1:关于结构体对齐和packed属性

下午跟同事下楼抽烟,聊到一个有意思的问题,不讲故事了,直接看问题:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct data{
        char a;
        int b;
};

int main()
{
        char *mem = calloc(1, 100);
        struct data *dt;

        memset(mem, ‘c‘, 1);
        memset(mem+1, 2, 1);
        memset(mem+2, 0, 99);
        dt = (struct data*)mem;

        printf("%c  %d
", dt->a, dt->b);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

很多人用这种方法给进行数据转换,想当然会认为a就是’c’,b在小端机器上就是2,大端机器上则是0x02000000,嗯,还不错,知道大小端。但是答案还是错了。

其实struct dt的size是8,并不是1+4=5,结构体默认被对齐了,所有在字段a后面会有3个字节的填充,如果直接用mem强转,那么3个填充的0恰好覆盖掉预期中的2,造成结果的错误。上面的代码正确答案应该是:c 0

如果你把结构体dt定义成:

struct data{
        char a;
        char c;
        int b;
}
  • 1
  • 2
  • 3
  • 4
  • 5

就知道那个丢失的2去哪里了。

如果希望达到预期的c 2,则只需要如下定义结构体即可:

struct data{
        char a;
        int b;
}__attribute__((packed));
  • 1
  • 2
  • 3
  • 4

这种问题在CPU和网络协议以及持久层序列化之间的矛盾处理中非常常见。毕竟不管是网络带宽也好还是存储介质也罢,每一个字节都是钱,能少一个字节甚至一个bit都是在节约,然而对于CPU而言,时间就是钱,空间反而不重要,所以CPU倾向于内存的对齐,于是乎CPU在处理网络协议头的时候非常容易犯上面的错,当前的Linux内核一般都不用结构体强转,都是手工转换,对于序列化程序而言,更是有诸如XML,json等上层库可用,免去了程序员的很多工作。

事件2:关于编译期的sizeof

周五下班早,这是在下班的路上被人怼的:
技术图片
说实话,这个问题我不会,瞬间感觉被鄙视,然而我本来就承认自己不会编程,也就无所谓了。好在我有手机云编译器,就试了一下:
技术图片

然后,我用这个问题调侃了朋友圈的几乎所有同行,当然除了前领导,现领导以及业界的比较牛的人,网上能搜到名字的人我也不敢调侃,这些人如果回答对了,显得我毫无水平且具有挑衅性情,万一回答不出来,我还想混呢…而且我怕被打…其他同等级别同等水平的就无所谓了,反正就是经常互相调侃,我这不就是被调侃的吗?

果然啊,不出所料,有人回答5,有人回答6,当然回答6的偏多。哈哈, 很多人跟我一样不会编程…我也就没什么觉得悲哀的了。

后来通过询问以及自己手机查找资料,知道了答案。

sizeof是一个编译期间预处理就决定结果的操作,编译期肯定不会执行任何语句,i++也好,++i也罢,都不会执行,到了运行期,sizeof的结果已经有了,就更不会去执行i++了…

后来朋友圈的回复不断,有人挖出了C语言标准,有人挖出了汇编码,有人挖出了编译器规程,不过最有意义的还是下面的图了:
技术图片


就上面两个题目,面试的时候去问,相信大批量的人回答不对。但是这两个问题其实也就是知道了也就知道了,并没有什么一锤定音的功能,万万不能用这些问题去评价某个人,它们只是检测一个人对C语言的熟悉程度而已,编程者的事情知道的不多,不多说。


顺便一说,我学过谭浩强的书,但学的不好。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow





以上是关于闲来无事看两个好玩的C语言面试题的主要内容,如果未能解决你的问题,请参考以下文章

C++ 接雨水,不看后悔系列,解一道高频面试题

必看面试题

这个C语言面试题真的有水平,强烈推荐!

求助c语言编写一个字节位互换

曾经的华为C面试题,一点就通

python面试题