C語言指標詳解(高階)

2021-10-08 12:13:56 字數 2775 閱讀 6547

(以下為本人的一些學習心得,有錯誤希望大家能指出來)

首先我們介紹一下幾種其他型別的指標用法:

我們都知道怎麼在c語言裡宣告乙個常量,就是用關鍵字const來指定就好,這樣這個常量的值就不能被語句改動了,一旦被改動,那就會報錯。

1. 指向常量的指標

long number =

9999l;

const

long

*pnumber =

&number;

那如果我們也希望有乙個指標pnumber能訪問number,但是不希望它能改number的值,也就是說number的值可以自己變,pnumber的值也可以自己變,但是不能通過pnumber修改number的值。我們可以採用指向常量的指標,就是讓這個指標以為自己指向的是乙個常量,這樣可以實現(有沒有很熟悉這個模式?你可以讀我但是你沒資格改我)。

2. 常量指標

long number =

9999l;

long

*const pnumber =

&number;

如果我們希望這個指標只能指向number,不能再改了,可以使用常量指標,即只要交換const和long * 的位置。當然了,這樣就可以通過pnumber修改number的值了,即這裡的const指定的是指標的值無法修改。

我們可以結合上面兩個,擁有乙個無法改變自己指向也無法修改自己指向的值的指標,那就是:

long number =

9999l;

const

long

*const pnumber =

&number;

當然,如果希望更進一層即number的值也無法改動只要把number用const宣告就好了。

3. 指標和陣列的關係

指標涉及到記憶體的儲存,而眾所周知陣列本質上是一段連續儲存的記憶體。所以我們很自然的想到這兩個肯定有關係。上一節我們說到對指標的值+1就是加乙個指標型別的位元組,所以對於陣列這種連續記憶體,我們會想到用指標來訪問陣列的元素。

1)一維陣列

char array[10]

;scanf

("%s"

, array)

;

之前我們說過對於函式scanf(),有兩個引數,第二個引數就是要在記憶體中存放的位址,那麼對於字串的輸入,我們只需要寫上要存放的陣列的名字,那麼就代表該陣列的首位址而無需加上取址運算子&。而當訪問某個元素時,array和array + i都代表乙個位址,類似於乙個指標,那麼* array就是陣列的第乙個元素的值,* (array + i)表示第i個元素的值。

但是需要注意,陣列和指標是有區別的,陣列名稱是乙個固定的位址,而不是乙個指標,可以在表示式右邊使用陣列名及其使用的位址,但是不能修改它。

2)多維陣列

前面討論的是一維陣列和指標的關係,二維或多維陣列在某種程度上是相同的。然而,指標和陣列名稱之間的差異變得更為明顯。對於二維陣列來說,我們知道在記憶體中依舊是按照一維陣列的形式即連續記憶體存放的,而不是按照我們直覺想的那樣的矩形。只不過這個一維陣列的每乙個元素都是乙個陣列。

對於二維陣列來說,如果我們要使用指標引用第乙個元素,需要** array,或者* array[0],又或者直接根據下標array[0][0]。也就是說使用array,就是在使用char** 型別的位址值,取消對array的引用,會得到相同的位址值,但其型別是char*,給它加 i 會得到乙個char* 的位址,而這個位址是記憶體中第 i 個元素,即array[0]陣列中第 i 個元素。取消對它的引用,會得到該位址中儲存的內容。

總結一下就是我們要理解

*

*array + i //陣列的元素值 + i*(

*array + i)

//陣列第一維第i個元素的值**

(array + i)

//陣列第i維第乙個元素的值*(

*(array + i)

+ j)

//陣列第i維第j個元素的值

以上幾種取消引用board方式的意義

hint:int board[5][5];

* (* board + 1)和* ((*board) + 1)有區別嗎?

答:無區別,*的優先順序比+高。

以上為用陣列名稱引用二維陣列,我們也可以宣告乙個二維陣列的指標來引用二維陣列中的每乙個元素。

char array[10]

[10];

char

*parray =

*array;

for(

int i =

0; i <10*

10; i ++

)printf

("%c ",*

(parray + i)

);

顯然,在上面這個例子中我們就是把二維陣列當成一維陣列在處理,直接在指標上處理可以只用乙個一層迴圈來遍歷整個陣列。

這裡需要注意的是給指標初始化時我們取消了對array的引用(* array),因為array屬於char **型別的指標,而我們宣告的是char *型別的指標,所以型別不同需要對其進行一次取消引用,也可以使用:char *parray = &array[0][0]; 效果相同,但是如果使用char *parray = array就會導致報錯或警告,因為它們有著不同的間接級別:parray指標引用的位址包含乙個char型別的值,而array引用乙個位址,那個位址引用另乙個含有char型別值的位址(array[0])。

所以現在大家應該懂了int *和int **的區別了吧

C語言 高階指標

import import myfunction.h 巨集後面不要加分號 define kimagewidth 200 define kimageheight 200 有引數的巨集 define kmax a,b a b a b 加上括號 define kmul a,b a b define and...

c語言指標詳解

一.指標的概念 指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。要搞清乙個指標需要搞清指標的四方面的內容 指標的型別,指標所指向的型別,指標的值或者叫指標所指向的記憶體區,還有指標本身所佔據的記憶體區。1.指標的型別 從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部...

C語言指標詳解

類似於 int p char p 或者自定義型別的 person p struct p 這些都是基本的指標變數,不管什麼型別的指標變數都是乙個存位址的變數,所以它們的大小都是四個位元組 還有一種void p 型別,類似於 js 或者 c 的 var 可以傳入任何型別變數的位址,也可以轉換成任何型別變...