指標可以說是C語言本身所具有的最大特性,平時根據不同使用場合習慣地將其簡單分類,下面是小編為大家整理的C語言中各種型別的指標的概念總結,歡迎參考~
C語言中有很多關於指標的使用,指標也是C語言的靈魂所在,而且C語言中也有很多有關指標的概念,這裡學習並總結了一些知道的概念。
常量指標:首先它是一個指標,常量只是用來修飾指標的定語。其定義如下:
12 | char const * cp; char a= 'a' ; |
如何識別呢?根據右結合優先,先是*優先,所以這個cp變數是一個指標,然後是const修飾*,所以這是一個常量指標。即指向常量的指標。
12 | cp=&a; //正常語法 *cp=a; //錯誤語法,因為其指向的值是一個常量 |
指標常量:首先它是一個常量,指標是用來修飾常量的,即常量的值為一個指標地址。
12 | char * const cp; char a= 'a' ; |
如何識別呢?根據右結合優先,先是const優先,所以這個cp變數是一個常量,然後是*修飾const,所以這是一個指標常量。
12 | cp=&a; //錯誤語法,因為其地址為是一個常量 *cp=a; //正確,地址所指向的內容是一個普通字元 |
指標陣列:首先它是一個數組,指標是用來修飾陣列內容的,表示什麼樣的陣列 :即存放指標的陣列
1 | char *arr[3] = { "1" , "123" , "345" }; |
如何識別,因為[]的'優先順序大於*,所以先是定義為一個數組,而後由*來修飾這個數
12 | printf ( "arr0%c" ,*arr[0]); printf ( "arr1%s" ,arr[1]); |
陣列指標:首先它是一個指標,陣列是修飾指標的,即指向陣列的指標。
123 | char (*p)[3]; //申明時不能同時初始化 char arr[3] = { '1' , '4' , '7' }; p=&arr; //指向陣列的首地址,同時指標的型別是char * [3] 型別的,即加1操作後為sizeof(char [3])三個位元組數 |
如何識別:因為這次添加了一個顯示優先,所以這次先是一個指標,而後[]修飾指標
123456789 | printf ( "%c" ,(*p)[0]); //先取arr的首地址,再根據這個地址取陣列內容 printf ( "%c" ,(*p)[1]); printf ( "%c" ,(*p)[2]); printf ( "%c" ,*(( char *)p+0)); //先轉換為char指標,再取值 printf ( "%c" ,*(( char *)p+1)); printf ( "%c" ,*(( char *)p+2)); printf ( "%c" ,(( char *)p)[0]); //先轉換為char指標,再取陣列的值,和第一個類似 printf ( "%c" ,(( char *)p)[1]); printf ( "%c" ,(( char *)p)[2]); |
函式指標:首先它是一個指標,函式是修飾指標的,即指向函式的指標。
12345678910 | char (*func)( void ); //定義函式指標 char test( void ) { return 'A' ; } func = test; //初始化賦值 printf ( "test address: %p" ,test); printf ( "func address: %p" ,func); char ch = func(); //呼叫 printf ( "%c" , ch); |
如何識別,同陣列指標一樣,因()的優先順序,所以這個定義首先是一個指標,而後才是對指標的描述,即一個指向函式的指標,其指向的函式也是規定的:即返回的是字元型別,不需要傳入引數
指標函式:首先它是一個函式,指標修飾函式的返回型別,即一個返回指標的函式
1 | char *func( void ); |
如何識別,因為沒有擴弧,所以*的優先順序沒有右邊的擴弧優先順序高,所以先是規定了一個函式,*只是修飾返回值的
12345678 | char *func( void ) {
char *str = "test" ;
return str;
}
void main() {
char *test = func();
printf ( "%s" ,test); } |
結構體指標:當然其原先也是一個指標,只不過就是指向了結構體而已。故而為結構體指標。
指標結構體:指標結構體,其實也沒有必要有這個概念,無非就是帶有指標作為子項的結構體。
指標型別轉換:指標型別轉換是個有意思的東西,你可以把一個int型的指標轉換為char型別,然後再把char型別的指標轉換為int型;就像普通的字元和int型之間的轉換一樣。但指標轉換後其值沒有變,唯一變的東西就是指標的步長,即進行指標運算時的計算方式。當為char指標時其運算單位均以1個位元組為1個運算單位,而當為int指標時通常都是以4個位元組為1個運算單位。
指標算術:根據上面的指標型別轉換介紹可知,不同的指標型別進行算術運算時其計算方式時不相同的,其不同之處就在於其步長的位元組數不同,而具體其步長為幾個位元組數是以其指標型別決定的,指向char的指標步長即為1。通常的指標運算有指標與數字的加減運算,相同型別的指標的減法運算,而且還要是指向同一個陣列的,不然意義不大。同理推得不同型別的指標進行運算意義更不大,甚至會報錯。
下面舉一個指標算術的例子,交換兩個變數值不利用額外變數
畢竟new關鍵字還是申請了額外的記憶體,雖然沒有申請變數,換湯未換藥
123456 | int *a,*b; a= new int (10); //給指標賦值 b= new int (20); //a=0x00030828,b=0x00030840 a=( int *)(b-a); //a=0x00000006 b=( int *)(b- int (a)); //b=0x00030828 a=( int *)(b+ int (a)); //a=0x00030840 |
只是交換變數的話也可以:
1234567 | int a = 4; int b = 5;
*((( char *)&a)+1) = *(( char *)&b); *(( char *)&b)=*(( char *)&a); *(( char *)&a)=*((( char *)&a)+1); *((( char *)&a)+1)=0; |
指標引數:指標引數就是指,指標作為函式的引數進行傳遞,因為C語言只支援單向傳值,且返回值只能是一個值型別,所以想要從函式內返回多個內容或者與函式體有一個共同的資料操作區域,那這個時候就可以考慮通過傳指標引數的方式了。傳指標也是傳值,只不過這時的值為指標指向的地址,也就是一個int整數。通過傳遞一個地址後就可以對一個共同的區域進行操作和資料共享了。
指標指標:指標的指標就是指向指標的指標,同理還有指向指標指標的指標;不過一般人的思維能做二級、三級的指標的就很好了。這裡主要是擴充套件一下指標與多維陣列的關聯關係。從個別到一般來分解多維陣列的處理。這裡個別肯定是用二維陣列來舉個例子,那就可以延伸到多維陣列。