C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针
指針的進階(一)目錄:
- 字符指針
- 數組指針和指針數組
- 函數指針
字符指針
在開始講解這一章節之前,我們需要了解指針前面聲明的類型的意義
類型 * 指針名
對于指針來說,我們在給指針進行聲明時,我們聲明的類型并不是指針的類型,而是指針所指向的地址的類型,也就是指針看待這段地址的方式,它該如何讀取數據,它如果加一該移動多少位,只有了解了這個才能方便理解下面的內容
我們首先來說的就是字符指針char*
一般我們是這樣運用字符指針的
char a = 'a';char* p = &a;但是我們還能以這種方式運用
char*str = "hello world";這時候,經常就會有初學者以為我們的指針指向的是hello world這個字符串,但其實這里只是把字符串的首元素的地址保存到了這個指針當中。
同時我們還需要理解這樣的指針與字符串的區別。
例如:
char str1[] = "hello";char *str2 = "world";這里的str1是在棧上開辟一塊內存空間來存放hello這段字符,而這里的str2是用指針指向常量區的‘’world‘’這段字符,所以我們無法給str2進行賦值與修改,因為常量是不可改變的,我們也無法將這str1與str2進行比較,因為他們是本質不同的兩樣東西。
借此,在引申一個小內容
為什么在這里,str1與str2不同呢?
因為我們給字符串賦值時,是在棧上面開辟一個內存空間,來給這個字符串存放一個數值,雖然他們存放的內容是一樣的,但是它們存放在不同的內存塊中,所以進行比較的時候是不同的
那為什么str3和str4是相同的呢?
因為它們是字符指針,它們指向的都是常量區中的hello world這段字符,它們指向的內容一樣,所以它們相同。
這也就是為什么我們在進行字符串的比較的時候運用的都是strcmp這個函數的原因。
數組指針和指針數組
在我剛剛接觸指針的時候,我經常會搞混兩個東西,一個是數組指針,一個是指針數組,因為它們太過相似,但如果你了解了運算符的優先級以及我之前說的指針如何看待類型,你就會很快的區分它們
上圖中的兩個指針是不是特別相似?那我們如何區分呢?
首先,我們先看幾個運算符的優先級對于p1,[] 的優先級是很明顯高于 *的,所以它的本質就應該是一個數組,而剩下的int *就應該是它所存放的數據類型,所以它是一個存放指針元素的數組,即指針數組。
而對于p2,它的()的優先級是很明顯高于 [] 的,所以我們應該先去考慮括號中的內容,括號中是一個指針 *,所以它的本質就應該是一個指針,而剩下的就是它所指向的地址的類型,所以它是一個指向數組的指針,即數組指針。
如果我們要了解一個數組指針是如何作用的,我們首先要了解這樣一個知識點。
對于一個數組,它的數組名和&數組名有什么區別。
我們都知道數組名是這個數組的首元素的地址,但是&數組名卻不是很了解。
我們查看它們的地址,卻完全的一樣,那是不是證明它們相同呢?
其實不是,我們再給它們分別+1
這里區別就顯現出來了,arr+1加的只是一個元素的大小,而&arr+1加了一整個數組的大小。
所以我們就能了解,&arr指向的是這一整個數組的地址。
而我們的數組指針,是一個指向數組地址的指針,所以數組指針應該這樣指向一個數組。
函數指針
在了解函數指針前我們要先了解一個小的誤區
這兩個哪一個才是函數指針呢?
還是之前判斷數組指針的那個方法,我們看優先級,先看括號,它是一個指針,剩下的就是它所指向的類型,一個返回值為void的函數。
而第二個其實就是一個函數的聲明,聲明一個返回值為void*的函數
我們該如何調用這個函數指針呢?
無論是直接調用還是進行解引用后調用,我們都可以直接使用這個函數
在使用函數指針的時候,因為函數的特殊性,在很多情況下代碼的可讀性會十分差,如下面這段代碼。
這是它的參數類型
這是它的函數名
外面剩下的則是它的返回類型。
所以它是一個參數為int 和函數指針的一個函數,返回值為函數指針。
這樣的代碼讓人很難理解。
那該如何簡化呢?我們可以用typedef進行簡化
簡化完后
這樣我們的代碼可讀性就大大的提升了。
第一部分就講到這里吧
總結
以上是生活随笔為你收集整理的C语言程序设计 | 指针的进阶(一):字符指针、数组指针、指针数组、函数指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法 | 斐波那契查找
- 下一篇: C语言程序设计 | 指针(二):常量指针