C語言指標

2022-05-05 02:18:09 字數 3827 閱讀 2145

int p; //p是整型變數  

int *p; //首先從p 處開始,先與*結合,所以說明p 是乙個指標,然後再與int 結合,說明指標所指向的內容的型別為int 型.所以p是乙個指向整型資料的指標

int p[3]; //首先從p處開始,先與結合,說明p 是乙個陣列,然後與int 結合,說明陣列裡的元素是整型的,所以p是乙個由整型資料組成的陣列

int *p[3]; //首先從p 處開始,先與結合,因為其優先順序比*高,所以p 是乙個陣列,然後再與*結合,說明陣列裡的元素是指標型別,然後再與int 結合,說明指標所指向的內容的型別是整型的,所以p 是乙個由指向整型資料的指標所組成的陣列

int (*p)[3]; //首先從p 處開始,先與*結合,說明p 是乙個指標然後再與結合(與"()"這步可以忽略,只是為了改變優先順序),說明指標所指向的內容是乙個陣列,然後再與int 結合,說明陣列裡的元素是整型的.所以p 是乙個指向由整型資料組成的陣列的指標

int **p; //首先從p開始,先與*結合,說是p 是乙個指標,然後再與*結合,說明指標所指向的元素是指標,然後再與int 結合,說明該指標所指向的元素是整型資料.

int p(int); //從p 處起,先與()結合,說明p 是乙個函式,然後進入()裡分析,說明該函式有乙個整型變數的引數,然後再與外面的int 結合,說明函式的返回值是乙個整型資料

int (*p)(int); //從p 處開始,先與指標結合,說明p 是乙個指標,然後與()結合,說明指標指向的是乙個函式,然後再與()裡的int 結合,說明函式有乙個int 型的引數,再與最外層的int 結合,說明函式的返回型別是整型,所以p 是乙個指向有乙個整型引數且返回型別為整型的函式的指標

int *(*p(int))[3]; //從p開始,先與()結合,說明p 是乙個函式,然後進入()裡面,與int 結合,說明函式有乙個整型變數引數,然後再與外面的*結合,說明函式返回的是乙個指標,,然後到最外面一層,先與結合,說明返回的指標指向的是乙個陣列,然後再與*結合,說明陣列裡的元素是指標,然後再與int 結合,說明指標指向的內容是整型資料.所以p 是乙個引數為乙個整資料且返回乙個指向由整型指標變數組成的陣列的指標變數的函式.

int*ptr;//指標的型別是int*

char*ptr;//指標的型別是char*

int**ptr;//指標的型別是int**

int(*ptr)[3];//指標的型別是int(*)[3]

int*(*ptr)[4];//指標的型別是int*(*)[4]

int*ptr; //指標所指向的型別是int

char*ptr; //指標所指向的的型別是char

int**ptr; //指標所指向的的型別是int*

int(*ptr)[3]; //指標所指向的的型別是int()[3]

int*(*ptr)[4]; //指標所指向的的型別是int*()[4]

這個值將被編譯器當作乙個位址.在32 位程式裡,所有型別的指標的值都是乙個32 位整數,因為32 位程式裡記憶體位址全都是32 位長。stm32f系列屬於中低端的32位arm微控制器。

指標所指向的記憶體區就是從指標的值所代表的那個記憶體位址開始,長度為sizeof(指標所指向的型別)的一片記憶體區。我們說乙個指標的值是xx,就相當於說該指標指向了以xx 為首位址的一片記憶體區域;我們說乙個指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首位址。

在32 位平台裡,指標本身佔據了4 個位元組的長度。

char a[20];  

int *ptr=(int *)a; //強制型別轉換並不會改變a 的型別

ptr++;

指標ptr被加了1,編譯器是這樣處理的:它把指標ptr 的值加上了sizeof(int),在32 位程式中,是被加上了4,因為在32 位程式中,int 佔4 個位元組。由於位址是用位元組做單位的,故ptr 所指向的位址由原來的變數a 的位址向高位址方向增加了4 個位元組。由於char 型別的長度是乙個位元組,所以,原來ptr 是指向陣列a 的第0 號單元開始的四個位元組,此時指向了陣列a 中從第4 號單元開始的四個位元組。

&是取位址運算子

*是間接運算子

char *str[3]=;  

char s[80];

strcpy(s,str[0]); //也可寫成strcpy(s,*str);

strcpy(s,str[1]); //也可寫成strcpy(s,*(str+1));

strcpy(s,str[2]); //也可寫成strcpy(s,*(str+2));

str 是乙個三單元的陣列,該陣列的每個單元都是乙個指標,這些指標各指向乙個字串。把指標陣列名str 當作乙個指標的話,它指向陣列的第0 號單元,它的型別是char **,它指向的型別是char *。

struct mystruct  

; struct mystruct ss=;

//宣告了結構物件ss,並把ss 的成員初始化為20,30 和40。

struct mystruct *ptr=&ss;

//宣告了乙個指向結構物件ss 的指標。它的型別是

//mystruct *,它指向的型別是mystruct。

int *pstr=(int*)&ss;

//宣告了乙個指向結構物件ss 的指標。但是pstr 和

//它被指向的型別ptr 是不同的。

怎樣通過指標ptr 來訪問ss 的三個成員變數?
ptr->a; //指向運算子,或者可以這們(*ptr).a,建議使用前者

ptr->b;

ptr->c;

怎樣通過指標pstr 來訪問ss 的三個成員變數?
*pstr; //訪問了ss 的成員a。

*(pstr+1); //訪問了ss 的成員b。

*(pstr+2) //訪問了ss 的成員c。

這樣使用pstr 來訪問結構成員是不正規的,所有的c/c++編譯器在排列陣列的單元時,總是把各個陣列單元存放在連續的儲存區里,單元和單元之間沒有空隙。但在存放結構物件的各個成員時,在某種編譯環境下,可能會需要字對齊或雙字對齊或者是別的什麼對齊,需要在相鄰兩個成員之間加若干個"填充位元組",這就導致各個成員之間可能會有若干個位元組的空隙。即使pstr 訪問到了結構物件ss 的第乙個成員變數a,也不能保證(pstr+1)就一定能訪問到結構成員b。因為成員a 和成員b 之間可能會有若干填充位元組,說不定*(pstr+1)就正好訪問到了這些填充位元組呢。指標訪問結構成員的正確方法應該是使用指標ptr 的方法。

非專業人員略過,詳情請看參考

指標的賦值語句要求賦值號兩邊的型別一致,所指向的型別也一致

float f=12.3;  

float *fptr=&f;

int *p;

p=(int*)&f;

強制型別轉換的結果是乙個新指標,該新指標的型別是type *,它指向的型別是type,它指向的位址就是原指標指向的位址。

char s='a';  

int *ptr;

ptr=(int *)&s;

*ptr=1298;

指標ptr 是乙個int *型別的指標,它指向的型別是int。它指向的位址就是s 的首位址。在32 位程式中,s 佔乙個位元組,int 型別佔四個位元組。最後一條語句不但改變了s 所佔的乙個位元組,還把和s 相臨的高位址方向的三個位元組也改變了。這三個位元組是幹什麼的?只有編譯程式知道,而寫程式的人是不太可能知道的。也許這三個位元組裡儲存了非常重要的資料,也許這三個位元組裡正好是程式的一條**,而由於你對指標的馬虎應用,這三個位元組的值被改變了!這會造成崩潰性的錯誤。

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