linux c陣列和指標 詳解

2021-08-19 22:15:20 字數 3958 閱讀 9503

普通陣列宣告

//宣告陣列

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個變數,就很麻...