C 指標理解

2022-01-31 04:48:02 字數 4173 閱讀 4682

1.指標的概念

本質上講指標也是一種變數,普通的變數包含的是實際的資料,而指標變數包含的是記憶體中的一塊位址,這塊位址指向某個變數或者函式,指標就是位址。指標是乙個指示器,它告訴程式在記憶體的哪塊區域可以找到資料。

2.指標的內容

指標的內容包含4部分:指標的型別,指標所指向的型別,指標的值,指標本身所占有的記憶體區。在初學指標時,指標的型別和指標所指向的型別是極容易搞混淆的,弄清楚這些概念,有助於我們正確的使用指標。

3.指標的型別和指標所指向的型別

從語法上講,指標的型別是指把指標宣告語句中的指標名字去掉所剩下的部分。 

指標指向的是一塊記憶體區域,指標所指向的型別取決於這塊內存在編譯時是什麼型別,比如乙個int*型別指標所指向的型別是int。 

下面我來就一些例子來對這兩個概念進行說明。

intp;//這僅僅是乙個普通的變數

int* p;//int*也表示一種資料型別:int指標型別。所以p的型別為:int*型別,p所指向的型別為int型

到這裡,稍微暫停一下。教大家一種如何看待指標型別和指標所指向的型別的方法。(我自己的理解) 

就上面這個int*p例子來說,它可以寫成int* p,也可以寫成int *p。第一種的理解偏向於位址,就是p是乙個位址變數,p表示乙個十六進製制位址;第二種的寫法偏向於值,*p是乙個整型變數,它能夠表示乙個整型值。 

這兩種寫法都正確,只是理解上不同,但是我認為,在理解指標型別和指標所指向的型別這兩個概念時,完全可以把它們兩個結合起來。 

想想我們使用指標的步驟:宣告指標,為指標賦值,然後使用指標所指向的值。 

我們都知道指標是一種復合資料型別,它必須和基本的型別結合才能構成指標型別。 

那麼int*就是一種復合的資料型別——整型指標型別。 

這樣就好解釋第一種寫法了,在宣告時,int* p,直接宣告p變數為整型指標型別,這是第一步。 

第二步就是為指標賦值了,p是指標型別,它存放的是位址,這裡假設我這樣為它賦值:p = &普通變數;(比如int a = 5;p=&a;)。 

第三步使用指標,在c++ primer中詳細的解釋了*是解除引用的運算子(我的理解是位址解析運算子),如果p是位址,那麼*p就是實際的值(比如上面對應的*p = 5)。對於初學者來說,在理解它的含義時,完全可以跨過這一步,上面說了在宣告指標時int* p和int *p這兩種寫法都可以,在宣告時我偏向第一種理解,在使用時我偏向第二種理解:畢竟我們使用的是值,而*p就是這個值。 

我的結論:對於int* p和int *p的理解(也是對於指標型別和指標所指向的型別的理解),乙個指標包含兩部分,位址和值,指標宣告時宣告的是乙個位址變數(指標就是位址),在使用時使用的是指標所指向的值。或者說指標包含兩個型別:指標型別和指標所指向的型別,宣告時是宣告指標型別,使用時是使用指標所指向的型別。

intp[3];//p先和結合,說明p是乙個陣列,再和int結合,所以p是乙個int型陣列

int* p[3];//優先順序比*高,p是陣列,再加上int*,可以稱它為指標陣列,陣列的每乙個元素的值都為指標(位址)

int (*p)[3];//*p可以看作是普通變數,就回到第三種情況(int p[3]),但是這裡p是指標變數,它指向的是乙個包含3個整型數值的陣列。可以稱它為陣列指標,陣列中每乙個元素的值為普通整型值。

int** p;//int*代表指標型別,*是指標型別,所以p是指向int型指標的指標,p指向的型別是int*型別(int型指標)

intp(int);//這很明顯是乙個返回型別為int,並且帶乙個int型引數的函式

int (*p)(int);//p是函式指標,指向的是返回值為int並且帶乙個int引數的函式。這個宣告包含兩部分:函式變數+函式位址變數(姑且把函式也看做是變數)

