C語言指標

2021-07-15 03:07:57 字數 3211 閱讀 3556

1.指標的一些基本理解

(1)指標使用三部曲:

①定義指標變數:int *p定義乙個指標變數p

②關聯指標變數:就是指標的繫結,其意義是讓指標指向乙個可以訪問、應該訪問的地方

③解引用:為了間接訪問目標變數

(2)指標使用時:

①星號:星號在用於指標相關功能的時候有2種用法:第一種是指標定義時,結合前面的型別用於表明要定義的指標的型別;第二種功能是指標解引用,解引用時*p表示p指向的變數本身

②取位址符&:取位址符使用時直接加在乙個變數的前面,然後取位址符和變數加起來構成乙個新的符號,這個符號表示這個變數的位址。

③指標定義並初始化、與指標定義然後賦值的區別:

指標定義並初始化:int *p = &a;

指標定義然後賦值:int *p; p = &a;

④左值與右值:放在賦值運算子左邊的就叫左值,右邊的就叫右值。所以賦值操作其實就是:左值 = 右值。當乙個變數做左值時,編譯器認為這個變數符號的真實含義是這個變數所對應的那個記憶體空間;當乙個變數做右值時,編譯器認為這個變數符號的真實含義是這個變數的值,也就是這個變數所對應的記憶體空間中儲存的那個數。

(3)指標的野指標的問題:

①什麼是野指標:野指標,就是指標指向的位置是不可知的,也就是指標變數在定義時如果未初始化,值也是隨機的。

②野指標的危害:野指標很可能觸發執行時段錯誤(sgmentation fault)。

③怎麼避免野指標:在指標的解引用之前,一定確保指標指向乙個絕對可用的空間。

常規方法:

第一點:定義指標時,同時初始化為null

第二點:在指標解引用之前,先去判斷這個指標是不是null

第三點:指標使用完之後,將其賦值為null

第四點:在指標使用之前,將其賦值繫結給乙個可用位址空間

④null的問題:

#ifdef _cplusplus // 定義這個符號就表示當前是c++環境

#define null 0 // 在c++中null就是0

#else

#define null (void )0 // 在c中null是強制型別轉換為void 的0

#endif

null的實質其實就是0,然後我們給指標賦初值為null,其實就是讓指標指向0位址處。為什麼指向0位址處?2個原因。第一層原因是0位址處作為乙個特殊位址(我們認為指標指向這裡就表示指標沒有被初始化,就表示是野指標);第二層原因是這個位址0位址在一般的作業系統中都是不可被訪問的,如果c語言程式設計師不按規矩(不檢查是否等於null就去解引用)寫**直接去解引用就會觸發段錯誤,這種已經是最好的結果了。

(4)onst關鍵字與指標:

const修飾指標有4種形式,區分清楚這4種即可全部理解const和指標。

第一種:const int *p; //p本身不是cosnt的,而p指向的變數是const的

第二種:int const *p; //p本身不是cosnt的,而p指向的變數是const的

第三種:int * const p; // p本身是cosnt的,p指向的變數不是const的

第四種:const int * const p; //p本身是cosnt的,p指向的變數也是const的

2.進一步的指標運用:

(1)以指標方式來訪問陣列元素:

陣列格式訪問陣列元素是:陣列名[下標]; (注意下標從0開始)

指標格式訪問陣列元素是:*(指標+偏移量);

陣列下標方式和指標方式均可以訪問陣列元素,兩者的實質其實是一樣的。在編譯器內部都是用指標方式來訪問陣列元素的,陣列下標方式只是編譯器提供給程式設計者一種殼(語法糖)而已。所以用指標方式來訪問陣列才是本質的做法。

(2)指標參與運算的特點:

指標變數+1,並不是真的加1,而是加1*sizeof(指標型別);如果是int 指標,則+1就實際表示位址+4,如果是char 指標,則+1就表示位址+1;如果是double *指標,則+1就表示位址+8.

(3)指標型別和強制裝換:

乙個指標涉及2個變數:乙個是指標變數自己本身,乙個是指標變數指向的那個變數。int p;定義指標變數時,p(指標變數本身)是int 型別,*p(指標指向的那個變數)是int型別的。

指標資料型別轉換例項分析:int * -> char *:int和char的不同在於char只有1個位元組而int有4個位元組,所以int的範圍比char大。在char所表示的範圍之內int和char是可以互轉的不會出錯;但是超過了char的範圍後char轉成int不會錯,而從int到char轉就會出錯。

(4)sizeof運算子和strlen函式:

主要是因為在不同平台下各種資料型別所佔的記憶體位元組數不盡相同(譬如int在32位系統中為4位元組,在16位系統中為2位元組···)。所以程式中需要使用sizeof來判斷當前變數/資料型別在當前環境下佔幾個位元組。

strlen是乙個c庫函式,用來返回乙個字串的長度(注意,字串的長度是不計算字串末尾的』\0』的)。一定要注意strlen接收的引數必須是乙個字串(字串的特徵是以』\0』結尾)

3.指標與函式之間的關係

(1)指標與函式傳參:

①普通變數作為函式形參:函式傳參時,普通變數作為引數時,形參和實參名字可以相同也可以不同,實際上都是用實參來替代相對應的形參的。——傳值呼叫

②陣列作為函式形參:函式名作為形參傳參時,實際傳遞是不是整個陣列,而是陣列的首元素的首位址(也就是整個陣列的首位址。因為傳參時是傳值,所以這兩個沒區別)。所以在子函式內部,傳進來的陣列名就等於是乙個指向陣列首元素首位址的指標。所以sizeof得到的是4.—–傳址呼叫

③指標作為函式形參:和陣列作為函式形參一樣.—–傳址呼叫

④結構體變數作為函式形參:結構體變數作為函式形參的時候,實際上和普通變數(類似於int之類的)傳參時表現是一模一樣的,只是結構體一般都很大。

(2)輸入型引數與輸出型引數:

const用來修飾指標做函式傳參,作用就在於宣告在函式內部不會改變這個指標所指向的內容,所以給該函式傳乙個不可改變的指標。

如果這個引數是用來做輸入的,就叫輸入型引數;如果這個引數的目的是用來做輸出的,就叫輸出型引數。

看到乙個函式的原型後,怎麼樣一眼看出來哪個引數做輸入哪個做輸出?函式傳參如果傳的是普通變數(不是指標)那肯定是輸入型引數;如果傳指標就有2種可能性了,為了區別,經常的做法是:如果這個引數是做輸入的(通常做輸入的在函式內部只需要讀取這個引數而不會需要更改它)就在指標前面加const來修飾;如果函式形參是指標變數並且還沒加const,那麼就表示這個引數是用來做輸出型引數的。

參考:

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...