C語言全方位講解指針的使用
接著上次的函數(shù)的基本知識(shí),今天我們來講一講指針
一、指針的概念
1.1、變量和地址
所謂指針,也就是內(nèi)存的地址;所謂指針變量,也就是保存了內(nèi)存地址的變量。
總結(jié):指針就是變量,用指針存放地址(口語中說的指針通常指的是指針變量)
1.2、指針變量和指針的類型
指針變量就是一個(gè)變量,它存儲(chǔ)的內(nèi)容是一個(gè)指針。在我們定義一個(gè)變量的時(shí)候,要確定它的類型。在定義指針變量時(shí)也是一樣的,必須確定指針類型。int 變量的指針需要用 int 類型的指針存儲(chǔ),float 變量的指針需要用 float 類型的指針存儲(chǔ)。
指針類型決定了:指針解引用的權(quán)限有多大與指針走一步走多大字節(jié)(步長(zhǎng))
整型指針+1跳過一個(gè)整型。字符指針+1跳過一個(gè)字符
二、指針變量
2.1、指針變量的定義及使用
(1)指針變量的定義
指針變量的定義形式如:數(shù)據(jù)類型 *指針名;例如:
int* x;//整型指針變量 float* f;//浮點(diǎn)型指針變量 char* ch;//字符型指針變量
指針的變量名分別是:x;f和ch。而int*;float*與char*分別是他們中存儲(chǔ)的數(shù)據(jù)的類型。
(2)指針變量的使用
取地址運(yùn)算符&:?jiǎn)文窟\(yùn)算符&是用來取操作對(duì)象的地址。例:&i 為取變量 i 的地址。對(duì)于常量表達(dá)式、寄存器變量不能取地址(因?yàn)樗鼈兇鎯?chǔ)在存儲(chǔ)器中,沒有地址)。
指針運(yùn)算符*(解引用運(yùn)算符 ):與&為逆運(yùn)算,作用是通過操作對(duì)象的地址,獲取存儲(chǔ)的內(nèi)容。例:x = &i,x 為 i 的地址,*x 則為通過 i 的地址,獲取 i 的內(nèi)容。
//聲明了一個(gè)普通變量 a int a; //聲明一個(gè)指針變量,指向變量 a 的地址 int *pa; //通過取地址符&,獲取 a 的地址,賦值給指針變量 pa = &a; //通過間接尋址符,獲取指針指向的內(nèi)容 printf("%d", *pa);
2.2、指針運(yùn)算
(1)指針與整數(shù)的加減運(yùn)算
指針變量的自增自減運(yùn)算。指針加 1 或減 1 運(yùn)算,表示指針向前或向后移動(dòng)一個(gè)單元(不同類型的指針,單元長(zhǎng)度不同)。
(2)指針減指針
前提是兩個(gè)指針指向同一個(gè)空間。
指針減指針得到兩個(gè)指針間的元素個(gè)數(shù)
例: Arr[9]指向9與10中間部分(下標(biāo))
三、野指針
3.1、概念:
野指針就是指針指向的為止是不可知的(隨機(jī)的,不正確的,沒有明確限制的)
3.2、野指針的成因
(1)指針未初始化
(2)指針越界
如圖:在第十次 訪問時(shí),可以進(jìn)入到循環(huán),相當(dāng)于從第10個(gè)點(diǎn)向后訪問4個(gè)字節(jié),之后的字節(jié)不屬于原數(shù)組,則越界了,則稱為野指針。(只有在超出范圍后,在會(huì)發(fā)生崩潰)
//越界訪問 *int arr[10] ={ 0 }; int* p = arr; int i=0; for (i=0; i <= 10; i++)//共執(zhí)行了11次,而arr數(shù)組總共只有10個(gè)元素 { *p = i; p++; }
(3)指針指向的空間釋放
int* test()//局部變量 { int a = 10; return &a; } int main() { int *p=test();//返回值是a的地址,而局部變量在引用之后就會(huì)銷毀。 *p = 20; return 0; }
3.3、如何規(guī)避野指針
1.指針初始化
2.小心指針越界。
3.指針指向空間釋放即置NULL
4.指針使用之前檢查有效性。
四、字符指針
4.1、字符指針類型
在指針的類型中我們知道有一種指針類型為字符指針 char* ; 一般使用:
int main() { const char* pstr = "hello ";//這里是把一個(gè)字符串放到pstr指針變量里了嗎? printf("%s\n", pstr); return 0; }
本質(zhì)是把字符串 hello首字符的地址放到了pstr中。
4.2、例題
int main() { char str1[] = "hello bit."; char str2[] = "hello bit."; const char *str3 = "hello bit."; const char *str4 = "hello bit."; if(str1 ==str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if(str3 ==str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n"); return 0; }
最終輸出的結(jié)果是
這里str3和str4指向的是一個(gè)同一個(gè)常量字符串。C/C++會(huì)把常量字符串存儲(chǔ)到單獨(dú)的一個(gè)內(nèi)存區(qū)域。當(dāng)幾個(gè)指針指向同一個(gè)字符串的時(shí)候,他們實(shí)際會(huì)指向同一塊內(nèi)存。 但是用相同的常量字符串去初始化不同的數(shù)組的時(shí)候就會(huì)開辟出不同的內(nèi)存塊。所以str1和str2不同,str3和str4不同。
五、指針與數(shù)組
之前我們可以通過下標(biāo)訪問數(shù)組元素,學(xué)習(xí)了指針之后,我們可以通過指針訪問數(shù)組的元素。在數(shù)組中,數(shù)組名即為該數(shù)組的首地址,結(jié)合上面指針和整數(shù)的加減,我們就可以實(shí)現(xiàn)指針訪問數(shù)組元素。
5.1、指針與二維數(shù)組
(1)二維數(shù)組的地址
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int *p=a[0];//此處的p內(nèi)存放的數(shù)組a第一行的地址。
5.2、多級(jí)指針
(1)多級(jí)指針(指向指針的指針)
指針變量作為一個(gè)變量也有自己的存儲(chǔ)地址,而指向指針變量的存儲(chǔ)地址就被稱為指針的指針,即二級(jí)指針。依次疊加,就形成了多級(jí)指針。
指針變量也是一種變量,也會(huì)占用存儲(chǔ)空間,也可以使用 &獲取它的地址。C語言不限制指針的級(jí)數(shù),每增加一級(jí)指針,在定義指針變量時(shí)就得增加一個(gè)星號(hào) *。p1 是一級(jí)指針,指向普通類型的數(shù)據(jù),定義時(shí)有一個(gè) *;p2 是二級(jí)指針,指向一級(jí)指針 p1,定義時(shí)有兩個(gè)*。例:假設(shè)有一個(gè) int 類型的變量 a,p1是指向 a 的指針變量,p2 又是指向 p1 的指針變量,它們的關(guān)系如下圖所示:
六、指針數(shù)組
1.parr的第一個(gè)數(shù)組里放arr1的首元素地址
2.parr每個(gè)元素的類型是int*。
3.該數(shù)組里每個(gè)元素都是指針,所以它是一個(gè)指針數(shù)組
4.Parr[i][j],也可以寫成parr[i]+j,
5.相當(dāng)于地址+j為向后挨個(gè)元素指向
七、數(shù)組指針
7.1、數(shù)組指針的定義
如以下語句:
int (*p)[10]; //解釋:p先和*結(jié)合,說明p是一個(gè)指針變量,然后指著指向的是一個(gè)大小為10個(gè)整型的數(shù)組。 //所以p是一個(gè)指針,指向一個(gè)數(shù)組,叫數(shù)組指針。 //這里要注意:[]的優(yōu)先級(jí)要高于*號(hào)的,所以必須加上()來保證p先和*結(jié)合。
7.2、&數(shù)組名與數(shù)組名
讓我們看一段代碼
#include <stdio.h> int main() { int arr[10] = { 0 }; printf("arr = %p\n", arr); printf("&arr= %p\n", &arr); printf("arr+1 = %p\n", arr+1); printf("&arr+1= %p\n", &arr+1); return 0; }
運(yùn)行結(jié)果如下
根據(jù)上面的代碼我們發(fā)現(xiàn),其實(shí)&arr和arr,雖然值是一樣的,但是意義應(yīng)該不一樣的。
實(shí)際上: &arr 表示的是數(shù)組的地址,而不是數(shù)組首元素的地址。(細(xì)細(xì)體會(huì)一下)
本例中 &arr 的類型是: int(*)[10] ,是一種數(shù)組指針類型。
數(shù)組的地址+1,跳過整個(gè)數(shù)組的大小。
7.3、數(shù)組指針的使用
#include <stdio.h> void print_arr1(int arr[3][5], int row, int col)//形參用數(shù)組來接受 { int i = 0; for(i=0; i<row; i++) { for(j=0; j<col; j++) { printf("%d ", arr[i][j]); }}} void print_arr2(int (*arr)[5], int row, int col)//形參用數(shù)組指針來接受 { int i = 0; for(i=0; i<row; i++) { for(j=0; j<col; j++) {printf("%d ", arr[i][j]);} printf("\n");}} int main() { int arr[3][5] = {1,2,3,4,5,6,7,8,9,10}; print_arr1(arr, 3, 5); //數(shù)組名arr,表示首元素的地址 //但是二維數(shù)組的首元素是二維數(shù)組的第一行 //所以這里傳遞的arr,其實(shí)相當(dāng)于第一行的地址,是一維數(shù)組的地址 //可以數(shù)組指針來接收 print_arr2(arr, 3, 5); return 0; }
八、指針與函數(shù)
8.1、函數(shù)指針的定義
returnType (*pointerName)(param list);
其中,returnType 為函數(shù)返回值類型,pointerNmae 為指針名稱,param list 為函數(shù)參數(shù)列表。參數(shù)列表中可以同時(shí)給出參數(shù)的類型和名稱,也可以只給出參數(shù)的類型,省略參數(shù)的名稱,這一點(diǎn)和函數(shù)原型非常類似。 注意( )的優(yōu)先級(jí)高于*,第一個(gè)括號(hào)不能省略,如果寫作returnType *pointerName(param list);就成了函數(shù)原型,它表明函數(shù)的返回值類型為returnType *。
8.2、指向函數(shù)的指針
int (*pf[4])(int,int)={Add,Sub,Mul,Div};
函數(shù)指針數(shù)組,在函數(shù)指針的基礎(chǔ)上,將指針變?yōu)橹羔様?shù)組
總結(jié)
以上就是初階指針的基本內(nèi)容了?。。。》浅8兄x你能看到這里!
如果你覺得你有些想法和我一樣,想和我一起提升自己可以關(guān)注私信我,與我一起進(jìn)步,一起共同努力?。。。?!
到此這篇關(guān)于C語言全方位講解指針的使用的文章就介紹到這了,更多相關(guān)C語言 指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++靜態(tài)鏈接與動(dòng)態(tài)鏈接詳解
下面小編就為大家介紹C++靜態(tài)鏈接與動(dòng)態(tài)鏈接。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2021-10-10C++?RBTree紅黑樹的性質(zhì)與實(shí)現(xiàn)
紅黑樹是一種二叉搜索樹,但在每個(gè)結(jié)點(diǎn)上增加一個(gè)存儲(chǔ)位表示結(jié)點(diǎn)的顏色,可以是Red或Black;通過對(duì)任何一條從根到葉子的路徑上各個(gè)結(jié)點(diǎn)著色方式的限制,紅黑樹確保沒有一條路徑會(huì)比其他路徑長(zhǎng)出倆倍,因而是平衡的2023-03-03C語言實(shí)現(xiàn)程序開機(jī)自啟動(dòng)
本文給大家分享的是一則C語言實(shí)現(xiàn)開機(jī)自啟動(dòng)的代碼,主要是通過C來獲取程序路徑修改注冊(cè)表項(xiàng)來實(shí)現(xiàn),有需要的小伙伴可以參考下2016-01-01vscode使用cmake時(shí)將命令行參數(shù)傳遞給調(diào)試目標(biāo)的方法
這篇文章主要介紹了vscode使用cmake時(shí)將命令行參數(shù)傳遞給調(diào)試目標(biāo),下面介紹了一個(gè)示例,將參數(shù)first_arg, second-arg和third arg傳遞給程序(此處需要注意,third arg中間雖然存在空格,但是仍然被視作一個(gè)參數(shù)),需要的朋友參考下吧2024-03-03C++教程之a(chǎn)rray數(shù)組使用示例詳解
這篇文章主要為大家介紹了C++教程之a(chǎn)rray數(shù)組使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03