2011-07-13 55 views
3

我在接受採訪時被問到了這個問題。這個計劃的結果是什麼?我自信地說,這不會編譯。我說a是一個數組名稱,不佔用任何空間,因此& a應該沒有任何意義,因此這不會被編譯。但實際上,事實證明,編譯以及成功運行。有人可以解釋,這是如何工作的。這個C程序如何編譯並運行成功?

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

「a」是指向數組的指針。 – Microfed

+0

一個數組佔用內存中的空間(你會在哪裏存儲它的內容),因此檢索數組的地址是完全合理的。 –

+0

請參閱[我的舊(ish)答案](http://stackoverflow.com/questions/5181237/confusion-in-data-types-in-a-2d-array/5181495#5181495)的相關信息。 – pmg

回答

4

&a;行只是計算數組a的地址,並默默丟棄它。

+0

那麼a和&a有什麼區別。我以爲a是數組的起始地址。但看起來像&a也有同樣的事情?或者也許a和a具有相同的值,但+ 1和&a + 1將具有差異值。 – xyz

+0

a相當於&a其中a是一個數組。看到這個解釋:http://www.fredosaurus.com/notes-cpp/arrayptr/arraysaspointers2.html –

+0

好吧,有基本的想法。 https://ideone.com/0f7Tk上的程序展示了差異a + 1和&a + 1。 – xyz

3

該程序沒有可觀察到的結果。它已成功編譯,但沒有任何可觀察到的行爲。

&a是一個表達式。由於a是陣列類型的對象,因此&a是陣列的地址(其值可能與&a[0]一致,但其類型不是 - int* vs int(*)[50])。任何後跟分號的表達式都是一個表達式語句。函數體是由{}包含的零個或多個語句的序列,因此這是一個合法的main()函數。 (當你寫a[0] = 10;這也是一個表達語句。)

在C++標準的as-if規則下,實現甚至可能決定不爲數組分配任何內存,並且什麼都不做,因爲即使如果是這樣,你就沒有辦法檢查它了(至少從C++的角度來看)。

下面也是一個有效的C++程序

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

您可以使用表達式作爲一個聲明,這是完全有效的。它不會做任何事情。

1

這段代碼應該按照我的感覺成功編譯和運行。 a是一個數組, & a不過是第一個索引的地址(與a相同)。所以& a是一個表達式,它不會做任何事情... 它與之相同:

int x; &x;

由於表達式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定義了指針類型到整數的隱式轉換。該指針的值唯一標識了原始指針,並且必須適合指針算術。大多數編譯器通過簡單地將指針的逐字地址存儲在整數中來實現這一點。重要的例外:任何特定的與機器有關的零指針值必須映射到C端的0,並且轉換爲指針的指針必須映射到架構的nil值(在大多數架構上,機器零值也爲0) 。

main返回指針的整數表示形式,在大多數系統上它的內存地址,根據C標準的定義,它指定它的退出代碼。


編譯這個程序

cc -o interview_question interview_question.c 

可以執行和使用顯示其退出代碼

./interview_question ; echo $? 

這將是一些任意的,但不是一個隨機數。

編輯歸因於@John Bodes的評論和更正。

+0

Quibbles:'a'是一個數組,不是指針;它會在大多數情況下將其類型隱式轉換爲指針。其次,'&a'的類型是'int(*)[50]',而不是'int **'。 –

+0

@John Bode:感謝您的更正。欣賞它。 – datenwolf

+1

這不一定是K&R C.如果我用gcc編譯(作爲一個.c文件)並運行,我得到一個垃圾返回碼。 (編譯器將它視爲舊的K&R。)但是,如果我使用g ++編譯(作爲.cpp文件)並運行,我會得到一個零返回碼。最後的&a被放棄,程序返回0(參見ISO/IEC 14882:2003 3.6.1¶5)。 –

相關問題