存放內存單元的地址,該地址被形象的稱爲指針,存放在指針中的值都被當成地址處理。而指針變量就是一個存放地址的變量。與普通的變量相同把它看做一個新的類型就好。數組
在32位平臺下,有32根地址線,有2^32個排列組合,所以可編2^32(4G)個地址。編址的最小單位是字節。
因爲int變量佔四個字節,取地址取最低地址表示。(double、long同理)。
在32位機器上,地址是32個0或1組成的二進制序列,(32/8)那地址就得用4個字節空間來存儲,因此一個指針變量的大小就應該是4個字節。
同理在64位機器上,有64根地址線,(64/8)於是地址要用8個字節空間來存儲。ide
type+ * (二級指針:int **,type是int*)。type*****類型的指針是爲了存放某類型變量的地址。指針
指針的類型決定了指針向前或向後走一步有多大距離:加減上所指向類型佔字節的大小。於是加1或減一是令指針指向了下或上一個一個變量、數組、結構體。。。。
看下面例子:code
int n = 10; int *pi = &n; char *pc = (char *)&n; printf("%p\n", pi); ---> 00D8F9D0 printf("%p\n", pi+1); --->00D8F9D4 printf("%p\n", pc); --->00D8F9D0 printf("%p\n", pc+1); --->00D8F9D1
答案符合正如咱們解釋的那樣
ps:二級指針、三級指針..他們指向的類型都是指針類型,因此加一或減一都會加或減4個字節。(指針所佔空間大小爲4B)blog
指針的類型決定了,對指針解引用的時候有多大權限(能訪問幾個字節),例如:char* 指針解引用就只能訪問一個字節,而int*的指針就可以訪問4個字節。內存
int n = 0x11223344; int* pi = &n; char* pc = (char*)&n; //解引用只能指向一個空間 *pc=0x55; printf("%x\n", n); --->11223355 *pi = 0; printf("%x\n", n); --->0
表明兩個指針之間經歷的元素。
eg:it
int a[10]; int *p=&a[0]; int *q =&a[9]; 則:p-q=9不是(4*9=36) 若 char *p=(char*)&a[0]; char *q =(char *)&a[9]; p-q=36; //元素個數由指針指向類型決定。
標準規定:容許指向數組元素的指針與指向數組最後一個元素後面的那個內存位置的指針比較,可是不容許與指向第一個元素以前的那個內存位置的指針比較。
對比:class
for(vp=&values[N_values];vp>&values[0];) //比較都是合法的 { *--vp=0; } for(vp=&values[N_values-1];vp>=&values[0];vp--) //vp=-1時比較後不成立而後才退出循環! { *vp=0; }
存放一級指針地址的變量。
由於指針也是變量,既然是變量,那他也確定有地址,有地址,因此也能夠被保存起來,保存一級指針地址的空間,就是二級指針。
其關係表示
基礎
二者本質上沒有什麼關係!
數組名與數組地址及數組首元素的關係:數組地址與數組首元素地址在數值上相等。但意義上不一樣。(數組地址加一加過了整個數組,而首元素地址加一隻加過了一個元素)
數組名在取地址符號後,及在sizeof中單獨使用時表明整個數組,剩下的情景都表示數組中首元素地址。
數組表示中 數組名稱【元素下標】=*(數組名稱+元素下標) 此處的數組名稱表示首元素地址。變量
我的心得:指針就是一個存放地址的變量,二級指針也是個變量,三級四級都是,因此不要總把指針看做個例。
數組和指針沒有什麼關係,只是在某些表達形式上,有不少相同之處。
一個數組,裏面存放元素的類型都是某類型指針,數組內每一個空間都存放一個地址,指向某內存空間。
int* arr1[10]; //×××指針的數組 char* arr2[4]; //一級字符指針的數組 char** arr3[4];//二級字符指針的數組