C 中 int a[] 和 int*a 有什麼區別?

C 中 int a[] 和 int*a 有什麼區別?

int sum (int a[], int n) {

int i, s = 0;

for (i = 0; i &< n; i++)

s += a[i];

return s;

}

是不是後面是 s += a[i] 前面定義就要用 int a[], 後面是 s += *(a+i) 前面就用 int* a 呢?初學者求教


做參數傳遞時,沒有任何區別

void gao(char a[], char b[65536]) { // 這個65536也是逗你玩的
while (a != b) {
printf("%c %d
", *a, 0[a]); // a[i]可以看做*(a+i)的「語法糖」
++a; // 所以不等於 int * const a
}
}

int main() {
char s[] = "Hello, World!";
gao(s, s + sizeof(s) / sizeof(s[0]));
return 0;
}

至於目前排名最高的回答,真的不是問東答西了么?


引用自:C++數組名可以看成指針么?

指針和數組名的共同特點是都是用來指代一個地址的,在參數里,沒有區別。

不同的是:

1、指針是需要佔用內存空間來存儲地址的;數組名則更像是一個立即數或者常數。你可以修改指針指向的內容,但你絕對無法改變數組名的指向。

2、數組和指針對於sizeof來說是不同的,指針變數佔用的空間通常等於當前CPU的最大位元組數(比如:32位CPU是4位元組),數組名取sizeof的話,得到的則是數組的大小。

3、
如果用extern聲明一個外部變數,指針和數組不能混用。比如在文件1.cpp里聲明了char
ca[]="abcde",在文件2.cpp里如果要引用,那麼必須是extern char ca[]而不是extern char *
ca,因為前者是常數,後者是一個佔用了內存空間的有效的變數,區別還是很大的。

4、對數組名取地址是合法的,但有些編譯器不
推薦這樣做,對數組名取地址的結果與直接使用數組名的結果是一致的,這是C語言的一種特殊規定。有一個類似的效果就是函數名,假如func1是一個函數
名,那麼*func1==func1==func1,這只是特殊用法,不代表函數名/數組名真的可以這麼做。


做形參的時候,int a[]與int *a無任何區別。

眾所周知,數組名本身就是指針 。如果聲明一個int a[5]; 那麼a就是一個指針。既然無區別,為什麼還要設置兩種形參呢?顯然,這是考慮到了程序的可讀性。如果你希望傳遞數組,就用前者;如果只是單純地想傳遞指針,就用後者


int a[] 和 int *a :

在做函數形參時,無區別,並且 int a[] 為「活化石」寫法(即不推薦寫法,因為 int a[]不能顯式的表示出我們要傳遞的是一個指針),但是有些程序員認為 int a[] 更好,因為 *a 不能表示出函數所需要的對象是數組還是一個單對象的指針。所以,仁者見仁,我個人更推崇int *a。

總結:

這兩種寫法都表示我們要傳遞一個指針,在函數內部可以對a賦其他值。(在用作數組變數時,數組名只能做「指針常量」,但做數組型形式參數時,兩者相同)


其實使用數組名int a[]定義也相當於指針int *a.比如,要訪問int a[5]實際上是先獲得這個數組的頭指針int *a,然後在內存中偏移5個int的數據長度int *(a+5),也就是從代碼的理解上,可以認為
int a[5]與
int *(a+5)等價,所以編程時看到數組
int a[]要很自然地想到
int *a.

看這個例子:

int a[] = new int[5];
int *a = new int[5];

這兩個用new關鍵字來定義數組的方式是等價的,最終你都能用a[5]訪問到數組的最後一個元素。(new是C++裡面的,C裡面用allocate,舉例用new簡便一些,畢竟C++包含了C的特性。)

區別是:定義數組時使用int a[5],系統會分配5個int的內存空間,但是用int *(a+5)就達不到這個效果。


上面的說得很對,但是太長了可能讓你糊塗。我簡要的跟你說明一下主要區別:

int a[]中的a,是一個指針常量,我強調一下,是常量!它不是一個變數。因此你可以對其取值,但是不可以進行a++,a--這樣的運算。這就好比i = 5,5++是不行的,5是常數。而i++是可以的。

而int *a,這個a是一個指針變數,這個是可以進行a++,a--運算的。

兩者作為函數的形參時,是沒有區別的。原因在於,c遵循的是值傳遞。


做參數傳遞時,沒有任何區別


1.在很多情況下a[i]是等同於*(a+I)的,在編譯器編譯的過程中很多時候會將a[i]直接替換為*(a+i)。

http://2.int a[i]申請的是一個靜態數組,而int a*申請的是一個指針變數,比喻:這就好像是申請建築用地,a[i]在建筑前即申請了一片空地,而a*申請的是一個路標,你可以讓這個路標指向任何一個建築。那麼可以發現,題主所說的int a[i]和int *a在這裡是有區別的,前者是申請好了一片空間,而後者則是一個路標,還沒有申請空間。

3.那麼對於int a[]和int *a,當且僅當在函數定義時是相同的,其他情況均不同。

4.而對於a[i]和*(a+i),在大多數情況下可以等效,但是我們可以對*a的a進行自加,即a++,而不可以對a[]的a進行自加。因為a[]的a作為數組首地址,是常量,而*a的a是變數,就像一片空地的地址是不能任意變化的,而路標是可以移動的。

5.由上面的比喻可以看出,int a[i](i為常數)是靜態數組,即在設計時就需要考慮其大小,這樣帶來的缺點是空間大小固定,導致空間不夠用或者浪費。因而通過申請int a*(申請一個路標),然後通過malloc函數申請一片空間(在建設工程中申請一片空地,這樣可以按照需求確定大小,然後讓路標指向這片空地),得到動態數組(即申請的空間可以由變數大小確定)。這種用法只能用int a*而不能用int a[i]。

6.最新的C99標準允許使用變長數組,即a[i]的i可以是變數,這樣使用a[i]也可以按需申請空間了。

以上大部分來自C Primer Plus,如有錯誤請提出。


《c專家編程》,裡面有一章專門講指針跟數組的區別!網上可以下載。書講得很詳細,看完讓人有茅塞頓開的感覺。


做形參的時候,都是一樣的


我也初學,但為啥我覺得雖然實質一樣,但畢竟一個數組一個指針,定義初始化什麼的都不一樣吧


如有一函數sum調用數組時,可以寫三種格式:

1.sum(int *a)

2.sum(a[])

3.sum(a[M])


推薦閱讀:

C語言編譯器是如何實現指針+1這樣的一個機制?
為什麼很多人建議學C語言不用任何IDE,直接用編輯器和編譯器?
C 語言有哪些缺陷?
int i=0,j; for(j=3;i=j=0;i++,j++)循環多少次?
請問培訓,選擇python還是unity3d?

TAG:計算機 | C編程語言 |