C语言精要总结-指针系列(二)
?
此文為指針系列第二篇:
C語言精要總結(jié)-指針系列(一)
C語言精要總結(jié)-指針系列(二)
指針運(yùn)算
前面提到過指針的解引用運(yùn)算,除此之外,指針還能進(jìn)行部分算數(shù)運(yùn)算、關(guān)系運(yùn)算
指針能進(jìn)行的有意義的算術(shù)運(yùn)算包括加減法運(yùn)算,但不包括乘除運(yùn)算。并且運(yùn)算存在諸多限制。
加法運(yùn)算
指針加法運(yùn)算只適合指針與整數(shù),不能用在指針與指針。
指針加上或者減去一個整數(shù)n,是存儲的地址值加上或者減去n*指針指向類型的空間大小。也就是
結(jié)果指針 = 指針 ±? n * 指針指向類型空間大小。
例如int類型的整數(shù)指針+1,運(yùn)算結(jié)果依然是一個整型指針,其存儲的地址值為原指針值+1*4,這是因?yàn)檎妥兞空加?個字節(jié)的空間。這個計(jì)算結(jié)果,恰好在當(dāng)前指針指向基礎(chǔ)上,向下偏移指向下一個相同類型的空間。如下圖
?
指針與整數(shù)的加減法一般用在迭代連續(xù)的內(nèi)存空間-數(shù)組,如果運(yùn)算得到的指針指向第一個元素之前或者最后一個元素之后,可能會產(chǎn)生非法讀寫內(nèi)存中斷,就像引用一個未初始化的指針一樣不可預(yù)知。
指針除了可以與整數(shù)做加減運(yùn)算,連個指針之間還可以做減法運(yùn)算(不能做加法運(yùn)算)且必須是同類型的指針。運(yùn)算結(jié)果為兩個指針指向地址之間,可以存放多少此類型的變量數(shù)(或其相反數(shù)),類型為ptrdiif_t類型(一種有符號整數(shù)類型)。
1 int * p1 = (int *) 0x100; 2 int * p2 = (int *) 0x10c; 3 printf("p2-p1 : %d\n",p1 - p2); // -3如上程序?qū)⑤敵?3,也如上圖所示,這3個空間存放著 10、80、6三個整型變量。
指針與指針相減,一般也用在連續(xù)地址空間-數(shù)組中。此時兩個指針相減跟下標(biāo)索引相減是等價(jià)的。
1 int arr[5] ; 2 printf("%d\n",&arr[4] - &arr[0] == 4 - 0); // 1常量指針與指針常量
常量指針表示通過此指針,不能修改其指向的內(nèi)存區(qū)域的內(nèi)容,指針本身的值是可以修改為指向另一個變量,雖然可以修改指向另一個變量,但是依然不允許修改指向變量里的內(nèi)容。常量指針一般用在函數(shù)一些函數(shù)參數(shù)中,以只讀的方式傳遞函數(shù)參數(shù)。這里說明一點(diǎn)C語言除了宏定義常量和枚舉之外,是不能定義普通常量的,只可用const定義只讀變量,而常量指針指向的是就是一個只讀變量。只讀變量是不能修改的變量。
1 const int readOnlyVar = 10; 2 int * pROVar = (int *) & readOnlyVar; 3 * pROVar = 11; 4 printf("%d\n",readOnlyVar);而指針常量表示指針本身的內(nèi)容不可變(指向不可變),因此,定義指針常量時必須同時初始化一個地址值。
定義指針常量和定義常量指針的方式區(qū)別在于const關(guān)鍵字的位置
int const * p1 ; const int * p2 ; int * const p3 = NULL; const int * const p4 = NULL;以*號為界限,看cosnt修飾的是誰,如果修飾的是類型關(guān)鍵字,表示指向常量類型——常量指針,如果修飾的是指針標(biāo)識符,表示指針常量。顯然p1、p2是常量指針,p3是指針常量,p4既是常量指針,又是指針常量。
指針數(shù)組
指針數(shù)組指元素由指針組成的數(shù)組,一般用在存儲字符串組,例如下面的程序
1 char * options[5] = { 2 "--list", 3 "--prefix", 4 "--with" 5 }; 6 for (i = 0 ; i < 5 ;i ++) 7 { 8 if (NULL != options[i]){ 9 printf("%s\n",options[i]); 10 } 11 }此時指針數(shù)組前三個成員指向靜態(tài)區(qū)的三個字符串常量,而后兩個指針被默認(rèn)初始化為0(NULL)
C語言中出現(xiàn)的字符串字面量,實(shí)際是存儲在靜態(tài)數(shù)據(jù)區(qū)的字符串常量。當(dāng)一個字符串出現(xiàn)在C語言表達(dá)式中,其實(shí)際值是一個指針常量。如下面聲明一個指針常量的代碼
char * str = "hello";可以用另一段代碼來描述,即先在某處為字符串分配空間,記錄指向第一個字符的一個指針常量,并將字符拷貝進(jìn)去。代碼如下
char * const strBuff = (char * ) malloc (6); strcpy(strBuff,"hello"); char * str = strBuff; free(strBuff);既然明確字符串常量在代碼中實(shí)際是一個指針常量,因此其也可以參與運(yùn)算。代碼如下
printf("%c\n",* "hello"); // h printf("%s\n", "hello" + 1);// ello常量指針“hello”+1后得到一個新的指針,按指針運(yùn)算的規(guī)則將指向下一個e,所以以字符串形式輸出ello
除此之外指針輸在還用在處理許多多維數(shù)組的地方,這在后續(xù)的章節(jié)中會提到。
常量指針數(shù)組與指針常量數(shù)組
常量指針數(shù)組表示元素都指向常量的數(shù)組。定義方式如下
1 const char * options[5] = { 2 "--list", 3 "--prefix", 4 "--with" 5 };當(dāng)然,這里的例子,const加與不加沒太大區(qū)別,因?yàn)?span style="color:#ff0000;">即便不加const關(guān)鍵字,options中的每一個元素依然是指向一個字符串常量,是不能修改的。例如要將“--list”中的第2個‘-’換成'+'號,下面的代碼是行不通的,方法只有讓指針指向一個全新的字符串常量(因?yàn)槭浅A恐羔?#xff0c;所以指針本身的內(nèi)容可以修改)
* (options[0] + 1) = '+';加上const的好處是,讓編譯器或者IDE工具在運(yùn)行之前便告知你此類代碼存在的問題。關(guān)于字符串常量,下面的異常代碼可能更易懂一些
char * str = "hello"; *(str + 3) = 'w';指針常量數(shù)組表示每個指針元素都是不可修改的(指向固定了),但是其指向內(nèi)容,視情況是可以修改的。
1 char * const options[5] = { 2 "--list", 3 "--prefix", 4 "--with" 5 };當(dāng)然,因?yàn)樽址A康木壒?#xff0c;上面的代碼定義了一個指針元素、指針元素指向區(qū)域內(nèi)都不可變的指針數(shù)組。例如,像下面的代碼都是非法的
1 options[0] = tmpStr; // 修改指針指向新的字符串常量 2 *(options[0]) = '+'; // 修改第一個元素指向區(qū)域的內(nèi)容下一系列將用一兩個復(fù)雜的案例詳細(xì)講解指針與數(shù)組的關(guān)系。
總結(jié)
以上是生活随笔為你收集整理的C语言精要总结-指针系列(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 带你入门 CSS Grid 布局
- 下一篇: Maven环境搭建