繁体   English   中英

这个C程序如何编译运行成功?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM