複製鏈接
請複製以下鏈接發送給好友

指針

(編程語言中的一個對象)

鎖定
指針,是C語言中的一個重要概念及其特點,也是掌握C語言比較困難的部分。指針也就是內存地址,指針變量是用來存放內存地址的變量,在同一CPU構架下,不同類型的指針變量所佔用的存儲單元長度是相同的,而存放數據的變量因數據的類型不同,所佔用的存儲空間長度也不同。有了指針以後,不僅可以對數據本身,也可以對存儲數據的變量地址進行操作。 [1] 
指針描述了數據在內存中的位置,標示了一個佔據存儲空間實體,在這一段空間起始位置的相對距離值。在 C/C++語言中,指針一般被認為是指針變量,指針變量的內容存儲的是其指向的對象的首地址,指向的對象可以是變量(指針變量也是變量),數組函數等佔據存儲空間的實體。
中文名
指針
外文名
pointer
特    點
可對存儲數據的變量地址進行操作 [1] 
適用對象
高級語言 [2] 
性    質
不同類型的指針變量所佔用的存儲單元長度是相同的 [1] 
定    義
內存地址 [1] 

指針基本問題

計算機中,所有的數據都是存放在存儲器中的,不同的數據類型佔有的內存空間的大小各不相同。內存是以字節為單位的連續編址空間,每一個字節單元對應着一個獨一的編號,這個編號被稱為內存單元的地址。比如:int 類型佔 4 個字節,char 類型佔 1 個字節等。系統在內存中,為變量分配存儲空間的首個字節單元的地址,稱之為該變量的地址。地址用來標識每一個存儲單元,方便用户對存儲單元中的數據進行正確的訪問。在高級語言中地址形象地稱為指針。 [2] 

指針地址與指針

指針相對於一個內存單元來説,指的是單元的地址,該單元的內容裏面存放的是數據。在 C 語言中,允許用指針變量來存放指針,因此,一個指針變量的值就是某個內存單元的地址或稱為某內存單元的指針。 [1] 

指針變量及其定義

指針變量是存放一個內存地址的變量,不同於其他類型變量,它是專門用來存放內存地址的,也稱為地址變量。定義指針變量的一般形式為:類型説明符*變量名。 [1] 
類型説明符表示指針變量所指向變量的數據類型;*表示這是一個指針變量;變量名錶示定義的指針變量名,其值是一個地址,例如:char*p1;表示 p1 是一個指針變量,它的值是某個字符變量的地址。 [1] 

指針變量與其指向的對象的關聯

#include <stdio.h>  
//測試環境: Windows 10 Pro x86(32位)
//打印的變量(i或者p)的地址可能每次都不一樣
int main(int argc,char** argv)
{
    int i = 0x12345678;         
    int* p = &i;              
 
    printf("0x%08x \n", i);      //打印結果: 0x12345678
    printf("0x%08x \n", &i);     //打印結果: 0x004ffed0
    printf("%d \n", sizeof(i));  //打印結果: 4
 
    printf("0x%08x \n", p);      //打印結果: 0x004ffed0
    printf("0x%08x \n", &p);     //打印結果: 0x004ffecc
    printf("%d \n", sizeof(p));  //打印結果: 4
  
    // 指針變量p指向的對象是變量i

    // 1.指向的對象變量i的地址是&i(0x004ffed0)
    // 2.指向的對象變量i的類型是int
    // 3.指向的對象變量i的內容是0x12345678
    // 4.指針變量p本身的地址是&p(0x004ffecc)
    // 5.指針變量p本身的類型是int*
    // 6.指針變量p本身的內容是&i(0x004ffed0)
  
    return 0;
}
從示例代碼打印結果可以看出,指針變量p存儲的內容就是其所指向的變量i的地址。指針變量p本身也是一個變量,也需要佔據存儲空間(32位系統下佔4個字節),同樣也有地址。

指針運算符

  • & 取址運算符
功能:返回變量的內存地址(升一級) [4] 
  • * 取值運算符
功能:訪問指針指向的變量(降一級) [4] 

指針指針運算

  • 指針±數值:p±n等價於p±n*c 。
  • 指針-指針:結果為兩指針所指向地址間數據的個數。
  • 指針 比較 指針:產生的結果為 0(假)和 1(真)。 [4] 

指針注意事項

指針不允許把一個數賦予指針變量

