C/指標
指標的定義
[編輯]- 指標為一種變數,儲存的內容是記憶體地址。
- 指標的使用會因為目的型態不同而有些微的影響。
理解指標
[編輯]指標是C語言中一個較難理解的概念,因為這個概念很接近底層。要想理解它,要從電腦; 计算机=>zh-mo:電腦底層開始。
電腦; 计算机=>zh-mo:電腦底層的儲存
[編輯]在電腦; 计算机=>zh-mo:電腦內部有很多的儲存單元,每個儲存單元都可以存放數據。這些儲存單元就像一個個小盒子,每個盒子裏只能存放一個數字。
於是你看着眼前堆放的一大堆盒子,如何找到某個特定的盒子裏存放的數據呢?
我們可以把盒子整齊排成一排,按順序編號。這樣,我們只需要報出編號,就能順利找到一個盒子。
你可以想像,在電腦; 计算机=>zh-mo:電腦的虛擬世界中,有一個很高的柱子,這個柱子有很多層,每層都是一個格子,每個格子存放一個數字。這些格子按順序編號,每個格子都有唯一的編號,用這個編號就能找到對應的格子。
無論採用哪種比喻,本質上都是相同的。記憶體; 内存=>zh-mo:記憶體中有很多儲存單元,按順序編號,用編號定位。這個「編號」就是「記憶體; 内存=>zh-mo:記憶體地址」。這就是電腦; 计算机=>zh-mo:電腦內部的記憶體; 内存=>zh-mo:記憶體組織形式。
指標
[編輯]所謂指標,無非是一類別變數,這類別變數儲存的值是儲存單元的地址,而不是通常的需要加工處理的數據(不過少數情況下也可能對指標進行運算)。你可以理解成:「指標」就是「指」向一個儲存單元的「標」。
指標的類型
[編輯]指標的類型,其實就是指標指向的儲存單元中的數據的類型。任何類型的數據,在電腦; 计算机=>zh-mo:電腦內部都不過是二進制形式的數字。儲存單元可沒有區分數據類型的能力。所以,為了方便使用、避免出錯,C語言的設計者讓指標擁有了類型,這樣就可以用指標的類型來區分目標儲存單元中的數據的類型。
不同類型的指標在使用時是有區別的。
現實中的電腦; 计算机=>zh-mo:電腦幾乎全部是按位元組編址的,也就是每個小盒子裏都只能裝一位元組(8 個位元; 二进制位=>zh-mo:位元)的數據。而在 C/基本數據類型 中講到,不同類型的數據會佔用不同位元組數的空間,如 int 佔用 4 位元組、long long 佔用 8 位元組。
當我們使用指標時,即操作指標指向的儲存單元的值時,實際上會連同這個目標儲存單元後面的幾個單元一起操作,具體的單元數量取決於指標的類型。比如,操作 int 型的指標指向的儲存單元,就會從目標地址開始,一同操作四個單元的數據;操作 long long 型的指標指向的儲存單元,就會一口氣操作 8 個單元的數據。
你可以理解成,我們認為這幾個連續的儲存單元中存放了某種類型的數據,於是我們定義了一個指標為這種類型,並讓它指向這段儲存單元的開頭。這樣,我們只需要操作這個指標,就可以很方便的操作這幾個連續儲存單元中存放的整個數據。
講完了理論,接下來該看看實踐了。
變數指標
[編輯]- 指標的宣告:
int *ptr; /* 則 (int *) 為變數型態,ptr 為變數名稱 */
- 取得記憶體地址:在變數前面使用 '&' 字元。
- 指向記憶體地址:在變數前面使用 '*' 字元。
#include <stdio.h>
int main()
{
int v = 5;
int *ptr = &v;
printf("%d\n", *ptr);
}
函數指標
[編輯]函數其實也可以是指標。
#include <stdio.h>
typedef void (*MyDelegate)(int i );
MyDelegate test1( int i )
{
printf("%d\n", i );
}
MyDelegate test2( int i )
{
printf("%d\n", i+1 );
}
int main(int argc, char* argv[])
{
MyDelegate function;
function = (MyDelegate)test1;
function( 21 ); /* 等同於呼叫 test1 */
function = (MyDelegate)test2;
function( 21 ); /* 等同於呼叫 test2 */
}