您好,登錄后才能下訂單哦!
這篇文章主要介紹“C語言指針和數組應用實例分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“C語言指針和數組應用實例分析”文章能幫助大家解決問題。
數組是一段連續的內存空間
數組的空間大小為 sizeof(array_type) * array_size
數組名可看做指向數組第一個元素的常量指針
下面看一段代碼:
#include <stdio.h> int main() { int a[5] = {0}; int* p = NULL; printf("a = 0x%X\n", (unsigned int)(a)); printf("a + 1 = 0x%X\n", (unsigned int)(a + 1)); printf("p = 0x%X\n", (unsigned int)(p)); printf("p + 1 = 0x%X\n", (unsigned int)(p + 1)); return 0; }
輸出結果如下:
通過這段代碼說明指針運算是合法的。
指針是一種特殊的變量,與整數的運算規則為
p + n; <-->(unsigned int)p + n*sizeof(*p);
結論∶
當指針 p 指向一個同類型的數組的元素時:p+1 將指向當前元素的下一個元素;p-1 將指向當前元素的上一個元素。
指針之間只支持減法運算
參與減法運算的指針類型必須相同
p1- p2; <--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
注意:
只有當兩個指針指向同一個數組中的元素時,指針相減才有意義,其意義為指針所指元素的下標差
當兩個指針指向的元素不在同一個數組中時,結果未定義
下面看一段簡單的指針運算代碼:
#include <stdio.h> int main() { char s1[] = {'H', 'e', 'l', 'l', 'o'}; int i = 0; char s2[] = {'W', 'o', 'r', 'l', 'd'}; char* p0 = s1; char* p1 = &s1[3]; char* p2 = s2; int* p = &i; printf("%d\n", p0 - p1); //printf("%d\n", p0 + p2); //ERROR printf("%d\n", p0 - p2); //printf("%d\n", p0 - p); //ERROR //printf("%d\n", p0 * p2); //ERROR //printf("%d\n", p0 / p2); //ERROR return 0; }
輸出結果如下:
注意兩個指針指向不同的數組,雖然它們兩相減符合語法,但是最后的結果肯定沒有意義。
再來看一段指針運算的應用代碼:
#include <stdio.h> #define DIM(a) (sizeof(a) / sizeof(*a)) int main() { char s[] = {'H', 'e', 'l', 'l', 'o'}; char* pBegin = s; char* pEnd = s + DIM(s); // Key point char* p = NULL; printf("pBegin = %p\n", pBegin); printf("pEnd = %p\n", pEnd); printf("Size: %d\n", pEnd - pBegin); for(p=pBegin; p<pEnd; p++) { printf("%c", *p); } printf("\n"); return 0; }
輸出結果如下:
注意以下幾點:
數組大小的計算方法:#define DIM(a) (sizeof(a) / sizeof(*a))
char* pEnd = s + DIM(s); // Key point ==> pEnd 指向 'o' 后面的地址 ==>
這在 C 語言中是一個擦邊球的邊界位置,也是一個技巧,在這個邊界位置可以認為該指針是合法的,可以和其他指針進行比較運算和減法運算等,在 C++ 標準庫里面也合法
指針也可以進行關系運算 (<,<=,>,>=)
指針關系運算的前提是同時指向同一個數組中的元素
任意兩個指針之間的比較運算(==,!=)無限制
參與比較運算的指針類型必須相同
數組聲明時編譯器自動分配一片連續的內存空間
指針聲明時只分配了用于容納地址值的 4 字節空間
指針和整數可以進行運算,其結果為指針
指針之間只支持減法運算,其結果為數組元素下標差
指針之間支持比較運算,其類型必須相同
以下標的形式訪問數組中的元素
以指針的形式訪問數組中的元素
指針以固定增量在數組中移動時,效率高于下標形式
指針增量為1且硬件具有硬件增量模型時,效率更高
下標形式與指針形式的轉換
a[n] <--> *(a +n) <--> *(n + a) <--> n[a]
注意:現代編譯器的生成代碼優化率已大大提高,在固定增量時,下標形式的效率已經和指針形式相當;但從可讀性和代碼維護的角度來看,下標形式更優。
下面看一個數組的訪問方式代碼:
#include <stdio.h> int main() { int a[5] = {0}; int* p = a; int i = 0; for(i=0; i<5; i++) { p[i] = i + 1; } for(i=0; i<5; i++) { printf("a[%d] = %d\n", i, *(a + i)); } printf("\n"); for(i=0; i<5; i++) { i[a] = i + 10; } for(i=0; i<5; i++) { printf("p[%d] = %d\n", i, p[i]); } return 0; }
輸出結果如下:
注意這個奇怪的寫法:i[a] = i + 10; ==> a[i] = i + 10;
下面通過一個實例,說明數組和指針的不同:
ext.c:
int a[] = {1, 2, 3, 4, 5};
test.c:
#include <stdio.h> int main() { extern int a[]; printf("&a = %p\n", &a); printf("a = %p\n", a); printf("*a = %d\n", *a); return 0; }
輸出結果如下:
下面來驗證一下數組名究竟是不是指針,將 test.c 改成:
#include <stdio.h> int main() { extern int* a; printf("&a = %p\n", &a); printf("a = %p\n", a); printf("*a = %d\n", *a); return 0; }
輸出結果如下:
ext.c 中 a[ ] 的地址為 0x804a014,test.c 中的extern int* a; 只是申明標識符 a,編譯器會認為在這之前就已經給了地址值,就是 0x804a014,所以printf("a = %p\n", a); 就是打印0x804a014 地址中的 4 個字節的數,也就是 a[ ] 數組中的第一個元素 1,所以打印 0x1,*a 就是取 0x1 地址中的數,但是這個地址值是留給操作系統的,不可訪問,訪問就會產生段錯誤。
a 為數組首元素的地址
&a 為整個數組的地址
a 和 &a 的區別在于指針運算
這個就能看出 a + 1 和 &a + 1 的不同,a + 1 增加的步長是一個元素的大小,&a + 1 則是增加的步長是整個數組的大小。
下面看一個指針運算的經典問題:
#include <stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; int* p1 = (int*)(&a + 1); int* p2 = (int*)((int)a + 1); int* p3 = (int*)(a + 1); printf("%d, %d, %d\n", p1[-1], p2[0], p3[1]); return 0; }
輸出結果如下:
p1[-1] 就是 *(p1 - 1),由于 p1 指向的元素是 5 后面的位置,減 1 之后就指向了 5;p2 的地址是 0x804a015(注意 linux 系統為小端系統),*p2 就是 0x02000000,對應十進制的值就是 33554432;p3 的地址為 &a[1],所以 p3[1] 就是 3 了。
數組作為函數參數時,編譯器將其編譯成對應的指針
結論:一般情況下,當定義的函數中有數組參數時,需要定義另一個參數來標示數組的大小。
下面看一段代碼:
#include <stdio.h> void func1(char a[5]) { printf("In func1: sizeof(a) = %d\n", sizeof(a)); *a = 'a'; a = NULL; } void func2(char b[]) { printf("In func2: sizeof(b) = %d\n", sizeof(b)); *b = 'b'; b = NULL; } int main() { char array[10] = {0}; func1(array); printf("array[0] = %c\n", array[0]); func2(array); printf("array[0] = %c\n", array[0]); return 0; }
輸出結果如下:
這段代碼就說明數組參數退化成指針,因為 sizeof(a) 為 4 個字節,而不是 5 個字節。
關于“C語言指針和數組應用實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。