C語言指標

2021-10-02 12:28:01 字數 4609 閱讀 1166

指標,就是記憶體的位址;指標變數,就是儲存了記憶體位址的變數

記憶體中位元組的編號稱為位址(address)或指標(pointer)。位址從 0 開始依次增加,對於 32 位環境,程式能夠使用的記憶體為 4gb,最小的位址為 0,最大的位址為 0xffffffff。

定義指標變數與定義普通變數非常類似,不過要在變數名前面加星號*,格式為:

datatype *name;
或者

datatype *name = value;
*pointer;
這裡的*稱為指標運算子,用來取得某個位址上的資料,

指標變數加減運算的結果跟資料型別的長度有關。

陣列(array)是一系列具有相同型別的資料的集合,每乙份資料叫做乙個陣列元素(element)。陣列中的所有元素在記憶體中是連續排列的,整個陣列占用的是一塊記憶體。

定義陣列時,要給出陣列名和陣列長度,陣列名可以認為是乙個指標,它指向陣列的第 0 個元素。在c語言中,我們將第 0 個元素的位址稱為陣列的首位址。

陣列名的本意是表示整個陣列,也就是表示多份資料的集合,但在使用過程中經常會轉換為指向陣列第 0 個元素的指標,所以上面使用了「認為」一詞,表示陣列名和陣列首位址並不總是等價。
如果乙個指標指向了陣列,我們就稱它為陣列指標(array pointer)。

陣列指標指向的是陣列中的乙個具體元素,而不是整個陣列,所以陣列指標的型別和陣列元素的型別有關

c語言中沒有特定的字串型別,我們通常是將字串放在乙個字元陣列中

c語言還支援另外一種表示字串的方法,就是直接使用乙個指標指向字串,例如:

char

*str =

"";//或者:

char

*str;

str =

"";

這與直接定義字元陣列的區別在於,字元陣列儲存在全域性資料區或棧區,第二種形式的字串儲存在常量區。全域性資料區和棧區的字串(也包括其他資料)有讀取和寫入的許可權,而常量區的字串(也包括其他資料)只有讀取許可權,沒有寫入許可權。

總結:c語言有兩種表示字串的方法,一種是字元陣列,另一種是字串常量,它們在記憶體中的儲存位置不同,使得字元陣列可以讀取和修改,而字串常量只能讀取不能修改。

在c語言中,函式的引數不僅可以是整數、小數、字元等具體的資料,還可以是指向它們的指標。用指標變數作函式引數可以將函式外部的位址傳遞到函式內部,使得在函式內部可以操作函式外部的資料。

陣列是一系列資料的集合,無法通過引數將它們一次性傳遞到函式內部,如果希望在函式內部運算元組,必須傳遞陣列指標。

c語言允許函式的返回值是乙個指標(位址),我們將這樣的函式稱為指標函式。

如果乙個指標指向的是另外乙個指標,我們就稱它為二級指標,或者指向指標的指標。

定義多級指標時,有幾級指標就加幾個*。取指標最終所指向的資料時,是幾級指標就加幾個*

null 是「零值、等於零」的意思,在c語言中表示空指標。從表面上理解,空指標是不指向任何資料的指標,是無效指標,程式使用它不會產生效果。

其實,null 是在stdio.h中定義的乙個巨集,它的具體內容為:

#define null ((void *)0)
在程序的虛擬位址空間中,最低位址處有一段記憶體區域被稱為保留區,這個區域不儲存有效資料,也不能被使用者程式訪問,將 null 指向這塊區域很容易檢測到違規指標。

在大多數作業系統中,極小的位址通常不儲存資料,也不允許程式訪問,null 可以指向這段位址區間中的任何乙個位址。

對於上面提到的((void *)0):

void 用在函式定義中可以表示函式沒有返回值或者沒有形式引數,用在這裡表示指標指向的資料的型別是未知的。

*也就是說,void 表示乙個有效指標,它確實指向實實在在的資料,只是資料的型別尚未確定,在後續使用過程中一般要進行強制型別轉換。

c語言動態記憶體分配函式 malloc() 的返回值就是void *型別,在使用時要進行強制型別轉換。

如果乙個陣列中的所有元素儲存的都是指標,那麼我們就稱它為指標陣列。指標陣列的定義形式一般為:

datatype *arrayname[length]

;

[ ]的優先順序高於*,該定義形式應該理解為:

datatype *

(arrayname[length]

);

括號裡面說明arrayname是乙個陣列,包含了length個元素,括號外面說明每個元素的型別為datatype *。

二維陣列在概念上是二維的,有行和列,但在記憶體中所有的陣列元素都是連續排列的,它們之間沒有「縫隙」。

以下面的二維陣列 a 為例:

int a[3]

[4]=

,,};

但在記憶體中,a 的分布是一維線性的,整個陣列占用一塊連續的記憶體:12

3456

78910

11c語言中的二維陣列是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最後存放 a[2] 行;每行中的 4 個元素也是依次存放。

定義乙個指向 a 的指標變數 p:

