一篇文章帶你了解C語言指針進(jìn)階
1.字符指針
我們已經(jīng)知道了數(shù)組名在大部分時(shí)候表示數(shù)組的地址,指針本質(zhì)上也表示一個(gè)地址,那么我們能否用指針來創(chuàng)建一個(gè)字符串呢?
int main() { char arr1[] = "abcdef"; char arr2[] = "abcdef"; const char* p1 = "abcdef"; const char* p2 = "abcdef";//const可省略,默認(rèn)為常量字符串 printf("%s\n", arr1); printf("%s\n", arr2); printf("%s\n", p1); printf("%s\n", p2); return 0; }
需要注意的是字符指針創(chuàng)建的字符串是常量字符串,普通的字符串只要數(shù)組名不同即使字符串內(nèi)容相同,也是不同的字符串,但是不論用多少個(gè)指針創(chuàng)建字符串,只要字符串內(nèi)容相同,所有指針指向的就是同一個(gè)字符串,因此字符指針指向的字符串不能修改,在沒有const修飾的情況下也是如此。
2.指針數(shù)組
我們知道數(shù)組可以存儲(chǔ)整形,浮點(diǎn)型,或自定義的結(jié)構(gòu)體,那么可不可以存儲(chǔ)指針呢?答案是:可以。元素都為指針的數(shù)組就稱為指針數(shù)組,形式為:數(shù)據(jù)類型* 數(shù)組名[ ],例如:儲(chǔ)存整形指針的指針數(shù)組創(chuàng)建成int*p[10],表示的就是一個(gè)包含十個(gè)指針元素的數(shù)組,利用指針數(shù)組我們可以訪問指針數(shù)組內(nèi)的指針進(jìn)而操作變量或其他數(shù)組。
int main()//利用指針數(shù)組分別遍歷三個(gè)數(shù)組 { int arr1[] = { 1, 2, 3, 4, 5 }; int arr2[] = { 2, 3, 4, 5, 6 }; int arr3[] = { 3, 4, 5, 6, 7 }; int*parr[] = { arr1, arr2, arr3 }; int i, j; int Sz = sizeof(parr) / sizeof(parr[0]); int sz = sizeof(arr1) / sizeof(arr1[0]); for (i = 0; i < Sz; i++) { for (j = 0; j < sz; j++) { printf("%d ",*(parr[i]+j) ); } printf("\n"); } }
3.數(shù)組指針
我們知道指針可以指向整形,浮點(diǎn)型,或自定義的結(jié)構(gòu)體,那么能不能指向數(shù)組呢?答案也是:可以。指向數(shù)組的指針稱為數(shù)組指針,形式為:數(shù)據(jù)類型(*p)[ ] ,例如int(*p)[10],表示的就是一個(gè)指向包含十個(gè)元素?cái)?shù)組的指針,這和指針數(shù)組的區(qū)別在于要將*p用小括號(hào)括起來以確保它是一個(gè)指針而非數(shù)組(無括號(hào)的情況下p先和 [ ]結(jié)合)。
int main()利用數(shù)組指針遍歷數(shù)組 { int arr[6] = { 1, 2, 3, 4, 5, 6 }; int(*p)[6] = &arr; int i; int sz = sizeof(arr) / sizeof(arr[0]); for (i=0;i<sz;i++) printf("%d", (*p)[i]); //int*arr[5]; //int*(*p)[5]=&arr;//int(*p[10])[5]-->p[10]是一個(gè)指針數(shù)組,剩下int(* )[5]的是數(shù)組的類型,類型為數(shù)組指針,p是一個(gè)數(shù)組有十個(gè)元素,每個(gè)元素都是一個(gè)數(shù)組指針,指向的數(shù)組有五個(gè)int類型的元素 return 0; }
有了指針數(shù)組和數(shù)組指針,我們還可以進(jìn)行兩者的嵌套使用,例如:數(shù)組指針數(shù)組(int(*p[ ])[ ]),指針數(shù)組指針(int*(*p)[ ]),前者是一個(gè)數(shù)組里面的元素是指向另外一些數(shù)組的指針,后者是個(gè)指針指向一個(gè)元素全為另外一些指針的數(shù)組。
void print(int(*p)[5],int x,int y)//用數(shù)組指針接收數(shù)組地址 { int i,j; for (i = 0; i < x; i++) { for (j = 0; j < y; j++) { printf("%d ", *(*(p + i) + j));//arr[i]==*(arr+i)==*(p+i)==p[i] } printf("\n"); } } int main()//利用數(shù)組指針遍歷二維數(shù)組 { int arr[3][5] = { { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 3, 4, 5, 6, 7 } }; print(arr, 3, 5);//arr是首元素地址,二維數(shù)組的首元素是個(gè)第一行的一維數(shù)組 return 0; }
4.函數(shù)指針
我們知道指針可以指向整形,浮點(diǎn)型,自定義的結(jié)構(gòu)體和數(shù)組,那么能不能指向一個(gè)函數(shù)呢?答案同樣是:可以。函數(shù)指針的形式為:函數(shù)返回類型(*p)(參數(shù)類型,參數(shù)類型....)例如:int(*p)(int,int)表示的就是一個(gè)指向返回類型為整形,兩個(gè)參數(shù)類型也是整形的函數(shù)的指針。注意:利用函數(shù)指針調(diào)用函數(shù)時(shí)有幾個(gè)解引用操作符都可以沒有也可以,但是括號(hào)不可或缺!
int Mul(int x, int y) { return x*y; } int main() { int a, b; scanf("%d%d", &a, &b); int(*p)(int,int) = &Mul;//函數(shù)指針,有無&都可以 printf("%d", (p)(a, b));//用指針調(diào)用函數(shù)(*(void(*)()0))() printf("%d", (*p)(a, b)); printf("%d", (**p)(a, b)); printf("%d", (***p)(a, b));//任意個(gè)數(shù)的*都可以 return 0; }
5.數(shù)組傳參
我們知道簡(jiǎn)單的一維數(shù)組的傳參方式:數(shù)組名是首元素地址,我們可以直接用指針接收也可以直接用數(shù)組接收,那么指針數(shù)組和二維數(shù)組呢?指針數(shù)組傳參傳的也是其首元素的地址,而它的首元素是一個(gè)指針,指針的地址我們當(dāng)然用二級(jí)指針接收,同樣地我們也可以直接指針數(shù)組接收。二維數(shù)組傳參傳的是其首元素的地址,要注意的是,二維數(shù)組的首元素并不是第一個(gè)元素而是第一行元素所構(gòu)成的一維數(shù)組,一維數(shù)組的地址我們當(dāng)然用數(shù)組指針接收,同樣地,我們也可以直接用二維數(shù)組接收。
void test1(int arr[])//直接數(shù)組接收 { printf("%d\n", arr[]); } void test2(int*arr)//指針接收首元素地址 { printf("%d\n", arr[]); } void test3(int arr[][5])//二位數(shù)組直接接收 { printf("%d\n", arr[][5]); } void test4(int(*arr)[5])//數(shù)組指針接收 { printf("%d\n", arr); } void test5(int*arr[])//直接指針數(shù)組接收 { printf("%d\n", arr); } void test6(int**arr)//二級(jí)指針接收 { printf("%d\n", arr); } int main() { int arr1[5] = {1,2,3,4,5}; int arr2[3][5] = {1,2,3,4,5}; int* arr3[5] = {NULL}; test1(arr1); test2(arr1); test3(arr2); test4(arr2); test5(arr3); test6(arr3); return 0; }
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池的示例代碼
本文主要介紹了C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05C++對(duì)string進(jìn)行大小寫轉(zhuǎn)換操作方法
這篇文章主要介紹了C++對(duì)string進(jìn)行大小寫轉(zhuǎn)換操作方法,本文通過兩種方法結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02深入理解C++中public、protected及private用法
這篇文章主要介紹了C++中public、protected及private用法,對(duì)于C++面向?qū)ο蟪绦蛟O(shè)計(jì)來說是非常重要的概念,需要的朋友可以參考下2014-08-08解析C++的線性表鏈?zhǔn)酱鎯?chǔ)設(shè)計(jì)與相關(guān)的API實(shí)現(xiàn)
這篇文章主要介紹了解析C++中的線性表鏈?zhǔn)酱鎯?chǔ)設(shè)計(jì)與相關(guān)的API實(shí)現(xiàn),文中的實(shí)例很好地體現(xiàn)了如何創(chuàng)建和遍歷鏈表等基本操作,需要的朋友可以參考下2016-03-03visual studio code 編譯運(yùn)行html css js文件的教程
這篇文章主要介紹了visual studio code 如何編譯運(yùn)行html css js文件,本文通過圖文實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03