
- C程式設計教程
- C - 首頁
- C語言基礎
- C - 概述
- C - 特性
- C - 歷史
- C - 環境設定
- C - 程式結構
- C - Hello World
- C - 編譯過程
- C - 註釋
- C - 詞法單元
- C - 關鍵字
- C - 識別符號
- C - 使用者輸入
- C - 基本語法
- C - 資料型別
- C - 變數
- C - 整數提升
- C - 型別轉換
- C - 型別強制轉換
- C - 布林值
- C語言中的常量和字面量
- C - 常量
- C - 字面量
- C - 轉義序列
- C - 格式說明符
- C語言中的運算子
- C - 運算子
- C - 算術運算子
- C - 關係運算符
- C - 邏輯運算子
- C - 位運算子
- C - 賦值運算子
- C - 一元運算子
- C - 自增和自減運算子
- C - 三元運算子
- C - sizeof運算子
- C - 運算子優先順序
- C - 其他運算子
- C語言中的決策
- C - 決策
- C - if語句
- C - if...else語句
- C - 巢狀if語句
- C - switch語句
- C - 巢狀switch語句
- C語言中的迴圈
- C - 迴圈
- C - while迴圈
- C - for迴圈
- C - do...while迴圈
- C - 巢狀迴圈
- C - 無限迴圈
- C - break語句
- C - continue語句
- C - goto語句
- C語言中的函式
- C - 函式
- C - 主函式
- C - 按值傳遞函式呼叫
- C - 按引用傳遞函式呼叫
- C - 巢狀函式
- C - 可變引數函式
- C - 使用者定義函式
- C - 回撥函式
- C - 返回語句
- C - 遞迴
- C語言中的作用域規則
- C - 作用域規則
- C - 靜態變數
- C - 全域性變數
- C語言中的陣列
- C - 陣列
- C - 陣列的特性
- C - 多維陣列
- C - 將陣列傳遞給函式
- C - 從函式返回陣列
- C - 變長陣列
- C語言中的指標
- C - 指標
- C - 指標和陣列
- C - 指標的應用
- C - 指標運算
- C - 指標陣列
- C - 指標到指標
- C - 將指標傳遞給函式
- C - 從函式返回指標
- C - 函式指標
- C - 指向陣列的指標
- C - 指向結構體的指標
- C - 指標鏈
- C - 指標與陣列
- C - 字元指標和函式
- C - 空指標
- C - void指標
- C - 懸空指標
- C - 解引用指標
- C - 近、遠和巨型指標
- C - 指標陣列的初始化
- C - 指標與多維陣列
- C語言中的字串
- C - 字串
- C - 字串陣列
- C - 特殊字元
- C語言中的結構體和聯合體
- C - 結構體
- C - 結構體和函式
- C - 結構體陣列
- C - 自引用結構體
- C - 查詢表
- C - 點(.)運算子
- C - 列舉(或enum)
- C - 結構體填充和打包
- C - 巢狀結構體
- C - 匿名結構體和聯合體
- C - 聯合體
- C - 位域
- C - Typedef
- C語言中的檔案處理
- C - 輸入和輸出
- C - 檔案I/O(檔案處理)
- C預處理器
- C - 預處理器
- C - 編譯指示
- C - 預處理器運算子
- C - 宏
- C - 標頭檔案
- C語言中的記憶體管理
- C - 記憶體管理
- C - 記憶體地址
- C - 儲存類
- 其他主題
- C - 錯誤處理
- C - 可變引數
- C - 命令執行
- C - 數學函式
- C - static關鍵字
- C - 隨機數生成
- C - 命令列引數
- C程式設計資源
- C - 問題與解答
- C - 快速指南
- C - 速查表
- C - 有用資源
- C - 討論
C語言中的指標
什麼是C語言中的指標?
C指標是一種派生資料型別,用於儲存另一個變數的地址,也可以用於訪問和操作儲存在該位置的變數資料。指標被認為是派生資料型別。
使用指標,您可以訪問和修改記憶體中位於的位置的資料,在函式之間有效地傳遞資料,並建立動態資料結構,如連結列表、樹和圖。
指標宣告
要宣告一個指標,請使用**間接訪問運算子(*)**後跟資料型別。
語法
指標變數宣告的一般形式為:
type *var-name;
這裡,type是指標的基本型別;它必須是有效的C資料型別,而var-name是指標變數的名稱。用於宣告指標的星號*與用於乘法的星號相同。但是,在此語句中,星號用於將變數指定為指標。
有效指標變數宣告示例
看看一些有效的指標宣告:
int *ip; /* pointer to an integer */ double *dp; /* pointer to a double */ float *fp; /* pointer to a float */ char *ch /* pointer to a character */
所有指標的值的實際資料型別,無論是整數、浮點數、字元還是其他型別,都是相同的,一個表示記憶體地址的長十六進位制數。不同資料型別指標之間的唯一區別是指標指向的變數或常量的資料型別。
指標初始化
宣告指標變數後,需要使用**取地址(&)運算子**將其初始化為另一個變數的地址。此過程稱為**引用指標**。
語法
以下是初始化指標變數的語法:
pointer_variable = &variable;
示例
這是一個指標初始化的示例:
int x = 10; int *ptr = &x;
這裡,x是一個整數變數,ptr是一個整數指標。指標ptr被初始化為x。
引用和解引用指標
指標引用記憶體中的一個位置。獲取儲存在該位置的值稱為**解引用指標**。
在C語言中,瞭解以下兩個運算子在指標機制中的作用非常重要:
- &運算子 - 它也被稱為“取地址運算子”。它用於引用,這意味著獲取現有變數的地址(使用&)以設定指標變數。
- *運算子 - 它也被稱為“解引用運算子”。使用*運算子執行**解引用**指標以獲取指標指向的記憶體地址中的值。
指標用於按引用傳遞引數。如果程式設計師希望函式對引數的修改對函式的呼叫者可見,這將很有用。這對於從函式返回多個值也很有用。
使用指標訪問和操作值
可以透過使用指標變數來訪問和操作指標指向的變數的值。您需要在指標變數前使用星號(*)來訪問和操作變數的值。
示例
在下面的示例中,我們獲取一個整數變數及其初始值,並將其更改為新值。
#include <stdio.h> int main() { int x = 10; // Pointer declaration and initialization int * ptr = & x; // Printing the current value printf("Value of x = %d\n", * ptr); // Changing the value * ptr = 20; // Printing the updated value printf("Value of x = %d\n", * ptr); return 0; }
輸出
Value of x = 10 Value of x = 20
如何使用指標?
要在C語言中使用指標,您需要宣告一個指標變數,然後將其初始化為另一個變數的地址,然後您可以透過解引用來使用它以獲取和更改指標指向的變數的值。
您可以將指標與任何型別的變數一起使用,例如整數、浮點數、字串等。您還可以將指標與派生資料型別一起使用,例如陣列、結構體、聯合體等。
示例
在下面的示例中,我們使用指標來獲取不同型別變數的值。
#include <stdio.h> int main() { int x = 10; float y = 1.3f; char z = 'p'; // Pointer declaration and initialization int * ptr_x = & x; float * ptr_y = & y; char * ptr_z = & z; // Printing the values printf("Value of x = %d\n", * ptr_x); printf("Value of y = %f\n", * ptr_y); printf("Value of z = %c\n", * ptr_z); return 0; }
輸出
Value of x = 10 Value of y = 1.300000 Value of z = p
指標變數的大小
指標變數佔用的記憶體(或大小)不取決於它指向的變數的型別。指標的大小取決於系統架構。
示例
在下面的示例中,我們列印不同型別指標的大小
#include <stdio.h> int main() { int x = 10; float y = 1.3f; char z = 'p'; // Pointer declaration and initialization int * ptr_x = & x; float * ptr_y = & y; char * ptr_z = & z; // Printing the size of pointer variables printf("Size of integer pointer : %lu\n", sizeof(ptr_x)); printf("Size of float pointer : %lu\n", sizeof(ptr_y)); printf("Size of char pointer : %lu\n", sizeof(ptr_z)); return 0; }
輸出
Size of integer pointer : 8 Size of float pointer : 8 Size of char pointer : 8
C指標示例
練習以下示例以學習指標的概念:
示例1:在C語言中使用指標
以下示例演示瞭如何在C語言中使用&和*運算子執行與指標相關的操作:
#include <stdio.h> int main(){ int var = 20; /* actual variable declaration */ int *ip; /* pointer variable declaration */ ip = &var; /* store address of var in pointer variable*/ printf("Address of var variable: %p\n", &var); /* address stored in pointer variable */ printf("Address stored in ip variable: %p\n", ip); /* access the value using the pointer */ printf("Value of *ip variable: %d\n", *ip ); return 0; }
輸出
執行程式碼並檢查其輸出:
Address of var variable: 0x7ffea76fc63c Address stored in ip variable: 0x7ffea76fc63c Value of *ip variable: 20
示例:列印整數的值和地址
我們將宣告一個int變數並顯示其值和地址:
#include <stdio.h> int main(){ int var = 100; printf("Variable: %d \t Address: %p", var, &var); return 0; }
輸出
執行程式碼並檢查其輸出:
Variable: 100 Address: 0x7ffc62a7b844
示例:整數指標
在此示例中,var的地址使用&運算子儲存在intptr變數中
#include <stdio.h> int main(){ int var = 100; int *intptr = &var; printf("Variable: %d \nAddress of Variable: %p \n\n", var, &var); printf("intptr: %p \nAddress of intptr: %p \n\n", intptr, &intptr); return 0; }
輸出
執行程式碼並檢查其輸出:
Variable: 100 Address of Variable: 0x7ffdcc25860c intptr: 0x7ffdcc25860c Address of intptr: 0x7ffdcc258610
示例5
現在讓我們以一個浮點變數為例,並找到它的地址:
#include <stdio.h> int main(){ float var1 = 10.55; printf("var1: %f \n", var1); printf("Address of var1: %d", &var1); }
輸出
執行程式碼並檢查其輸出:
var1: 10.550000 Address of var1: 1512452612
我們可以看到此變數(任何型別的變數)的地址都是一個整數。因此,如果我們嘗試將其儲存在“float”型別的指標變數中,請檢視會發生什麼:
float var1 = 10.55; int *intptr = &var1;
編譯器不接受此操作,並報告以下錯誤:
initialization of 'int *' from incompatible pointer type 'float *' [-Wincompatible-pointer-types]
注意:變數的型別及其指標的型別必須相同。
在C語言中,變數具有特定資料型別,這些資料型別定義了它們的大小以及它們如何儲存值。使用匹配型別(例如,float *)宣告指標可在指標與其指向的資料之間強制執行“型別相容性”。
C語言中不同資料型別佔用不同的記憶體空間。例如,一個“int”型別變數通常佔用4個位元組,而“float”型別變數可能佔用4或8個位元組,具體取決於系統。從指標新增或減去整數會根據它們指向的資料的大小在記憶體中移動指標。
示例:浮點數指標
在這個例子中,我們聲明瞭一個名為“floatptr”的“float *”型別的變數。
#include <stdio.h> int main(){ float var1 = 10.55; float *floatptr = &var1; printf("var1: %f \nAddress of var1: %p \n\n",var1, &var1); printf("floatptr: %p \nAddress of floatptr: %p \n\n", floatptr, &floatptr); printf("var1: %f \nValue at floatptr: %f", var1, *floatptr); return 0; }
輸出
var1: 10.550000 Address of var1: 0x7ffc6daeb46c floatptr: 0x7ffc6daeb46c Address of floatptr: 0x7ffc6daeb470
指向指標的指標
我們可以有一個指標變數,它儲存另一個指標本身的地址。

