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

时间:2011-07-13 12:54:35

标签: c

我在接受采访时被问到这个问题。这个计划的结果是什么?我自信地说,这不会编译。我说a是一个数组名称,并没有占用任何空间,所以& a应该没有任何意义,因此这将无法编译。但实际上,事实证明,编译和运行成功。有人可以解释,这是如何工作的。

main()    
{
    int a[50];
    &a; // or perhaps the interviewer wanted to know the output of this line..
}

5 个答案:

答案 0 :(得分:4)

&a;行只计算数组a的地址,并以静默方式丢弃它。

答案 1 :(得分:3)

该程序没有可观察到的结果。它已成功编译,但没有任何可观察的行为。

&a是一个表达式。由于a是数组类型的对象,&a是数组的地址(其值可能与&a[0]重合,但其类型不是 - int* vs { {1}})。任何以分号后跟的表达式都是表达式语句。函数体是int(*)[50]中包含的零个或多个语句的序列。因此,这是一个合法的{}函数。 (当你写main()时,这也是一个表达式声明。)

根据C ++标准的as-if规则,实现甚至可能决定不为您的阵列分配任何内存,并且根本不做任何事情,因为即使它确实如此,您也无法检查它(至少从C ++的角度来看)。

以下也是一个有效的C ++程序

a[0] = 10;

答案 2 :(得分:3)

面试官显然应该得到新的测试材料:)这......

main()    
{
    int a[50];
    &a;
}

...是旧的K& R C.如果没有声明,则函数返回int并且隐式返回函数的最后一个语句。您可以将以下内容重写为ANSI C:

int main()    
{
    int a[50];
    return &a;
}

所以我们要解析这个程序:


int main()    

定义一个函数main,返回int,取任意参数。


{
    int a[50];

在自动存储中定义一个50 int的数组,并将 int指针(int*)分配给这个数组的第一个元素到变量文字a


    return (intptr_t)&a;
}

现在这有点棘手。只需将a写入数组的第一个元素的地址即可。 &运算符获取存储此特定指针的变量的地址。在某处分配了50 int并且此变量当前指向此处并不重要。我们采用的是指向指针的指针,即int指针指针(int**)。数组,也是它的第一个元素。

然而,K& R C定义了指针类型到整数的隐式转换。该指针的值唯一地标识原始指针,并且必须适合于指针算术。大多数编译器通过简单地将指针的逐字地址存储在整数中来实现这一点。重要的例外:任何特殊的机器相关的nil-pointer值必须映射到C侧的0,并且intintptr_t 0投射到指针必须映射到架构nil值(在大多数架构上机器零值也是0。

main返回指针的整数表示,在大多数系统上返回其内存地址,根据C标准的定义,它指定退出代码。


编译此程序

cc -o interview_question interview_question.c

您可以使用

执行并显示其退出代码
./interview_question ; echo $?

哪些是随意的,但不是随机数。

由@John提交的编辑对评论和更正进行了修改。

答案 3 :(得分:2)

你可以使用表达式作为语句,它完全有效。它什么都不做。

答案 4 :(得分:1)

这段代码应该按照我的意愿编译并成功运行。 a是一个数组, & a只是第一个索引的地址(与a相同)。所以& a是一个不做任何事情的表达...... 同样如下:

int x; &安培; X;

由于表达式2无效,因此不会有任何输出。