简体   繁体   English

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

[英]How does this C program compile and run successfully?

I was asked this in an interview.我在一次采访中被问到这个问题。 What will be the result of this program?这个程序的结果是什么? I confidently said that this will not compile.我自信地说这不会编译。 I said that a is an array name and does not take up any space, so &a should not make any sense, hence this will not compile.我说 a 是一个数组名,不占用任何空间,所以 &a 应该没有任何意义,因此不会编译。 but on hands-on, it turns out that compiles as well as runs successfully.但在实践中,事实证明编译和运行都成功。 Could someone please explain, how this works.有人可以解释一下,这是如何工作的。

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

The &a; &a; line just computes the address of the array a , and silently discards it. line 只计算数组a的地址,然后默默地丢弃它。

This program has no observable result.该程序没有可观察到的结果。 It is compiled successfully but doesn't have any observable behavior.它已成功编译,但没有任何可观察到的行为。

&a is an expression. &a是一个表达式。 Because a is an object of array type, &a is the address of the array(its value may coincide with &a[0] , but its type doesn't - int* vs int(*)[50] ).因为a是一个数组类型的 object , &a是数组的地址(它的值可能与&a[0]一致,但它的类型不 - int* vs int(*)[50] )。 Any expression followed by a semicolon is an expression statement.任何后跟分号的表达式都是表达式语句。 A function body is a sequence of zero or more statements enclosed in {} Therefore this is a legitimate main() function. function 主体是包含在{}中的零个或多个语句的序列,因此这是一个合法的main() function。 (When you write a[0] = 10; this too is an expression statement.) (当你写a[0] = 10;这也是一个表达式语句。)

Under the as-if rule of the C++ standard, the implementation may even decide not to allocate any memory for your array, and do nothing at all, because even if it did, you wouldn't have any way to check it (at least from C++ point of view).在 C++ 标准的 as-if 规则下,实现甚至可能决定不为您的阵列分配任何 memory,并且什么也不做,因为即使有,您也没有任何方法可以检查它(至少从 C++ 的角度来看)。

The following is also a valid C++ program下面也是一个有效的C++程序

int main()
{
   1; 2; 3;
}

The interviewer clearly should got new test material:) This…面试官显然应该得到新的测试材料:)这……

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

… is old K&R C. … 是旧的 K&R C。 If not declared otherwise a function returns int and the last statement of the function is returned implicitly.如果未另行声明,则 function 返回int并且隐式返回 function 的最后一条语句。 You can rewrite this to ANSI C the following:您可以将其重写为 ANSI C 如下:

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

So lets dissect this program:所以让我们剖析这个程序:


int main()    

Define a function main returning an int , taking arbitrary parameters.定义一个 function main返回一个int ,采用任意参数。


{
    int a[50];

Define an array of 50 int in automatic storage and assign an int pointer ( int* ) to the first element of this array to variable of the literal a .在自动存储中定义一个包含 50 个int的数组,并将一个int指针 ( int* ) 分配给该数组的第一个元素到文字a变量。


    return (intptr_t)&a;
}

Now this is a bit tricky.现在这有点棘手。 Just writing a evaluates to the address of the first element of the array.只需将a计算为数组第一个元素的地址。 The & operator takes the address of the variable this particular pointer is stored in. It doesn't matter that there are 50 int allocated somewhere and this variable currently points there. &运算符获取存储此特定指针的变量的地址。在某处分配了 50 个int并且此变量当前指向那里并不重要。 What we take is the pointer to the pointer, ie an int pointer pointer ( int** ).我们取的是指向指针的指针,即一个int指针指针( int** )。 array, again its first element.数组,也是它的第一个元素。

However K&R C defines implicit conversion of pointer types to integers.然而 K&R C 定义了指针类型到整数的隐式转换。 The value of this pointer uniquely identifies the original pointer and must be suited for pointer arithmetic.此指针的值唯一标识原始指针,并且必须适合指针运算。 Most compilers implement this by simply storing the verbatim address of the pointer in the integer.大多数编译器通过简单地将指针的逐字地址存储在 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). 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 returns the integer representation of the pointer, on most system its memory address, which by definition of the C standard designates it's exit code. main返回指针的 integer 表示,在大多数系统上,它的 memory 地址,根据 C 标准的定义,它指定了它的退出代码。


Compiling this program编译这个程序

cc -o interview_question interview_question.c

You can execute and display its exit code using您可以使用执行并显示其退出代码

./interview_question ; echo $?

Which will be some arbitrary, but not a random number.这将是一些任意的,但不是随机数。

EDITs due to @John Bodes comment and corrections.由于@John Bodes 的评论和更正而进行的编辑。

you can use an expression as a statement, it's perfectly valid.您可以将表达式用作语句,它是完全有效的。 It won't do anything.它不会做任何事情。

This code should compile and run successfully as I feel.我觉得这段代码应该可以编译并成功运行。 a is an array, &a is nothing but the address of first index (same as a). a 是一个数组,&a 只是第一个索引的地址(与 a 相同)。 so &a is an expression which doesn't do anything... its same as:所以 &a 是一个不做任何事情的表达式......它与:

int x;诠释 x; &x; &X;

There will not be any output of this as expression 2 is doing nothing.不会有任何 output 因为表达式 2 什么都不做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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