在上圖中,“a”是一個普通的“int”型別變數,其指標為“x”。反過來,變數“y”儲存“x”的地址。
請注意,“y”被宣告為“int **”,表示它是一個指向另一個指標變數的指標。顯然,“y”將返回“x”的地址,而“*y”是“x”中的值(即“a”的地址)。
要從“y”獲取“a”的值,我們需要使用表示式“**y”。通常,“y”被稱為**指向指標的指標**。
示例
請看下面的例子:
#include <stdio.h> int main(){ int var = 10; int *intptr = &var; int **ptrptr = &intptr; printf("var: %d \nAddress of var: %d \n\n",var, &var); printf("inttptr: %d \nAddress of inttptr: %d \n\n", intptr, &intptr); printf("var: %d \nValue at intptr: %d \n\n", var, *intptr); printf("ptrptr: %d \nAddress of ptrtptr: %d \n\n", ptrptr, &ptrptr); printf("intptr: %d \nValue at ptrptr: %d \n\n", intptr, *ptrptr); printf("var: %d \n*intptr: %d \n**ptrptr: %d", var, *intptr, **ptrptr); return 0; }
輸出
執行程式碼並檢查其輸出:
var: 10 Address of var: 951734452 inttptr: 951734452 Address of inttptr: 951734456 var: 10 Value at intptr: 10 ptrptr: 951734456 Address of ptrtptr: 951734464 intptr: 951734452 Value at ptrptr: 951734452 var: 10 *intptr: 10 **ptrptr: 10
您也可以擁有**指向陣列的指標**,以及使用**struct**定義的派生型別。指標具有重要的應用。它們在透過傳遞引用呼叫函式時使用。指標還有助於克服函式只能返回單個值的限制。使用指標,您可以獲得返回多個值或陣列的效果。
空指標
如果您沒有確切的地址要分配,那麼始終建議將空值分配給指標變數。這在變數宣告時完成。分配了NULL的指標稱為**空**指標。
NULL指標是一個常量,其值為“0”,在多個標準庫中定義。
示例
考慮以下程式:
#include <stdio.h> int main(){ int *ptr = NULL; printf("The value of ptr is : %x\n", ptr); return 0; }
輸出
當以上程式碼編譯並執行時,會產生以下結果:
The value of ptr is 0
在大多數作業系統中,程式不允許訪問地址“0”處的記憶體,因為該記憶體由作業系統保留。
記憶體地址“0”具有特殊的意義;它表示指標不打算指向可訪問的記憶體位置。但按照慣例,如果指標包含空(零)值,則假定它不指向任何內容。
要檢查空指標,您可以使用如下所示的**if**語句:
if(ptr) /* succeeds if p is not null */ if(!ptr) /* succeeds if p is null */
變數的地址
如您所知,每個變數都是一個記憶體位置,每個記憶體位置都有其定義的地址,可以使用地址運算子(&)訪問,該運算子表示記憶體中的地址。
示例
考慮以下示例,它列印定義的變數的地址:
#include <stdio.h> int main(){ int var1; char var2[10]; printf("Address of var1 variable: %x\n", &var1); printf("Address of var2 variable: %x\n", &var2); return 0; }
輸出
當以上程式碼編譯並執行時,它將列印變數的地址:
Address of var1 variable: 61e11508 Address of var2 variable: 61e1150e
指標詳解
指標有很多但簡單的概念,它們對C程式設計非常重要。以下重要的指標概念應該對任何C程式設計師都清晰:
序號 | 概念及描述 |
---|---|
1 | 指標運算
指標可以使用四種算術運算子:++、--、+、- |
2 | 指標陣列
您可以定義陣列來儲存多個指標。 |
3 | 指向指標的指標
C允許您在指標上擁有指標,依此類推。 |
4 | 在C語言中將指標傳遞給函式
透過引用或透過地址傳遞引數使被呼叫函式能夠在呼叫函式中更改傳遞的引數。 |
5 | 在C語言中從函式返回指標
C允許函式返回指向區域性變數、靜態變數和動態分配記憶體的指標。 |