C 基礎(1) 指標

2021-10-16 05:10:44 字數 3861 閱讀 3848

三. 指標使用

四. 函式和指標

五. const 和指標

指標是另外一種型別的復合型別,復合型別是指基於其它型別定義的型別(意思是說指標是指向什麼型別,那麼指標本身就是什麼型別)

指標其實就是程式資料在記憶體中的位址,而指標變數是用來儲存這些位址的變數

記憶體是乙個很大的,線性的位元組陣列。每乙個位元組都是固定的大小,由8個二進位制位組成。最關鍵的是,每乙個位元組都有乙個唯一的編號,編號從0開始,一直到最後乙個位元組,這個編號就是所謂的位址

指標的值(虛擬位址值)使用乙個機器字長來儲存,也就是說,對於乙個機器字長為w位的電腦而言,它的虛擬位址空間是0~[2的w次冪] - 1,程式最多能訪問2的w次冪個位元組。這就是為什麼xp這種32位系統最大支援4gb記憶體的原因了。

機器字長 是指計算機進行一次整數運算所能處理的二進位制資料的位數(整數運算即定點整數運算,常見的有8位、16位、32位、64位等)

1. 變數在記憶體中的儲存

舉個例子: int a = 1;

因為 int 型別在 32 位作業系統中佔 4 個位元組,那麼 記憶體中 位址 0028ff40到0028ff43之間4個位元組 就儲存了變數a ,但是 指標只儲存了首位址值 0028ff40 作為 變數 a 的指標位址,所以佔據記憶體的位址就是位址值最小的那個位元組的位址

2. 指標在記憶體中的儲存

再舉個例子:

int a =1;

// 宣告乙個指標 格式 : 變數型別 * 指標變數名 = &變數名

// &變數名 表示獲取變數在記憶體中的首位址值

// * 表示是乙個指標

int* p =

&a;

p++;

指標也是一種資料型別,在32位程式裡,所有型別的指標的值都是乙個32位整數,因為32位程式裡記憶體位址全都是32位長,所以無論是什麼型別的指標,在32為系統中 指標都是占用4個位元組。在上例中,指標p 的型別是int *,它指向的型別是int,它被初始化為指向整形變數a,接下來的第3句中,指標p 被加了1,編譯器是這樣處理的:它把指標p的值加上了sizeof(int)大小的位元組,在32位程式中,是被加上了4。由於位址是用位元組做單位的,故p所指向的位址由原來的變數a的位址向高位址方向增加了4個位元組。

這個時候可以列印一下 p 指向的的記憶體位址資料

int

main()

第一次列印正確值,因為第一次列印的時候,指標p指向的是變數a的位址值

第二次列印了乙個負數,因為 p++ 操作是改變指向的記憶體位址,而不是把原來的4位元組擴張為8位元組

1. 定義指標物件

定義指標變數時,在變數名前寫乙個 * 星號,這個變數就變成了對應變數型別的指標變數。必要時要加( ) 來避免優先順序的問題:

int

* p_int;

//指向int型別變數的指標

double

* p_double;

//指向double型別變數的指標

person * p_struct;

//類或結構體型別的指標

int*

* p_pointer;

//指向 乙個整形變數指標的指標

int(

*p_arr)[3

];//指向含有3個int元素的陣列的指標

int(

*p_func)

(int

,int);

//指向返回型別為int,有2個int形參的函式的指標

2. 獲取指標指向的資料
int a =1;

int* p =

&a;printf

("%p\n"

,&a)

;// 變數a的所在的記憶體位址

printf

("%p\n"

, p)

;// 指標p的值 就是a的位址

printf

("%d\n"

,*p)

;printf

("%p\n"

,&p)

;//指標p的所在的記憶體位址

3. 指標值的狀態

空指標,意味著指標沒有指向任何物件 例:int * p;

無效指標(野指標) 例:int * p = 0x00001;

4. 指標的算數運算

指標可以加上或減去乙個整數。指標的這種運算的意義和通常的數值的加減運算的意義是不一樣的,指標的運算是有單位的

如上面 2.2 介紹 p++ 的例子:

指標p的型別是int *,它指向的型別是 int,p加1,編譯器在1的後面乘上了單位sizeof(int)

若p+3,則編譯之後的位址應該是 p的位址加 3 * sizeof(int)

指標運算最終會變為記憶體位址的元素,記憶體又是乙個連續空間,所以按理只要沒有超出記憶體限制就可以一直增加。這樣前面所說的指標值的狀態第二條就很好解釋了。

4.1 函式的引數和指標

實參傳遞給形參,是按值傳遞的,也就是說,函式中的形參是實參的拷貝份,形參和實參只是在值上面一樣,而不是同乙個記憶體資料物件。這就意味著:這種資料傳遞是單向的,即從呼叫者傳遞給被調函式,而被調函式無法修改傳遞的引數達到回傳的效果

void

change

(int a)

intmain

(void

)

有時候我們可以使用函式的返回值來回傳資料,在簡單的情況下是可以的,但是如果返回值有其它用途(例如返回函式的執行狀態量),或者要回傳的資料不止乙個,返回值就解決不了了。

傳遞變數的指標可以輕鬆解決上述問題:

void

change

(int

* a)

intmain

(void

)

有時我們會傳遞類或者結構體物件,而類或者結構體占用的記憶體有時會比較大,通過值傳遞的方式會拷貝完整的資料,降低程式的效率。而指標只是固定大小的空間,效率比較高

5.1 指向常量的指標

int a =1;

int b =2;

// 指向常量的指標,它指向的值不能修改,但是執行可以變

const

int* p =

&a;//將const放在型別前面或者後面,二者的意義完全相同

//int const * p;

// *p = b; // 編譯報錯

p =&b;// 通過

b =3;

// 通過

cout <<

*p << endl;

// 輸出:3

5.2 常量指標
int a =1;

int b =2;

int*

const p =

&a;// p = &b; // 編譯報錯

*p =3;

cout <<

*p << endl;

C 面試 (1) 指標

指標是c 中一類頗具特色的資料型別,允許直接操作記憶體位址,實現記憶體的動態分配。指標問題通常包括指標常量,常量指標,陣列指標,指標陣列,函式指標,指標傳值等。指標和引用的區別 非空區別。在任何情況下都不能使用指向空值的引用。因此如果你使用乙個變數並讓它指向乙個物件,但是該變數在某些時候也可能不指向...

C 基礎總結 4 指標

指標是乙個變數,其儲存的值是位址,而不是值本身。有點類似於組成原理裡面的變址定址 在討論指標之前,我們先來看看如何尋找常規變數的位址。只需對變數引用取位址符 就行了。如下面一段 duck變數為int型變數,其分配的位址是1000,裡面儲存的值是12,而birding是乙個int型指標變數它本身的位址...

C語言基礎四 指標

指標表示乙個位址,什麼型別的指標就應該指向什麼型別的記憶體空間,例如int 型別的指標就應該指向乙個int型別的空間。int a 7 int p null 指標的定義 p a 指標的繫結 p 5 指標的解引用對於同型別指標p1,p2,一般有這幾種運算 p1 3,p1 3,p2 p1 int a 5 ...