C語(yǔ)言指針的圖文詳解
指針是什么?
指針(Pointer)是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。
換句話(huà)說(shuō)就是可以通過(guò)指針找到以它為地址的內(nèi)存單元。
理解:內(nèi)存圖解。

指針是個(gè)變量,存放內(nèi)存單元的地址(編號(hào))。
int main(){
int a = 10;//在內(nèi)存中開(kāi)辟空間存儲(chǔ)
int* p = &a;//先對(duì)變量a取出它的地址,可以使用&操作。
//將a的地址存放在p變量中國(guó),p就是一個(gè)指針變量
}
小結(jié):指針就是變量,內(nèi)容是地址。(存放在指針中的值被當(dāng)做地址處理)
指針的大小
- 在32為計(jì)算機(jī)上指針大小4字節(jié)。
- 在64為計(jì)算機(jī)上指針大小8字節(jié)。
指針和指針變量
關(guān)于地址
printf("%p \n",&a);//%p地址格式 &a取a的地址int* p = &a; //int*指針類(lèi)型 //p 指針變量 //&a 取地址
使用
*p //解引用操作符
int a =10; //在內(nèi)存中存儲(chǔ)10 還有char*等類(lèi)型
int* p = &a;//定義指針,位置為a的內(nèi)存
*p = 20; //更改指針指向內(nèi)存的 值
printf("a= %d",a);//結(jié)果為a=20
int* p的理解 p是int類(lèi)型的一個(gè)指針(僅此而已),一般*p指向的也是一個(gè)int型的
1. 指針類(lèi)型決定了指針進(jìn)行解引用操作的時(shí)候,能訪問(wèn)空間的大小
int main(){
int n = 0x112233;
char* p = (char*)&n;
int* pi = &n;
*pc = 0; //在調(diào)試的過(guò)程中觀察內(nèi)存的變化。
*pi = 0;
return 0;
}
int*; *p可以訪問(wèn)4個(gè)字節(jié)。 char*; *p可以訪問(wèn)1個(gè)字節(jié)。 double*; *p可以訪問(wèn)8個(gè)字節(jié)。
原因 是類(lèi)型本身所需的內(nèi)存空間就是指針可以控制的空間。
意義:使用時(shí)選用合適的指針類(lèi)型進(jìn)行定義
2. 指針加減整數(shù)
int main(){
int a = 0x11223344;
int* p1 = &a;
char* p2 = &a;
printf("%p\n",p1);
printf("%p\n",p1+1);
printf("%p\n",p2);
printf("%p\n",p2+1);
return 0;
}