int (*p)[4] = a;

括號中的*表明 p 是乙個指標,它指向乙個陣列,陣列的型別為int [4],這正是 a 所包含的每個一維陣列的型別。

對指標進行加法(減法)運算時,它前進(後退)的步長與它指向的資料型別有關,p 指向的資料型別是int [4],那麼p+1就前進 4×4 = 16 個位元組,p-1就後退 16 個位元組,這正好是陣列 a 所包含的每個一維陣列的長度。也就是說,p+1會使得指標指向二維陣列的下一行,p-1會使得指標指向陣列的上一行。

陣列名 a 在表示式中也會被轉換為和 p 等價的指標!

使用指標 p 來訪問二維陣列中的每個元素

p指向陣列 a 的開頭,也即第 0 行;p+1前進一行,指向第 1 行。

*(p+1)+1表示第 1 行第 1 個元素的位址

*(p+1)單獨使用時表示的是第 1 行資料,放在表示式中會被轉換為第 1 行資料的首位址,也就是第 1 行第 0 個元素的位址,因為使用整行資料沒有實際的含義,編譯器遇到這種情況都會轉換為指向該行第 0 個元素的指標;就像一維陣列的名字,在定義時或者和 sizeof、& 一起使用時才表示整個陣列,出現在表示式中就會被轉換為指向陣列第 0 個元素的指標。

((p+1)+1)表示第 1 行第 1 個元素的值。

乙個函式總是占用一段連續的記憶體區域,函式名在表示式中有時也會被轉換為該函式所在記憶體區域的首位址,這和陣列名非常類似。我們可以把函式的這個首位址(或稱入口位址)賦予乙個指標變數,使指標變數指向函式所在的記憶體區域,然後通過指標變數就可以找到並呼叫該函式。這種指標就是函式指標。

函式指標的定義形式為:

returntype (

*pointername)

(param list)

;

returntype 為函式返回值型別,pointernmae 為指標名稱,param list 為函式引數列表。引數列表中可以同時給出引數的型別和名稱,也可以只給出引數的型別,省略引數的名稱,這一點和函式原型非常類似。

有幾種運算子的優先順序非常容易混淆,它們的優先順序從高到低依次是:

-定義中被括號( )括起來的那部分。

-字尾操作符:括號( )表示這是乙個函式,方括號[ ]表示這是乙個陣列。

-字首操作符:星號*表示「指向***的指標」。

常見指標變數的定義

定 義 含 義

int

*p;// p 可以指向 int 型別的資料,也可以指向類似 int arr[n] 的陣列。

int*

*p;//p 為二級指標,指向 int * 型別的資料。

int*p[n]

;//p 為指標陣列。[ ] 的優先順序高於 *,所以應該理解為 int *(p[n]);

int(

*p)[n]

;//p 為二維陣列指標。

int*p(

);//p 是乙個函式,它的返回值型別為 int *。

int(

*p)();

// p 是乙個函式指標,指向原型為 int func() 的函式。

指標變數可以進行加減運算,例如p++、p+i、p-=i。指標變數的加減運算並不是簡單的加上或減去乙個整數,而是跟指標指向的資料型別有關。

給指標變數賦值時,要將乙份資料的位址賦給它,不能直接賦給乙個整數,例如int *p = 1000;是沒有意義的,使用過程中一般會導致程式崩潰。

使用指標變數之前一定要初始化,否則就不能確定指標指向**,如果它指向的記憶體沒有使用許可權,程式就崩潰了。對於暫時沒有指向的指標,建議賦值null。

兩個指標變數可以相減。如果兩個指標變數指向同乙個陣列中的某個元素,那麼相減的結果就是兩個指標之間相差的元素個數。

陣列也是有型別的,陣列名的本意是表示一組型別相同的資料。在定義陣列時,或者和 sizeof、& 運算子一起使用時陣列名才表示整個陣列,表示式中的陣列名會被轉換為乙個指向陣列的指標。

該文章主要內容摘自c語言中文網教程

C語言指標

指標變數是包含記憶體位址的變數,它指向記憶體中的一塊區域,通過指標的值,可以間接訪問到相應的記憶體單元的資料,並做相應的修改。1 指標的定義和簡單使用 定義乙個指標變數和定義一般的變數類似,只需在變數名前面加乙個 對乙個指標變數賦值可以用取位址符 來獲取到乙個變數的位址,如果要獲得指標指向的記憶體區...

C語言指標

1 定義指標變數void change int n 格式 變數型別 變數名 定義了乙個指標變數p 指標變數只能儲存位址 指標變數p前面的int 指標變數p只能指向int型別的資料 int main void change int n 2 指標與陣列 陣列名其實質是乙個指標,但是它和普通的指標變數還是...

c語言指標

編寫程式,在主函式裡用指標陣列輸入六個字串,再用另乙個函式對這六個字串排序,並在主函式中輸出排好序的字串。include void sort char s,int n char temp for int i 0 ifor int j 0 jif strcmp s j s j 1 0 temp s j...