不允許把一個數賦予指針變量,故下面的賦值是錯誤的。例如: [1] 
錯誤操作 錯誤操作
分析:前面例子中定義了一個指針變量 pointer,但是不能直接把 200 賦值給指針變量 pointer。後面的例子中定義了一個整型變量 a,並賦初始值為 200,又定義了一個指針變量 pointer,這個變量指向整型數據,pointer 中只能用來存放整型變量的地址,而不能直接把整型變量a賦值給這個指針變量 pointer。所以可以把a的地址賦值給 pointer;應改成: [1] 
改正 改正

指針改變形參不代表改變實參

不能企圖通過改變指針形參的值而使指針實參的值改變。例如下面是錯誤的: [1] 
錯誤 錯誤
改正 改正

指針字符串指針

字符串指針指向的是一個字符串,例如下面是錯誤的: [1] 
錯誤 錯誤
分析:string1是一個指針變量,指向字符串"I love China",指針變量 string1 存放的是這個字符串的首地址。所以輸出的是一個字符串,應改寫成 printf(“%s\n”,string1); [1] 

指針調用函數指針

函數指針變量的調用,以下是錯誤的: [1] 
錯誤 錯誤
分析函數指針變量不能進行算術運算,這是與數組指針變量不同的。數組指針變量加減一個整數可使指針移動指向後面或前面的數組元素,而函數指針的移動是毫無意義的。函數調用中 “(*指針變量名)” 的兩邊的括號不可少,其中的 “ * ” 不應該理解為求值運算,在此處只是一種表示符號。要把“ z=*pomax(x,y);”改成“ z=(*pomax)(x,y);”。 [1] 

指針信息工程

C語言,在1972年開發Unix操作系統時,丹尼斯里奇和肯湯姆遜設計了C語言。C語言不完全是裏奇突發奇想而來,他是在肯·湯普遜發明的b語言的基礎上進行設計。把C語言作為程序員的編程工具是它設計的初衷,因此它的主要目標是成為一種有用的語言。作為面向過程抽象化的通用編程語言,C語言在底層開發中得到了廣泛的應用。C語言可以進行簡單地編譯和處理低級內存,是一種高效的編程語言,它只產生少量的機器語言,可以在沒有任何運行環境支持的情況下運行。 [3] 
函數是執行特定任務的獨立程序代碼單元。函數的結構和用法已經被C語言的語法規則定義了。函數在C語言中的細節略有不同。某些函數執行操作,如printf( ) 的作用是將數據打印在屏幕上顯示出來,而一些函數則查找直接程序以供使用,如strlen( ),向程序返回指定字符串的長度。 [3] 

指針指向函數的指針

程序編譯後,每個函數都有執行第一條指令的地址即首地址,稱為函數指針。函數指針即指向函數的指針變量,要間接調用函數可以使用指針變量來實現。 [3] 
int(*pf)(int, int); [3] 
通過將pf與括號中的“ * ”強制組合組合在一起,表示定義的pf是一個指針,然後與下面的“ ( ) ”再次組合,表示的是該指針指向一個函數,括號裏表示為int類型的參數,最後與前面的int組合,此處int表示該函數的返回值。因此,pf是指向函數的指針,該函數的返回值為int。函數指針與返回指針的函數的含義大不相同。函數指針本身是一個指向函數的指針。指針函數本身是一個返回值為指針的函數。 [3] 
舉例説明 舉例説明
float(*p)(float x,float y);定義了一個指向函數的指針變量。首先c=(*p)(a,b);語句:因為指針p儲存的是max函數的首地址,(*p)(a,b) 就相當於 max(a,b),函數返回較大值。其次c=(*p)(a,b);語句:因為指針p儲存的是 min函數的首地址,(*p)(a,b) 也就相當於min(a,b),函數返回較小值。 [3] 
舉例説明 舉例説明

指針指針變量的初始化

指針通過賦值語句初始化指針變量

C語言中指針初始化是指給所定的指針變量賦初值。 [2] 
舉例説明 舉例説明

指針野指針

C語言中指針初始化是指給所定義的指針變量賦初值。指針變量在被創建後,如果不被賦值,他的缺省值是隨機的,它的指向是不明確的,這樣的指針形象地稱為“野指針”。野指針是很危險的,容易造成程序出錯,且程序本身無法判斷指針指向是否合法。 [2] 
指針變量初始化時避免野指針的方法:可以在指針定義後,賦值NULL空值,也可寫成如下形式:
p=0或p='\0'
這兩種形式和p=NULL是等價
舉例説明 舉例説明
上面兩行代碼的含義是,指針變量p被賦值為空。雖然定義了一個指針變量,但是它並不指向任何存儲空間 [2] 
參考資料