int* (*p(int))[3];//這個有點複雜,它仍然是乙個函式指標。從*p(int)看,它是函式指標,帶乙個int引數;然後看,說明函式返回值為陣列,然後返回型別為int*。所以p是乙個指向返回值為int*型指標陣列,並且帶乙個int型引數的函式的指標

在平常使用中,我們只需要理解前面幾個就可以了,太複雜的指標基本用不到,可讀性也不好。

下面是一些指標的簡單例子。

demo1 &和*操作符

#include

intmain()

demo2

#include

intmain()

demo3  new和delete操作符

#include

intmain()

demo4 動態陣列

#include

intmain()

demo 5 陣列和指標

#include

intmain()

;short

stacks[3] = ;

//兩種方式去獲取陣列的位址——陣列名或對陣列首元素進行求址運算

double* pw = wages;

short* ps = &stacks[0];

cout

<<"pw = "

<<<",*pw = "

<<*pw

cout

<<"add 1 to the pw pointer:\n";

cout

<<"pw = "

<<<",*pw = "

<<*pw

<<"\n\n";

cout

<<"ps = "

<<<",*ps = "

<<*ps

cout

<<"add 1 to the ps pointer:\n";

cout

<<"pw = "

<<<",*ps = "

<<*ps

<<"\n\n";    

//stacks[1] 等同於 *(stacks + 1)

cout

<<"access two elements with array notation\n";

cout

<<" stacks[0] = "

<

<<"access two elements with pointer notation\n";

cout

<<"*stacks = "

<<*stacks

<<",*(stacks + 1) = "

<<*(stacks + 1)

}demo6 字串和位址

#include

intmain()

demo7 字串和位址

#include

#include

intmain()

demo8 動態結構 ->指向操作符

#include

struct

inflatable

;int

main()

4.指標的值(或稱指標所指向的記憶體區)指標的值或者叫指標所指向的記憶體區或位址,是指標本身儲存的數值,這個值將被編譯器當作乙個位址,而不是乙個一般的數值。在32位程式裡,所有型別的指標的值都是乙個32位整數,因為32位程式裡記憶體位址全都是32位長。 指標所指向的記憶體區就是從指標的值所代表的那個記憶體位址開始,長度為sizeof(指標所指向的型別)的一片記憶體區。以後,我們說乙個指標的值是xx,就相當於說該指標指向了以xx為首位址的一片記憶體區域;我們說乙個指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首位址。

指標所指向的記憶體區和指標所指向的型別是兩個完全不同的概念。在上例中,指標所指向的型別已經有了,但由於指標還未初始化,所以它所指向的記憶體區是不存在的,或者說是無意義的。

以後,每遇到乙個指標,都應該問問:這個指標的型別是什麼?指標指的型別是什麼?該指標指向了**?

5.指標本身所占有的記憶體區指標本身所占有的記憶體區是指標本身佔記憶體的大小,這個你只要用函式sizeof(指標的型別)測一下就知道了。在32位平台裡,指標本身佔據了4個位元組的長度。

指標本身佔據的記憶體這個概念在判斷乙個指標表示式是否是左值時很有用。

C 指標理解

一 指標的概念 本質上講指標也是一種變數,普通的變數包含的是實際的資料,而指標變數包含的是記憶體中的一塊位址,這塊位址指向某個變數或者函式,指標就是位址。指標是乙個指示器,它告訴程式在記憶體的哪塊區域可以找到資料。二 指標的內容 指標的內容包含4部分 指標的型別,指標所指向的型別,指標的值,指標本身...

C 指標理解

指標是c c 程式設計中的重要概念之一,也是最容易產生困惑並導致程式出錯的問題之一。利用指標程式設計可以表示各種資料結構,通過指標可使用主調函式和被調函式之間共享變數或資料結構,便於實現雙向資料通訊 指標能夠靈活的操作記憶體,合理的操作記憶體能夠使程式更高效。1.指標的概念 本質上講指標也是一種變數...

c 指標理解

const修飾指標有三種情況 const修飾指標 常量指標 const修飾常量 指標常量 const即修飾指標,又修飾常量 示例 int main 指標的理解 int a 10 p 表示位址 即 p a p 表示位址指向的內容 即 p 10 補充 const int p a 表示常量指標 int c...