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