【C语言】全面解析指针,指针知识点整理
目錄
前言:
1.指針的概念
2.指針的類(lèi)型
3.野指針
3.1野指針的成因:
?3.2如何避免野指針?
4.指針的運(yùn)算
5.指針和數(shù)組
6.二級(jí)指針
7.指針數(shù)組
總結(jié):?
?
前言:
對(duì)C語(yǔ)言來(lái)說(shuō),指針是一個(gè)難點(diǎn),如果用C語(yǔ)言來(lái)寫(xiě)數(shù)據(jù)結(jié)構(gòu)的話(huà),掌握指針的用法是必須的,如果指針沒(méi)學(xué)好,學(xué)數(shù)據(jù)結(jié)構(gòu)很吃力。所以希望大家一定要掌握指針啊!!!
1.指針的概念
1.指針就是個(gè)變量,用來(lái)存放地址,地址唯一表示一塊內(nèi)存空間。
ps:(內(nèi)存編號(hào) = 地址 = 指針)
2.指針的大小是固定的4/8個(gè)字節(jié)(32位平臺(tái)/64位平臺(tái))
2.指針的類(lèi)型
指針是有類(lèi)型的,指針的類(lèi)型決定了指針+-整數(shù)的步長(zhǎng),指針解引用時(shí)候的權(quán)限。
下面我來(lái)解釋一下上面的紅色部分的意思,舉個(gè)例子,看一下下面的代碼及運(yùn)行結(jié)果:
#include<stdio.h> int main() {int a = 4;int* p1 = &a;char* p2 = &a;printf("%p\n", p1);printf("%p\n", p2);printf("%p\n", p1+1);printf("%p\n", p2+1);return 0; }?剛開(kāi)始p1和p2地址是一樣的,但后面讓p1和p2分別進(jìn)行+1,后面的結(jié)果就不同了,p1加的1是int類(lèi)型的1,而p2+1加的是char類(lèi)型的1。
上面我們說(shuō)到指針的大小是固定的4/8個(gè)字節(jié),假設(shè)是32位平臺(tái),那么一個(gè)指針就占4個(gè)字節(jié)。如果這時(shí)我定義一個(gè)整型指針和字符指針,那么這個(gè)整型指針在解引用時(shí)就可以訪(fǎng)問(wèn)4個(gè)字節(jié),而字符指針就只能訪(fǎng)問(wèn)1個(gè)字節(jié)。
3.野指針
野指針的概念就是:指針的位置是不可知的
3.1野指針的成因:
野指針的成因有兩個(gè):1.指針未被初始化? ?2.指針的越界訪(fǎng)問(wèn)
給大家解釋一下:
指針未被初始化
這個(gè)應(yīng)該很好理解,就是我們?cè)趧?chuàng)建指針變量的時(shí)候沒(méi)有讓它指向任何對(duì)象
例如: int* p;? ?這樣p就是一個(gè)局部變量,p就是一個(gè)隨機(jī)值?
指針的越界訪(fǎng)問(wèn)
看一下下面的代碼:
#include<stdio.h> int main() {int arr[5] = { 1,2,3,4,5 };int* p = arr;int i = 0;for (i = 0; i < 6; i++){printf("%d ", *p);p++;}return 0; }先給大家解釋一下這個(gè)代碼的原理,int* p = arr; 這里arr是數(shù)組名,數(shù)組名是首元素的地址
那么現(xiàn)在p就是首元素的地址? 對(duì)p進(jìn)行解引用就是*p ,*p的值就是 1
p++;? 這行代碼就是讓p的地址++;指針的大小是固定的4/8個(gè)字節(jié), int型數(shù)據(jù)在C語(yǔ)言中也是4/8個(gè)字節(jié),我們拿到的指針都是數(shù)據(jù)第一個(gè)字節(jié)的地址,而數(shù)組在內(nèi)存中又是連續(xù)的,p++就是剛好往后移動(dòng)一個(gè)數(shù)據(jù)。
但是現(xiàn)在arr數(shù)組一共就只有5個(gè)元素,但是循環(huán)6次必然會(huì)導(dǎo)致數(shù)組的越界,那我們來(lái)看一下運(yùn)行結(jié)果
前面5個(gè)數(shù)就是arr數(shù)組里面的數(shù),第6個(gè)值就是一個(gè)隨機(jī)值。因?yàn)楫?dāng)循環(huán)到第6次時(shí),p已經(jīng)沒(méi)有指向的對(duì)象了,此時(shí)p就是一個(gè)野指針了。
?3.2如何避免野指針?
1.善于使用NULL,及時(shí)對(duì)指針進(jìn)行初始化
如果你在定義指針變量的時(shí)候,就已經(jīng)想到指針變量指向的對(duì)象,那就直接進(jìn)行初始化。
如果你在定義的時(shí)候,還不清楚指針指向的對(duì)象,也不清楚后面要不要使用指針,那就對(duì)指針變量賦值為NULL? ?
NULL就是空的意思,如果int *p=NULL; 那么此時(shí)p就是一個(gè)空指針,后面可以重新賦值,并不影響后面的使用。如果一個(gè)指針是空指針,在你還沒(méi)初始化前不要使用它。
2.避免指針的越界
3.避免返回局部變量的地址
4.指針的運(yùn)算
看下面這段代碼:
#include<stdio.h> int main() {//指針地址加減整數(shù)int arr[5] = { 1,2,3,4,5 };int* p1 = arr;int i = 0;for (i = 0; i < 5; i++){printf("%d ", *p1);p1++;}printf("\n");//解引用后的指針加減整數(shù)int b = 10;int* p2 = &b;(*p2)++;printf("%d", *p2);return 0; }p1++是對(duì)地址進(jìn)行加減整數(shù),上面已經(jīng)介紹過(guò)了,現(xiàn)在就不過(guò)多介紹了
而(*p2)++, 我是定義了一個(gè)b變量,然后賦值給了10,然后把b的地址給了p2,*p2通過(guò)解引用得到的就是10,(*p)++? 相當(dāng)于 10++ ,得到的就是11.
看一下運(yùn)行結(jié)果:
?ps:指針可以比較大小
指針還可以減指針
舉個(gè)例子:
#include<stdio.h> int main() {int arr[5] = { 1,2,3,4,5 };printf("%d", &arr[4] - &arr[0]);return 0; }這里沒(méi)用指針變量相減,其實(shí)是一樣的。畢竟指針就是地址。
兩個(gè)指針指向同一塊空間時(shí),指針減指針的絕對(duì)值得到的就是這兩個(gè)指針之間數(shù)據(jù)的個(gè)數(shù)。
注意這個(gè)不是 個(gè)數(shù)*數(shù)據(jù)類(lèi)型的大小?C語(yǔ)言規(guī)定的
5.指針和數(shù)組
1.數(shù)組是可以通過(guò)指針來(lái)訪(fǎng)問(wèn)的,可以參考我上面寫(xiě)的代碼。
2.通常情況下 數(shù)組名是首元素的地址?
但凡事都有例外:
????????1.sizeof(數(shù)組名)? 得到的是整個(gè)數(shù)組的大小?
????????2.&+數(shù)組名 這里取出的是整個(gè)數(shù)組的地址。
3.在進(jìn)行函數(shù)傳參時(shí),如果形參是數(shù)組,可以把形參設(shè)計(jì)成指針,當(dāng)然如果形參是數(shù)組,也可以傳指針作為實(shí)參。
6.二級(jí)指針
二級(jí)指針就是用來(lái)存放一級(jí)指針(指針變量)的地址。
#include<stdio.h> int main() {int a = 5;int* pa = &a;int** ppa = &pa;return 0; }此時(shí)pa是一級(jí)指針,ppa就是二級(jí)指針,ppa是把pa的地址取出來(lái)放在ppa里面
**ppa就是*pa找到pa,在對(duì)pa進(jìn)行解引用找到a
7.指針數(shù)組
指針數(shù)組的定義:int* 數(shù)組名[大小]??
指針數(shù)組的用法:
#include<stdio.h> int main() {int arr1[3] = { 1,2,3 };int arr2[3] = { 4,5,6, };int* arr3[2] = {arr1,arr2};int i = 0;int j = 0;for (i = 0; i < 2; i++){for (j = 0; j < 3; j++){printf("%d ", *(arr3[i] + j));}printf("\n");} }對(duì)指針數(shù)組可以模擬是實(shí)現(xiàn)二維數(shù)組,arr[i]里面存放的是arr1和arr2的地址。+j是獲得每一位數(shù)組元素的地址,在來(lái)*解引用拿到里面的值。輸出那個(gè)地方也可以換成??printf("%d ", arr3[i][j]);效果是一樣的。
總結(jié):?
指針真的很重要!指針真的很重要!指針真的很重要!(重要的事情說(shuō)三遍)一定要掌握
希望這篇文章可以幫到你 (水平有限,如果有問(wèn)題,歡迎大佬指正!感謝!)
?
總結(jié)
以上是生活随笔為你收集整理的【C语言】全面解析指针,指针知识点整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: dropzonejs vue 使用_可能
- 下一篇: luogu1856