[英]How does this C program compile and run successfully?
我在一次采访中被问到这个问题。 这个程序的结果是什么? 我自信地说这不会编译。 我说 a 是一个数组名,不占用任何空间,所以 &a 应该没有任何意义,因此不会编译。 但在实践中,事实证明编译和运行都成功。 有人可以解释一下,这是如何工作的。
main()
{
int a[50];
&a; // or perhaps the interviewer wanted to know the output of this line..
}
&a;
line 只计算数组a
的地址,然后默默地丢弃它。
该程序没有可观察到的结果。 它已成功编译,但没有任何可观察到的行为。
&a
是一个表达式。 因为a
是一个数组类型的 object , &a
是数组的地址(它的值可能与&a[0]
一致,但它的类型不 - int*
vs int(*)[50]
)。 任何后跟分号的表达式都是表达式语句。 function 主体是包含在{}
中的零个或多个语句的序列,因此这是一个合法的main()
function。 (当你写a[0] = 10;
这也是一个表达式语句。)
在 C++ 标准的 as-if 规则下,实现甚至可能决定不为您的阵列分配任何 memory,并且什么也不做,因为即使有,您也没有任何方法可以检查它(至少从 C++ 的角度来看)。
下面也是一个有效的C++程序
int main()
{
1; 2; 3;
}
面试官显然应该得到新的测试材料:)这……
main() { int a[50]; &a; }
… 是旧的 K&R C。 如果未另行声明,则 function 返回int
并且隐式返回 function 的最后一条语句。 您可以将其重写为 ANSI C 如下:
int main()
{
int a[50];
return &a;
}
所以让我们剖析这个程序:
int main()
定义一个 function main
返回一个int
,采用任意参数。
{
int a[50];
在自动存储中定义一个包含 50 个int
的数组,并将一个到文字int
指针 ( int*
) 分配给该数组的第一个元素a
变量。
return (intptr_t)&a;
}
现在这有点棘手。 只需将a
计算为数组第一个元素的地址。 &
运算符获取存储此特定指针的变量的地址。在某处分配了 50 个 int
并且此变量当前指向那里并不重要。我们取的是指向指针的指针,即一个 数组,也是它的第一个元素。int
指针指针( int**
)。
然而 K&R C 定义了指针类型到整数的隐式转换。 此指针的值唯一标识原始指针,并且必须适合指针运算。 大多数编译器通过简单地将指针的逐字地址存储在 integer 中来实现这一点。 Important exception: Any special machine dependent nil-pointer value must map to 0 on the C side and an int
or intptr_t
of 0 cast to a pointer must map to the architecture nil value (on most architectures the machine nil value is 0, too) .
main
返回指针的 integer 表示,在大多数系统上,它的 memory 地址,根据 C 标准的定义,它指定了它的退出代码。
编译这个程序
cc -o interview_question interview_question.c
您可以使用执行并显示其退出代码
./interview_question ; echo $?
这将是一些任意的,但不是随机数。
由于@John Bodes 的评论和更正而进行的编辑。
您可以将表达式用作语句,它是完全有效的。 它不会做任何事情。
我觉得这段代码应该可以编译并成功运行。 a 是一个数组,&a 只是第一个索引的地址(与 a 相同)。 所以 &a 是一个不做任何事情的表达式......它与:
诠释 x; &X;
不会有任何 output 因为表达式 2 什么都不做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.