普通陣列宣告
//宣告陣列
int arr[3];
int arr[3] = ;
//由編譯器自動指定陣列大小
int arr =
//多維陣列
int arr[2][2] = , }
陣列變數名本身就是陣列的位址,陣列跟指標的關係很密切
int arr =
//陣列的位址等於陣列第乙個元素的位址
//這兩者都是常量,不能改變,如果想改變可以賦值給乙個指標,然後改變該指標的值
arr == &arr[0]
//陣列名可以表示指標名,反之亦然
int *ptr = arr
ptr[0] == arr[0]
//當作為函式形參時,int , int *是一樣的
//相同的位址
arr + 2 == &arr[2]
//相同的值
*(arr + 2) == arr[2]
//第1個元素值加2,因為*的優先順序高於+
*arr + 2
指標的加減會根據指標型別的儲存單元倍數移動
下面的例子中:
int型指標+1實際上指標位置移動了4(我的centos7 64位int佔4個位元組)
long型指標+1實際上指標位置移動了8(我的centos7 64位long佔8個位元組)
#include int main();
long arr_l[3] = ;
int *ptr = arr;
long *ptr_l = arr_l;
//0x7ffd89358850 0x7ffd89358854
printf("%p %p\n", ptr, ptr+1);
//0x7ffea17892d0 0x7ffea17892d8
printf("%p %p\n", ptr_l, ptr_l+1);
}
指標求差,比較:
2個指標必須在同乙個陣列裡,差值就是他們之間相差幾個儲存單元
#include int main();
int *ptr_1 = &arr[2];
int *ptr_2 = &arr[4];
//2 -2
printf("%d %d\n", ptr_2 - ptr_1, ptr_1 - ptr_2);
//1 0
printf("%d %d\n", ptr_2 > ptr_1, ptr_2 < ptr_1);
//相加直接報錯
//printf("%d %d\n", ptr_2 + ptr_1, ptr_1 + ptr_2);
}
解引用未初始化的指標
int *pt;
*pt = 5; //嚴重錯誤
因為建立乙個指標時系統只分配了儲存指標本身的記憶體,並未分配儲存資料的記憶體。
高階例子
#include int main();
int *ptr = arr;
int total = 0;
//結合律優先順序相同的從右往左
//所以右邊的ptr指標先++再求值,所以ptr已經指向陣列第二個值
//而total是先加上ptr指向的值,然後ptr++
total += *ptr++;
/*等同於
total = total + *ptr
ptr++;
*/printf("%d %d", total, *ptr); //1 2
total += *++ptr;
/*等同於
total = total + *(ptr+1)
ptr++;
*/printf("%d %d", total, *ptr); //4 3
}
指標和陣列
int arr[2][2] = , };
1.arr是陣列首元素的位址,二維陣列的首元素是arr[0](是arr[0][0]的位址),所以*(arr[0])就是arr[0][0]。
2.*arr代表陣列首元素(arr[0])的值,而arr[0]是乙個陣列,陣列本身是位址,所以*arr == &arr[0][0]。
3.**arr與*&arr[0][0]等價
簡而言之,arr是位址的位址,要解引用2次才能得到原始值,位址的位址就是指標的指標,陣列維度越大,就越複雜,這就是為啥指標那麼難理解的原因。
#include int main(), };
//0x7ffd6688d660 0x7ffd6688d660 0x7ffd6688d660 0x7ffd6688d660
printf("%p %p %p %p\n", arr, arr[0], &arr[0], &arr[0][0]);
//0x7ffd6688d668 0x7ffd6688d664 0x7ffd6688d668 0x7ffd6688d664
printf("%p %p %p %p\n", arr+1, arr[0]+1, &arr[0]+1, &arr[0][0]+1);
}
arr 乙個指向第乙個陣列的指標(陣列指標,也就是指標的指標)
arr+1 由於arr是陣列指標儲存單元為陣列大小,所以會往後移動乙個陣列,即&arr[1]
*(arr+1) 第二個陣列的值即&arr[1][0]
*(arr+1)+1 即&arr[1][1]
*(*(arr+1) + 1) 即arr[1][1]
#include int main(), };
//0x7ffe4c7472b0 0x7ffe4c7472bc 0x7ffe4c7472bc 0x7ffe4c7472c0 4
printf("%p %p %p %p %d\n", arr, arr+1, *(arr+1), *(arr+1) + 1, *(*(arr+1) +1 ) );
//0x7ffe4c7472b0 0x7ffe4c7472bc 0x7ffe4c7472bc 0x7ffe4c7472c0 4
printf("%p %p %p %p %d\n", arr, &arr[1], &arr[1][0], &arr[1][1], arr[1][1] );
}
再來看下面2個宣告的區別,它們都是指標的指標
乙個是指標(可以改變自己,比如說自增)
乙個是指標陣列(不能改變自己)
int (* ptr)[2];
宣告了1個指標ptr,它指向了乙個陣列,該陣列包含2個int值。
int * pax[2];
宣告了乙個指標陣列pax,它裡面包含2個int型指標。
例子
#include int main(), };
ptr = &arr[0];
//1 2
printf("%d %d\n", ptr[0][0], ptr[0][1]);
printf("%d\n", **(++ptr)); //3
int * pax[2];
pax[0] = arr[0];
pax[1] = arr[1];
//1 2
printf("%d %d\n", pax[0][0], pax[0][1]);
//報錯因為pax為陣列變數,不能改變自己
printf("%d %d\n", **(++pax));
}
Linux C 陣列和指標
陣列的基本概念 定義及使用方法 字串的深入理解及相關字串操作庫函式 指標的基本概念 定義與使用方法 指標型別的引數和返回值 指標與陣列的關係 指向指標的指標和指標陣列 陣列的基本概念 簡單來說就是具有相同資料型別的若干變數的有序集合,是一種復合型別。陣列count的元素的儲存空間是相鄰的,陣列成員可...
Linux C語言指標,陣列和函式
函式 1.char a 10 char p p a p a 5 2.關係 3.注意指標的當前位置 通過自增 自減 賦值可以改變指標的當前位置 二維陣列由多個一維陣列組成二維陣列名加一,跳一行資料,所以二維陣列又交行位址 一般形式 儲存型別 資料型別 行指標名 列數 int p 3 表明這個指標變數 ...
Linux C 指標和陣列
目錄 1.為什麼需要陣列?2.深刻理解陣列 3.一維陣列中幾個關鍵符號的理解 4.陣列的訪問方式 5.指標變數資料型別的強制轉換 6.指標,陣列和sizeof 7.陣列的傳參 8.指標陣列和陣列指標 9.二維陣列 原因顯而易見,比如要錄入100個學生的成績,如果沒有陣列就必須定義100個變數,就很麻...