2014-12-03 79 views
1

我是C編程和學習指針的新手。看看下面的程序。函數中* p和(* p)[3]之間的區別是什麼?

第一程序

#include<stdio.h> 
    int fun(); 
    int main() 
    { 
    int num[3][3]={21,325,524,52,0,6514,61,33,85}; 
    fun(num); 
    printf("%d",*(*(num+1)+1)); 
    *(*(num+1)+1)=0; 
    printf("%d",*(*(num+1)+1)); 
    return 0; 
    } 
    int fun(int **p) 
    { 
    *(*(p+1)+1)=2135; 
    return 0; 
    } 

第二程序

#include<stdio.h> 
    int fun(); 
    int main() 
    { 
    int num[3][3]={21,325,524,52,0,6514,61,33,85}; 
    fun(num); 
    printf("%d",*(*(num+1)+1)); 
    *(*(num+1)+1)=0; 
    printf("%d",*(*(num+1)+1)); 
    return 0; 
    } 
    int fun(int *p) 
    { 
    *((p+1)+1)=2135; 
    return 0; 
    } 

第三程序

 #include<stdio.h> 
    int fun(); 
    int main() 
    { 
    int num[3][3]={21,325,524,52,0,6514,61,33,85}; 
    fun(num); 
    printf("%d",*(*(num+1)+1)); 
    *(*(num+1)+1)=0; 
    printf("%d",*(*(num+1)+1)); 
    return 0; 
    } 
    int fun(int (*p)[3]) 
    { 
    *(*(p+1)+1)=2135; 
    return 0; 
    } 
  1. 在第一個程序中**p用於fun()函數,我認爲它應該是正確的,並且在那個函數中我寫了*(*(p+1)+1)來改變第一個數組的第一個元素。但是在編譯這個程序時它顯示了error: invalid type argument of unary '*' (have 'int')。據我所知,num是一個指向數組的指針,它保存着num[1]的地址,該地址再次持有地址num[1][0]
  2. 在編譯第二個程序編譯器時顯示沒有錯誤。而*((p+1)+1)=0正在改變第一個數組的第二個元素的值。爲什麼它正在改變第二個數組的第二個元素的值而不是第一個數組的第一個元素的值?如何?它應該是*(*(p+1)+1)=0
  3. 在第三個程序中,compler顯示沒有錯誤,並顯示正確的結果。怎麼樣?。 *(p)[3]是什麼意思?

我已經搜索了這個,但沒有找到滿意的結果。

+1

請刪除所有出現的「+0」,然後是所有不必要的大括號。他們沒有用,並導致嚴重的頭痛。 – fjf2002 2014-12-03 21:32:02

+0

數組的名稱是指向數組的第一個元素的指針。也許在內部它不是真的一樣,但你可以用它作爲指針。 – Joachim 2014-12-03 21:40:23

+0

我編輯了這個問題。 :) – 2014-12-03 21:49:15

回答

1

我想你都在問:什麼是

int fun(int *p) 

int fun(int (*p)[3]) 

第一個之差預期的指針int。第二個需要一個指向3個數組的指針。

您可以調用使用num這兩個功能,因爲你如果聲明的功能就像它們被定義,你會得到編譯器錯誤/第一個版本警告聲明的功能

int fun(); 

下面是您的代碼的更新版本和編譯器警告,使用gcc和編譯器標誌-Wall

#include <stdio.h> 

int fun(int *p); 

int main() 
{ 
    int num[3][3]={21,325,524,52,0,6514,61,33,85}; 
    fun(num); 
    return 0; 
} 

int fun(int *p) 
{ 
    *(p+0)=2135; 
    return 0; 
} 
test.c: In function ‘main’: 
test.c:7:4: warning: missing braces around initializer [-Wmissing-braces] 
test.c:7:4: warning: (near initialization for ‘num[0]’) [-Wmissing-braces] 
test.c:8:4: warning: passing argument 1 of ‘fun’ from incompatible pointer type [enabled by default] 
test.c:3:5: note: expected ‘int *’ but argument is of type ‘int (*)[3]’ 
+0

謝謝你的回答。 :)但是如果我在函數中寫入** p怎麼辦? – 2014-12-03 21:51:28

+0

@ user3788135,你可以使用'** p'作爲第二個版本,但不是第一個版本。在第一個版本中,'* p'是'int'類型。 '** p'不是有效的類型。 – 2014-12-03 21:55:38

+0

對不起,先生我沒有得到你想要解釋我什麼。我想說的是,如果num是一個指向數組的指針,我們不能寫** p? – 2014-12-03 22:09:37

1

你的程序的所有生病形成。您的編譯器必須生成警告或錯誤消息,並且生成的任何可執行文件的輸出都是沒有意義的。

它們不合格,因爲int[3][3]int **不兼容,也不與int *int *[3]不兼容。

要將int[3][3]傳遞給函數,該函數必須接受int (*)[3],除此之外沒有別的(除了void *)。

這是因爲數組可以轉換爲指向數組的第一個元素的指針。 (在C語法中,num可以用於表示&num[0])。

在C中,只有真正的一維數組; int[3][3]類型的數組被認爲是3個元素的數組,其中每個元素都是3個整數的數組。

所以指向num第一個元素的指針是一個指向3個整數的數組的指針,寫成int (*p)[3]。你可以寫:

int (*p)[3] = &num[0]; 

或同一事物的簡寫:

int (*p)[3] = num; 

NB。你不斷寫*(*(num+1)+1))這是難以閱讀。相反,num[1][1]似乎更清晰。

在C中,x[y]總是完全等於*(x+y)

+0

我知道我可以做到這一點,但因爲我正在學習指針我想寫所有的代碼在指針 – 2014-12-03 22:06:59

相關問題