指標進階(一)(跑路人筆記)

2022-01-04 10:00:06

前言

請新增圖片描述

大家好!!!期末考試搞完了重操舊業來搞一下最重要的指標進階。這個作為最重要的知識我準備多搞幾期,這一期將指標進階的基礎知識如❀❀指標型別和指標的建立和有關指標的知識❀❀,❀❀後面講題目和使用方法❀❀。
那我們就開始吧!!
(PS:本章知識有些雜且難理解博主看視訊時也是經過了反覆的思考才終於有些理解所以沒看懂的同學不要因此氣餒)

字元指標

字元指標的建立

int main(void)
{
	char a = 'w';
	char *pa = &a;
	return 0;
}

pa就是我們的字元指標了他的型別是char*(無關話題的討論點)然後pa為他的指標名在後續操作中使用pa就是直接對a記憶體的使用。

一些無關話題

雖然是char型別的指標但是型別中的一般和變數名相結合後續我們將函數指標和陣列指標(本文就有)是會再次強調。

字元指標的知識以及與字元陣列的比較

字元指標記憶體放的是記憶體所以我們可以將字串賦值給我們的字元指標它就會存放字串首元素的地址如下:

int main()
{
	char *pa = "abcdefg";
	return 0;
}

pa中存的就是a的地址,當然pa本身也是變數也有屬於他的地址所以pa != &pa 兩者是屬於兩碼事
在這裡插入圖片描述
可以看到&pa 和pa 的不同 而且pa+1和&pa+1的跳躍跨度也不同所以千萬不要把這倆搞混。可以將pa類比為存放字串陣列的變數但又不完全相同
下面是不同點的講解(可能沒有完全覆蓋遺漏的點希望可以得到補充)

不同點一

(初始化賦值的不同)
如:

int main()
{
	char *pa = "abcdef";
	char arr[] = "abcdef";
	return 0;
}

雖然pa 和arr都是儲存的首元素地址但如果在初始化時對pa進行賦值pa的內容將不能被更改arr則可以如下圖:
在這裡插入圖片描述
這是因為我們在初始化字元指標賦值時對其賦值的是常數字串常數不可再次被改變。而對字元陣列內依舊是變數可以改變。
而對另一個字元指標再次賦值字串他們這兩個字串相同這兩個字元指標也相同
如下圖:
在這裡插入圖片描述
兩者完全相同。自然兩者均無法改變。

不同點二

(對變數名取地址的不同)
如&pa 和&arr
詳解:

int main()
{
	char arr[20] = "abcdefg";
	char* pa = arr;
	return 0;
}

在這裡插入圖片描述
可以看到pa 和 arr 同作為陣列名指向的內容相同且*(pa+1) *(arr+1)內容依舊相同但是&pa 和&arr是兩回事
看圖
在這裡插入圖片描述

他們所指記憶體不同其實連型別都不再相同
&pa的型別為char * 為二級陣列——指向一級指標的地址。(可以理解為套娃)
&arr的型別為char(
)[20]是陣列指標
請新增圖片描述
陣列指標沒看懂的同學下面會有講解,我們現在可以將它理解成指向整個陣列的指標。

陣列指標

陣列指標我們將它理解為指向陣列的指標在此之前我們不妨理解一下
&arr 和 arr之間的區別
其實區別很明顯:跳躍跨度不同
看圖:在這裡插入圖片描述
我們的arr+1操作後就只跳躍了一個位元組長度(因為是char型別)而我們的&arr+1則跳躍了一個陣列的大小。
我們的陣列指標就是指向&arr的指標
他繼承了&arr相同的跳躍能力
建立方法:
在這裡插入圖片描述

指標陣列

顧名思義這是一個陣列
不過這個陣列的元素是指標

指標陣列的建立

int main()
{
	char* arr[20] = { 0 };
	return 0;
}

要注意的點是他的型別和陣列指標型別很像
不過要區分也很簡單我們只要記住:
變數名和 * 結合的是指標如陣列指標就是將 *和變數名結合如char(*pa)[10],這就創造了一個指向10空間陣列的指標。
而指標陣列
的建立是char *pa[10]這就是建立了一個10個大小的指標陣列。
(指標陣列可以將相同型別的指標進行打包在傳參時又可以節省很多空間)

函數指標

函數也有他的儲存地址
在這裡插入圖片描述
Add和&Add兩者除型別不同之外,在使用中幾乎沒有不同。

函數指標的建立

在這裡插入圖片描述

函數指標陣列

陣列是一個存放相同型別資料的儲存空間。
我們已經學習了指標陣列,我們類比一下指標陣列就可以理解函數指標陣列了

函數指標的建立

在這裡插入圖片描述
與函數指標類似在陣列名後加上陣列大小即可。

指向函數指標陣列的指標

我們把函數都打包到函數指標陣列我們傳遞給其他函數時我們依舊需要函數指標陣列的指標。
(其實無論是函數指標陣列還是指向函數指標陣列的指標都是函數陣列和函數陣列指標的特殊形式而已。)

指向函數指標陣列的指標的建立

void test(const char* str)
{
	printf("%s\n", str);
}
int main()
{
	//函數指標pfun
	void (*pfun)(const char*) = test;
	//函數指標的陣列pfunArr
	void (*pfunArr[5])(const char* str);
	pfunArr[0] = test;
	//指向函數指標陣列pfunArr的指標ppfunArr
	void (*(*ppfunArr)[5])(const char*) = &pfunArr;
	return 0;
}

與變數名結合那麼這個變數就是指標
當變數名旁有**[ ]時我們的變數名會優先與[ ]結合所以我們要建立指向函數指標陣列的指標**時我們需要將變數名和
括在一起。

總結

指標進階遠遠不止這些博主也不知道會出多少期關於指標進階。
但作為C語言最重要也最難的內容博主認為出他個7 8 期都是合理的。
OK結束
下一期我會在此理解指標並講解一下指標的題目。