c語言指標和陣列
c語言中,指標和陣列很相似,但是也有些不一樣。
1. 宣告
int a[10]
:表示宣告一個數組。而int *a
則是宣告一個指向int型別的指標變數a。
2. 字元陣列與字串常量
char *message = "hello world\n"
聲明瞭一個字串常量hello world\n
,並用指標message指向字串的首個字元。
char message[] = "hello world\n"
則聲明瞭一個字元陣列。
其中字元陣列和字串常量之間最明顯的區別便是常量不可更改,而陣列可以更改。
3. 指標和下標
對於陣列,想要訪問其中的元素,有2中方法:下標引用和指標引用。如對於int a[5] = {1, 2, 3, 4, 5};
訪問元素2,a[1]
和*(a + 1)
效果是等價的。但是指標操作有時比下標引用效率更高,因為下標引用編譯器需要做一定的計算。
下標還可以是負值。
int *pi = &a[2];
p[-1]
則代表是a[1]
。但是注意a[-1]
是非法的,訪問陣列頭部元素的前一個位置的值是非法的,哪怕僅僅是指標的運算判斷也是標準未定義的行為。如:
int a[5] = {1, 3, 5, 7, 9}; int *p = &a[4]; /* 當退出迴圈時,p = a - 1, 雖然未對p提領,但這種行為時c標準未定義的行為 * 儘量不要使用 */ while (p >= a){ printf("%d ", *p--); }
NOTE:1[a]
和a[1]
效果也是一樣的,只是很少被使用。
4. 多維陣列
多維陣列即維數大於1的陣列。如int matrix[10][10];
聲明瞭一個10x10的矩陣。
多維陣列在記憶體中的儲存方式和一維陣列沒有區別,都是線性儲存的。且多維陣列儲存是以行主序儲存。以int a[4][3];
為例,它在記憶體中儲存順序是a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]...
所以,可以通過一下方式遍歷二維陣列:
int a[4][3], *pa = *a; for (pa = *a; pa < a + 4 * 3; pa++) ...;
一維陣列的陣列名是一個指標常量,它是指向元素的指標。而二維陣列的陣列名也差不多,但是指向的時一個數組的指標。如:
int vector[10];
int matrix[10][10];
int *vp = vector; // 宣告int *的指標
int (*p)[10] = matrix; // 宣告指向包含10個元素的陣列的指標
/* 非法的。左值p是指向int *的指標,
* 但右值matrix是指向長度為10的陣列的指標
*/
//int **p = matrix;
這種情況在陣列名作為函式引數傳遞時尤其要注意!