14

C语言经典面试题详解(第1节)

 3 years ago
source link: https://blog.popkx.com/explanation-of-classic-interview-questions-in-c-language/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

C语言经典面试题详解(第1节)

发表于 2019-02-05 20:02:04   |   已被 访问: 757 次   |   分类于:   C语言   |   暂无评论

程序员们求职时,常常会被要求回答一些“奇葩”而又不实用的问题,但这些题目确实能够从某种程度上反映出一个人的技术水平,作为求职者的我们,既然无力改变这种招聘流程,就只能努力提升自己——从这些“奇葩”的面试题目中找出自己的不足。

f2b387fff01dddb1924a71a0240589a9.png

先来看看这个问题

以下C语言代码输出什么?这个题目出自台湾某著名杀毒软件公司的笔试题。

int k = 8;
void main()
{
    int k=k;
    printf("%d\n", k);
}
3aecb8bcb19756dd84aedcf6c7cb9b0e.png
A. 输出 k=随机数
B. 输出 k=8
C. 编译报错
D. 输出 k=0

这个题目看起来的确很怪异,而且我相信在实际开发中,没有程序员会写这样的代码。但是现在先就题论题,答案是哪一个呢,以及为什么呢?得到答案最简单粗暴的方法就是做实验,所以新建 t.c 文件输入以上代码,编译执行结果如下:

# gcc t.c
# ./a.out
0

这里显示的是 0,那答案就选 D 咯?还不能这么早下结论,来考虑一下为什么程序会输出 0。考虑这种类型的问题,显然应该从编译器的角度出发。程序员们写出的 C语言代码需要被编译为可执行文件才能被投入运行,编译的总体流程如下:

27f37e6871e3a87490fac91e40784fd5.png

C语言源代码是以字节流的形式存储在磁盘中的,词法分析负责从字节流从整理彼此独立的词语,方便进行语法分析。语法分析器遇到 int k 时,一般会立即将其标记为 int 型的变量,然后再继续分析之后的内容。所以对于语法分析器来说, int k = k 这样奇怪的语句其实相当于下面这两句:
int k;
k = k;

这就明白了,这两句其实就是定义了一个 int 型变量,并且将它赋值给自己。现在我们改写一下上面的题目:

int k = 8;
void main()
{
    int k;
    k = k;
    printf("%d\n", k);
}

答案已经很明确了,printf 里的 k 显然是属于 main() 里的定义的局部变量 k,而这里的 k 并没有赋初值,所以最终输出的值是随机的,未定义的,应该选 A。

7df5da4809835689c3a85db00da77342.png

再看一个问题

下面这段C语言程序输出什么?这个问题出自国内某著名互联网公司的笔试题目。

#include <stdio.h>

int main()
{
     int a, x;
     for(a=0,x=0; a<=1 && !x++; )
         a++;
     printf("a=%d, x=%d\n", a, x);

     for(a=0,x=0; a<=1 && !x++; a++)
         a++;
     printf("a=%d, x=%d\n", a, x);

     return 0;
}
9b0efe8ca7af8bb209143a0596368983.png

先来看第一个 printf,在 for 中 a 和 x 都被赋初值为 0,接着按照如下流程执行:
  • 此时 a=0,x=0,判断 a<=1 && !x++,为真,执行了 a++;
  • 此时 a=1,x=1,判断 a<=1 && !x++,为假,跳出 for;
  • 此时 a=1,x=2。

再来分析一下第二个 printf,在 for 中 a 和 x 都被赋初值为 0,接着按照如下流程执行:

  • 此时 a=0,x=0,判断 a<=1 && !x++,为真,执行了 for 外的 a++;
  • 执行 for 里的 a++, 此时 a=2,x=1,判断 a<=1 && !x++,为假,跳出 for;
  • 此时 a=2,x=1。

到这里,相信大家应该已经知道上面的 C 语言程序会输出什么了,这里再写一下吧:

# ./a.out 
a=1, x=2
a=2, x=1

分析该问题的关键在于C语言中 a&&b 表达式的处理,需要注意的是这一点:如果 a 为假,就已经能够判断 a&&b 整个表达式为假了,因此 b 就不会被执行了。只有 a 为真,b 才有机会被执行。

8079eb4dc6a2e3858c303dfebcf7fc7f.png

类似的表达式还有 a||b,读者能够分析出什么情况下,b 不会被执行吗?

阅读更多:   C语言


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK