国外某嵌入式公司的面试题题外话,真的没有意义吗?

91百科网 78 0

在C语言程序开发中,程序员可以在定义数组时对其进行初始化,并且只允许初始化部分元素。 未明确指定初始值的元素将设置为零,例如:

int a[5] = {1, 2};

这行C语言代码执行后,数组a中的元素将为1,2,0,0,0。这是C语言中数组的基础知识点。 但遗憾的是,从我昨天在圈子里分享的一个面试题来看,仍然有一些C语言程序员认为,没有显式给出初始值的数组元素的值是未定义的。 以下是一家国外嵌入式公司的面试题。 有人在 StackOverflow 上提出了一个问题,我觉得这个问题很有趣:

某国外嵌入式公司面试题

题外话

好像每次我分享一些面试题,都会有人认为我是“孔乙己”。 担心这些面试问题是没有意义的。 但这真的没有意义吗? 首先要明确的是,分析面试题并不意味着提倡面试题中的C语言代码编写,而是讨论隐藏在其背后的基础知识。 例如,如果读者不能理解C语言中数组初始化的本质,他将无法得到这个问题的正确答案。

事实上,很多公司在招聘的时候,有些面试题或者笔试题看起来很奇怪,不符合标准的开发规范,所以有的程序员认为问这样的面试题完全没有意义。 但事实上,这些疑问可能来自于公司内部某个项目的重大bug。 短暂的面试时间不可能完整地描述出这个bug,所以我们必须将其抽象成一个看起来很“冷”的面试问题。 审查求职者。

考察求职者

如果求职者基础不扎实,以后可能会犯同样的错误,这是不允许的。 因此,对于我们求职者来说,当我们收到这些面试题时,首先想到的应该是它们背后隐藏着哪些知识点。 正确的做法是查漏补缺。

分析

有很多读者愿意这样做。 他们看到问题后,立即在自己的设备上编写相关的C语言代码并编译执行。 然而,他们似乎得到了两个答案,如下所示。 到底是怎么回事?

1, 0, 0, 0, 0
// 或者
1, 0, 1, 0, 0

其实这道题主要考察两个知识点。 一是前面提到的C语言数组初始化,二是C语言语句的“序列点”概念。 (关于“顺序点”,可以参考我之前的文章:《这段C语言代码虽然简单,但它隐藏的问题很容易被很多程序员忽视》)

这是怎么回事?

出现这两个结果的原因是 int a[5]={a[2]=1}; 事实上,C语言标准并没有明确定义(至少在C99中)。 就这个问题而言,唯一明确的是a[0]会被设置为1,其他一切都不会决定结果。

C语言程序员应该对C标准有一定的了解,这个问题只是一个机会。

首先有读者质疑是否int a[5]={a[2]=1}; 在C语言中是合法的。 所以先查一下相关标准:数组a是局部变量,因为标准中提到了:

6.7.8 Initialization
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

这意味着所有具有静态存储的初始化表达式都必须使用常量表达式进行初始化。 本题中,数组a初始化为a[2]=1,所以a一定没有静态存储空间,即只能是局部变量。

国外某嵌入式公司的面试题题外话,真的没有意义吗? 数组 面试 初始 表达式 求职 第1张

a 必须没有静态存储空间

局部变量a的作用域还包括其自身的初始化,因此int a[5]={a[2]=1};的写法用C语言应该是合法的。 这一点可以参考标准:

6.2.4 Storage durations of objects
For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends

然而,虽然这种写法是合法的,但是上面的C语言代码仍然无法确定数组a的结果。 标准中也对此进行了描述。 请参见:

6.7.9 Initialization
The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.

总体思路是初始化列表表达式的求值顺序是不确定的,因此其期间发生的“副作用”也是不确定的。

为什么这段C语言代码会产生两个结果?

经过简单的总结,你应该能够理解为什么这段C语言代码会产生两个结果。 其实C语言的表达方式:

int a[5] = {a[2]=1};

相当于两个表达式的组合 int a[5]={1}; 且a[2]=1;。 表达式 int a[5] = {1} 将导致数组 a 中的元素初始化为

1, 0, 0, 0, 0

而a[2] =1会将数组a的元素2设置为1,最终得到结果

1, 0, 1, 0, 0

但最终的结果会怎样呢? 不幸的是,根据上面的讨论,两个表达式的副作用的顺序 int a[5]={1}; a[2]=1; 不确定,即无法确定a[2]=1; 是否在int a[5]={1}之前执行; 或者之后,这可能会导致两种结果,这两种结果都不能被认为是错误的。

概括

正如前面提到的,“奇怪”的面试问题也可以帮助我们发现并填补空白。 为了解决这个面试题,我们甚至还阅读了一些C标准。 在这段时间里,我相信我们的技术在不知不觉中得到了提高。

竖起大拇指然后走开

欢迎在评论区一起讨论、提问。 文章均为手写、原创。 他们每天深入浅出地介绍C语言、Linux等嵌入式开发。 如果你喜欢我的文章,就关注吧,你可以看到最新的更新和以前的文章。

标签: 数组 面试 初始 表达式 求职

发表评论 (已有1条评论)

评论列表