2011-08-27 92 views
11

我在C書中讀到,對於數組num[7],術語num等於&num[0]。這個概念對我來說工作得很好,但是當我寫下如下所示的程序時,我再次感到困惑。給定`int num [7]`,`num`,`num#[0]`,`##'如何不同?

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int num[]={21,22,23,24,25,26,27}; 
    int *x,*y,*z; 
    x=&num; 
    y=num; 
    z=&num[0]; 
    printf("%d %d %d\n",sizeof(x),sizeof(y),sizeof(z)); 
    printf("%d %d %d\n",sizeof(&num),sizeof(num),sizeof(&num[0])); 
    printf("%d %d %d",*(&num),*(num),*(&num[0])); 
    getch(); 
    return 0; 
} 

輸出爲:

 4 4 4 
     4 28 4 
     2293536 21 21 

如果num是相同的&num[0]那麼爲什麼會出現在它們的大小有區別嗎?這是什麼第三種術語&num?我知道它顯示了垃圾值,但這種類型的術語有什麼意義? z=&num[0]我已經明白了。編譯器顯示對作業x=&num的警告,但對於y=num;,編譯器沒有任何問題。如果num的大小爲28那麼爲什麼它會被分配到一個沒有類型轉換的整數指針y

然後我試圖2-d陣列是這樣的:

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}}; 
    int i 
    printf ("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s), 
     sizeof(s[0][0]),sizeof(&s)); 
    getch(); 
    return 0; 
} 

現在的輸出是

8 4 32 4 4 

這裏sizeof(s[i])8。因爲s[i]是一維數組,它有兩個元素,所以很好。但我沒有任何線索&s[i]&s的含義。而且我再次能夠看到ss[0][0]不相同。我用Dev C++ 4.9.9.2版本來運行所有的程序。我想在這三類術語中清楚。

+2

閱讀有一個專門對這個問題一整節的C FAQ:http://c-faq.com/aryptr/index.html – AnT

+0

@good問題爲初學者!好友 – niko

回答

2

哇,這是一個很大的一氣呵成的問題:P

首先,我會嘗試這個輸出解釋給你聽:

4 4 4 
    4 28 4 
    2293536 21 21 

sizeof()是在C一元運算符。代碼編譯時將其替換爲整數,而不是在運行時。因此,編譯器會將您的printf文字性地更改爲:

printf("%d %d %d\n", 4, 4, 4); 
printf("%d %d %d\n", 4, 28, 4); 
printf("%d %d %d",*(&num),*(num),*(&num[0])); 

在編譯的很早階段。

編譯器是一種足以讓你整個數組的大小,當你寫sizeof(num)。這就是sizeof被定義用於數組的原因。所有其他元素給你一個爲(int *)除外的sizeof(& NUM),讓你的大小(INT **)(一個int **是相同的大小爲int *反正)的大小。

  • & num是指針的存儲器位置到您的陣列
  • NUM,和& NUM [0],是int的存儲器位置的陣列

在關於第二個題;

printf("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),sizeof(s[0][0]),sizeof(&s)); 

 

sizeof(s[i]) - size of an array (int[2]) == 8 
sizeof(&s[i]) - size of a pointer to an int array sizeof(int **) == 4 
sizeof(s) - size of a 2D array containing 8 ints == sizeof(int[8]) == 32 
sizeof(s[0][0]) - size of an int === 4 
sizeof(&s) - size of a pointer to an array == 4 
3

你的矛盾是有效的。是不是num相當於&num[0]的情況。那簡直是錯誤的。數組與指針是不同的類型,而num指的是類型爲int[7]的對象,而不是int*。這就是爲什麼尺寸不同,例如,因爲一個是七個整數的連續集合。

請注意,如果需要,可將num轉換爲int*,值爲&num[0]。當然,轉換與等同不一樣。你會發現數組和指針之間的混淆很奇怪,因爲人們不斷重複數組是指針的錯誤。他們不是。

3

現在我的問題是,如果num是相同的& num [0]那麼爲什麼有一個 差異在那裏大小?

num是一個數組。 sizeof對於數組有一個有時令人驚訝的行爲,那就是它告訴你整個數組的存儲大小,如果你將它傳遞給一個實際的數組,它只會告訴你指向數組中一個元素的指針的大小,這種元素的地址。這可能會導致混淆,因爲數組名稱降級爲函數調用中的指針。

因此,答案是num&num[0]不相同 - 後者是num的第一個元素的地址,其中包含有關刪除數組總大小的任何信息。這兩件事在許多情況下是可以互換的,例如調用實際函數,但在調用sizeof(這不是函數,而是由編譯器處理的特殊關鍵字)時不可以。

6

好問題在這裏。希望我們都能爲你解釋這些問題。

鑑於

int num[]={21,22,23,24,25,26,27}; 

然後

  • num已鍵入int[]因爲其內存在的地方被分配整數聲明數組。請注意,它確實有而不是的類型爲int*,如果您使用它,則會發生這種情況。
  • sizeof(num)是28,因爲num是7個整數的數組,它們在您的機器上的大小爲4個字節。如果整數是8個字節,則值爲56;如果它們具有2個字節,則值爲14,但每個整數最常見的是4個字節。
  • &num[0]是一個指針,類型爲int*,其num的第一個元素的地址。
  • x和朋友的大小是4,因爲它們被聲明爲指針,在您的機器上,在您的C編譯器中,指針分配爲4個字節。

需要記住的是,當某個數組在某些上下文中使用時,例如被作爲參數傳遞時,它將轉換爲int*。這就是爲什麼你可以說*num並得到21.棘手,但事情就是這樣。這就是爲什麼人們通常可以互換num&num[0],但是您應該牢記這一區別,因爲正如您注意到的那樣,sizeof值有所不同。

轉換是爲什麼y = num有意義。 y的類型爲int*,在C中,您將自動從int[]轉換爲int*。您不能執行x = &num,因爲&num的類型是「指向int數組的指針」。您不能將其分配給int*(指向int的指針)。

在的情況下

的int [4] [2] = {{1234,56},{1235,57},{1236,58},{1237,59}};

我們有作爲int[][]s的類型,如pointer to int[][]&s的類型和&s[i]作爲指針int[]類型(因爲s[i]是int數組)。由於C允許您將數組分配/傳遞給指針,因此您可以使用與第一個示例中相同的遊戲類型。

你會發現,s&s[0]&s[0][0]都指向相同的內存位置,但是,你注意到了,sizeof值會有所不同。

+0

@pst,對,我做了太多的假設。它包含7個四字節整數。是的,OP可能位於具有不同大小整數的機器上。 –

+0

更好,還有+1:p – 2011-08-27 21:02:52