int類(lèi)型時(shí)0C->10 變化4, char類(lèi)型時(shí)0C->0D 變化1。
理解:指針加一不是指向下一個(gè)緊挨著的地址,是指向下一個(gè)指針變量對(duì)應(yīng)的類(lèi)型變量開(kāi)始的地址。
意義 指針類(lèi)型決定了:指針走一步走多遠(yuǎn)(指針的步長(zhǎng))
野指針
野指針就是指針指向的位置是不可知的(隨機(jī)的、不正確的、沒(méi)有明確限制的)
野指針的成因
1.指針未初始化
int main(){ int a;//局部變量不初始化,默認(rèn)是隨機(jī)值 int *p;//局部的指針變?nèi)绻麤](méi)有初始化,就被初始化為隨機(jī)值。}int main(){
int a;//局部變量不初始化,默認(rèn)是隨機(jī)值
int *p;//局部的指針變?nèi)绻麤](méi)有初始化,就被初始化為隨機(jī)值。
}
2.指針越界訪問(wèn)
int main(){
int arr[10];
int *p = arr;
for(int i = 0;i<12;i++){
p++;
}
//當(dāng)指針的范圍超出數(shù)組的范圍時(shí),p就是野指針。
}
3.指針指向的空間釋放
int main(){
int arr[10];
int *p = arr;
for(int i = 0;i<12;i++){
p++;
}
//當(dāng)指針的范圍超出數(shù)組的范圍時(shí),p就是野指針。
}
解析:在main函數(shù)調(diào)用test()時(shí),進(jìn)入test()函數(shù),int a語(yǔ)句開(kāi)辟臨時(shí)的內(nèi)存空間并將這個(gè)內(nèi)存空間存儲(chǔ)為10;返回函數(shù)的時(shí)候返回的臨時(shí)的a的地址給*p,然后test函數(shù)已經(jīng)在執(zhí)行完test函數(shù)后結(jié)束,a的內(nèi)存空間被銷(xiāo)毀。這時(shí)的*p就是指向的地址正確但是內(nèi)容已經(jīng)改變。
將未知位置的值進(jìn)行修改是非常危險(xiǎn)的
如何避免野指針
1.指針初始化
2.小心指針越界
3.指針指向內(nèi)存釋放 即 指向NULL
4.指針只用之前檢查有效性
指針運(yùn)算
1.指針加減整數(shù)
2.指針-指針
3.指針的關(guān)系運(yùn)算
指針加減指針
int main(){
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
int* p = arr;
for(int i=0;i<sz;i++){
printf("%d ",*p);
p = p+1;// p++
}
int* p = &arr[9];
for(int i=0;i>0;i++){
printf("%d ",*p);
p-=1;// p++
}
return 0;
}
指針-指針
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",&arr[9]-&arr[0]);//輸出9 中間元素的個(gè)數(shù)。
printf("%d",&arr[0]-&arr[9]);//輸出-9
return 0;
}
指針減指針必須是自己減去自己。否則結(jié)果不可預(yù)知。
指針實(shí)現(xiàn)strlen()
int my_strlen(char* str){
char* start = str;
char* end = str;
while(*end != '\0'){
end++;
}
return ;
}
int main(){
char arr[] = "hello";
int len = my_strlen(arr);
printf("%d\n",len);
return 0;
}
指針的關(guān)系運(yùn)算
int main(){
float values[5];
for(float* vp=&values[5];vp>&values[0];){
printf("haha ");
*--vp = 0;
}
return 0;
}
這里碰到了兩個(gè)問(wèn)題 1. values[5]本身不屬于數(shù)組的部分。但是可以使用。經(jīng)測(cè)試values[5]不會(huì)警告,但是values[-1]及以下或values[6]及以上都會(huì)報(bào)錯(cuò)。2.指針的加減是類(lèi)型位置的移動(dòng)數(shù)組總也就是一個(gè)一個(gè)往過(guò)走。
for(float* vp=&values[5-1];vp>=&values[0];vp--){
printf("haha ");
*vp = 0;
}
這里在絕大多數(shù)的編譯器上是可以順利完成任務(wù)的,然而我們應(yīng)該避免這第二種寫(xiě)法,因?yàn)闃?biāo)準(zhǔn)不能保證他是可行的。
標(biāo)準(zhǔn)規(guī)定:允許指向數(shù)組元素的指針和指針與指向數(shù)組最后一個(gè)元素后面的那個(gè)內(nèi)存位置的指針比較,但是不允許與指向第一個(gè)元素之前的那個(gè)位置的指針進(jìn)行比較。
指針和數(shù)組
int main(){
int arr[10]={0};
printf("%p\n",arr); //地址-首元素地址
printf("%p\n",&arr[0]);
}
一般情況數(shù)組名都代表首元素的地址
除了:
1. &數(shù)組名 這時(shí)數(shù)組名代表整個(gè)數(shù)組的地址
2. sizeof(數(shù)組名) 這時(shí)也是代表整個(gè)數(shù)組。
二級(jí)指針
將第一層指針1想成變量,再取這個(gè)變量的地址存為一個(gè)指針2。那么指針2指向指針1,指針1指向原變量。原變量的地址存在了指針1中,指針1的地址存在了指針2中。
int main(){
int a = 10;
int* pa = &a;
int** ppa = &pa;//ppa就是二級(jí)指針。
//存在三級(jí)及以上指針,(無(wú)限套娃)
}
指針數(shù)組、數(shù)組指針
指針數(shù)組其實(shí)是個(gè)數(shù)組,數(shù)組指針是個(gè)指針
指針數(shù)組:存放指針的數(shù)組
int a = 10;
int b = 20;
int c = 30;
int* arr[3] = {&a,&b,&c};//指針數(shù)組
數(shù)組指針:指向數(shù)組的指針。
main(){
int a = 10;
int* pa = &a;
int** ppa = &pa;//ppa就是二級(jí)指針。
//存在三級(jí)及以上指針,(無(wú)限套娃)
}
### 指針數(shù)組、數(shù)組指針
指針數(shù)組其實(shí)是個(gè)數(shù)組,數(shù)組指針是個(gè)指針
<u>**指針數(shù)組**</u>:存放指針的數(shù)組
~~~c
int a = 10;
int b = 20;
int c = 30;
int* arr[3] = {&a,&b,&c};//指針數(shù)組
數(shù)組指針:指向數(shù)組的指針。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單回聲服務(wù)器
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單回聲服務(wù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C/C++中static,const,inline三種關(guān)鍵字詳細(xì)總結(jié)
以下是對(duì)C/C++中static,const,inline的三種關(guān)鍵字進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09
C++詳細(xì)講解互斥量與lock_guard類(lèi)模板及死鎖
線程的主要優(yōu)勢(shì)在于,能夠通過(guò)全局變量來(lái)共享信息。不過(guò),這種便捷的共享是有代價(jià)的:必須確保多個(gè)線程不會(huì)同時(shí)修改同一變量,或者某一線程不會(huì)讀取正由其他線程修改的變量。為了防止出現(xiàn)線程某甲試圖訪 問(wèn)一共享變量時(shí),線程某乙正在對(duì)其進(jìn)行修改。引入了互斥量2022-07-07

