C語言超詳細講解指針的使用
指針概述
C語言中指針也可以認為是一種類型,不同於數值型和字符型的類型。推演過去指針變量也就是相當於不同的變量類型,不同於數值變量、字符型變量、字符串變量。
指針變量兩種類型:自身類型和指向的類型
自身類型:將變量名去掉,剩下的就是指針變量類型。
指向類型:將變量名和離它最近的一個*去掉,剩下的類型就是指針指向的類型
int num = 10; int* p = NULL; p = #
如代碼中 指針變量的自身類型是 int * 型;指向類型是 int 型。
自身類型
自身類型是指變量p本身的類型,變量p中放的是地址內容,地址指向的是放整型的數據,為什麼需要說是指向整型的地址呢?因為不同類型數據占據的不同大小的一整塊內存,整型是一個占4字節大小的一個整體內存,字符型是一個占2個字節大小的一個整體內存,編譯器不會把它們拆分開。如定義瞭一個int型變量,它的地址是0x7fffffff00,緊接著馬上定義一個char型變量,他的地址就直接到瞭0x7fffffff04。從0x7fffffff00 ~ 0x7fffffff04中間不會再被分開瞭放int型數據,0x7fffffff04 ~ 0x7fffffff06中間不分開放char型數據。
所以 自身類型 是基本類型 + *組合而成,雖然裡面放的都是地址,但是地址指向的一整塊內容是有區別的。
指向類型
指向類型 是指 指針變量中放置的地址是指向的內容類型。
int num = 10; int* p = NULL; p = # int** pp = NULL; pp = &p;
這是一個二級指針,指向的類型是int*,說明變量pp指向的是指針類型的數據。
代碼例子
代碼1
#include <stdio.h> int main() { int num = 100; printf("num = %d, num address = %#lx\n", num, &num); //num = 100, num address = 0x7ffd4376ff4c int* p = NULL; p = # printf("*p = %d, p = %#lx, &p = %#lx\n", *p, p, &p); //*p = 100, p = 0x7ffd4376ff4c, &p = 0x7ffd4376ff40 int** pp = NULL; pp = &p; printf("**pp = %d, *pp = %#lx, pp = %#lx\n", **pp, *pp, pp); //**pp = 100, *pp = 0x7ffd4376ff4c, pp = 0x7ffd4376ff40 int arr[5]= {10,20,30,40,50}; printf("arr address = %#lx, arr[0] address = %#lx, arr[0] = %d\n",arr,&arr[0],arr[0]); //arr address = 0x7ffd4376ff20, arr[0] address = 0x7ffd4376ff20, arr[0] = 10 int* parr = NULL; parr = arr; printf("parr = %#lx, *parr = %d, *(parr+2) = %d\n",parr,*parr,*(parr+2)); //parr = 0x7ffd4376ff20, *parr = 10, *(parr+2) = 30 char str[6]= {'a','d','m','i','n','\0'}; printf("str address = %#lx, str[0] address = %#lx, str[1]= %c\n", str, &str[0],str[1]); //str address = 0x7ffd4376ff10, str[0] address = 0x7ffd4376ff10, str[1]= d char* pstr = NULL; pstr = str; printf("pstr = %#lx,*pstr = %c,*(pstr+2)= %c\n",pstr,*pstr,*(pstr+2)); //pstr = 0x7ffd4376ff10,*pstr = a,*(pstr+2)= m char str2[6] = "admin"; printf("str2 = %#lx, str2[0] address = %#lx, str2 = %s, str2[1]= %c\n",str2,&str2[0],str2,str2[1]); //str2 = 0x7ffd4376ff00, str2[0] address = 0x7ffd4376ff00, str2 = admin, str2[1]= d char* pstr2 = NULL; pstr2 = str2; printf("pstr2 = %#lx, pstr2 = %s\n",pstr2, pstr2); //pstr2 = 0x7ffd4376ff00, pstr2 = admin }
代碼2
#include <stdio.h> int main() { float num = 10; printf("num = %f, &num = %#lx\n\n", num, &num); //num = 10.000000, &num = 0x7ffcdf7ffd94 float* pnum = # printf("*pnum = %f, pnum = %#lx, &pnum = %#lx\n\n ", *pnum, pnum, &pnum); //*pnum = 10.000000, pnum = 0x7ffcdf7ffd94, &pnum = 0x7ffcdf7ffd88 float** p_pnum = &pnum; printf("**p_pnum = %f, *p_pnum = %#lx, p_pnum = %#lx\n\n",**p_pnum,*p_pnum,p_pnum); //**p_pnum = 10.000000, *p_pnum = 0x7ffcdf7ffd94, p_pnum = 0x7ffcdf7ffd88 char arr[10] = {'a','d','m','i','n'}; printf("arr[0]= %c, arr[5]= %c, arr[6]= %c, arr = %s\n",arr[0],arr[5],arr[6],arr); printf("&arr[0]= %#lx, &arr[1]= %#lx, arr= %#lx\n\n", &arr[0], &arr[1], arr); //arr[0]= a, arr[5]= , arr[6]= , arr = admin //&arr[0]= 0x7ffcdf7ffd70, &arr[1]= 0x7ffcdf7ffd71, arr= 0x7ffcdf7ffd70 char* parr = NULL; parr = arr; printf("*parr = %c, *(parr+4)=%c, *(parr+5)=%c, parr = %s\n",*parr,*(parr+4),*(parr+5),parr); printf("parr = %#lx, parr+4 = %#lx, parr+5= %#lx\n\n", parr, parr+4, parr+5); //*parr = a, *(parr+4)=n, *(parr+5)=, parr = admin //parr = 0x7ffcdf7ffd70, parr+4 = 0x7ffcdf7ffd74, parr+5= 0x7ffcdf7ffd75 char str[10]= "admin"; printf("str[0]= %c, str[5]= %c, str[6]= %c, str = %s\n",str[0],str[5],str[6],str); printf("&str[0]= %#lx, &str[1]= %#lx, str = %#lx\n\n", &str[0], &str[1], str); //str[0]= a, str[5]= , str[6]= , str = admin //&str[0]= 0x7ffcdf7ffd60, &str[1]= 0x7ffcdf7ffd61, str = 0x7ffcdf7ffd60 char* pstr = NULL; pstr = str; printf("*pstr= %c, *(pstr+4)= %c, *(pstr+5)= %c, pstr = %s\n", *pstr, *(pstr+4), *(pstr+5), pstr); printf("pstr = %#lx, pstr+4=%#lx, pstr+5= %#lx\n\n",pstr, pstr+4, pstr+5); //*pstr= a, *(pstr+4)= n, *(pstr+5)= , pstr = admin //pstr = 0x7ffcdf7ffd60, pstr+4=0x7ffcdf7ffd64, pstr+5= 0x7ffcdf7ffd65 }
數值型指針
數值型指針: int* p;
如:
int num = 100; int* p = # //同時定義和初始化 int* p1 = NULL; //定義 p1 = # //初始化
字符型指針
字符型指針可以分為指針指向的是單字符還是字符數組兩種
單字符
字符型指針: char* p;
char name = 'a'; char* p = &name; printf("p = %c",*p); //結果是 a
這裡需要註意需要用 占位符 %c 去承接內容(或者說顯示內容)
字符數組
字符型指針:char* p;
char arr[6] = {'a','d','m','i','n','\0'}; printf("arr = %s, arr = %#lx\n",arr,arr); //admin,0x7ffffffc0 printf("arr[0]= %c,arr[1]= %c\n",arr[0],arr[1]);//a,d char* parr = NULL; parr = arr; //也可以 parr = &arr,但是編譯時會報warning printf("parr = %s, parr = %#lx\n", parr,parr); //admin,0x7ffffffc0 printf("*(parr)= %c,*(parr + 1) = %c\n",*parr, *(parr+1));
這裡需要註意字符數組末尾需要加‘\0’字符表示字符數組結束,或者編譯器自己會自動加上,所以在定義字符數組長度時需要加+1。
註意 字符數組名既可以表示地址也可以表示整個字符數組的內容,而不是第一個字符。相應的指針也是整個字符數組的內容。
printf("arr = %c\n", arr); printf("parr = %c\n", parr);
以上兩行代碼可以編譯過但是不能顯示內容,需要用占位符%s去承接整個字符數組內容。
字符串型指針
字符型指針:char* p;
char str[5] = "admin"; printf("str = %s,str = %#lx\n",str,str); // admin,0x7ffffffe0. printf("str[0]= %c, str[1]= %c\n",str[0],str[1]); // a,d char* pstr = NULL; pstr = str; printf("pstr = %s, pstr = %#lx\n",pstr,pstr); // admin,0x7ffffffe0. printf("*pstr = %c,*(pstr+1) = %c\n",*pstr,*(pstr+1)); // a,d
如代碼中結果顯示所示,字符串數組名即是地址,同時也是數組內容,根據占位符的不同顯示不同內容,占位符為%s時顯示字符串,%#lx顯示地址。同樣的對於賦值給的指針變量也具有同樣的功能。
但是如果這裡
printf("str = %c\n",str); //可以編譯過但是不顯示任何信息
字符數組總結
字符數組和字符串數組名都可以即表示地址又表示地址對應的內容,註意看需要它以什麼形式顯示,顯示內容用%s,顯示地址用%#lx。
字符數組和字符串數組名對應的地址都是第一個字符所在的地址。如上面的代碼中 &arr[0] 和 arr 得到的地址相同
到此這篇關於C語言超詳細講解指針的使用的文章就介紹到這瞭,更多相關C語言指針內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!