?、C語?中的指針
與指針相關(guān)的概念
? 內(nèi)存:程序和數(shù)據(jù)通常存儲(chǔ)在硬盤上,他們會(huì)被持久保存。硬
盤可以存儲(chǔ)很多東西,但其傳輸數(shù)據(jù)的速度較慢,所以需要在
運(yùn)?程序或者打開數(shù)據(jù)時(shí),這些數(shù)據(jù)必須從硬盤上傳遞到另?
種容量較?但速度很快的存儲(chǔ)器上,之后才送?CPU執(zhí)?處理。
這樣的存儲(chǔ)器就是內(nèi)存。
? 內(nèi)存地址:為了正確訪問內(nèi)存單元,每個(gè)內(nèi)存單元都擁有?個(gè)
編號(hào),這些編號(hào)是連續(xù)的,稱作地址。編號(hào)對(duì)應(yīng)的內(nèi)存以字節(jié)
為單位劃分。
內(nèi)存地址的??:內(nèi)存地址的??與操作系統(tǒng)的位數(shù)相關(guān),32
位操作系統(tǒng)占4個(gè)字節(jié),64位操作系統(tǒng)占8個(gè)字節(jié)。
?、指針變量的定義
? 指針變量:特指存儲(chǔ)內(nèi)存地址的變量,統(tǒng)稱為指針變量或指針
? 指針變量的定義:
/*
int *指針變量的類型,表?整型指針
p為變量名
NULL為初始值,恒等于0
*/
int *p = NULL;
指針變量與基本類型變量定義?式的區(qū)別:為了區(qū)別于普通變
量的定義,*在變量定義的時(shí)候起到了修飾作?,修飾所定義的
變量p只能?于存儲(chǔ)指針。
/*
為了防?出現(xiàn)如下的逗號(hào)表達(dá)式,導(dǎo)致變量的類型混亂,*與
變量名相鄰
*/
三、與指針變量相關(guān)的運(yùn)算符
取址運(yùn)算符—&
/*
&:取址運(yùn)算符,獲取number變量對(duì)應(yīng)內(nèi)存單元的?地址,單?
運(yùn)算
*/
int number = 5;
//獲取number的地址賦值給指針變量p
int *p = &number;
printf("p -> %p\n", p);
p -> 0x7fff5fbff85c
取內(nèi)容運(yùn)算符—*
int number = 5, digital = 12;
int *p = &number;
//*為取內(nèi)容運(yùn)算符,等價(jià)于number變量,單?運(yùn)算
printf("content -> %d\n", *p);
//為指針變量p賦值新的內(nèi)存地址
p = &digital;
//為指針變量指向的存儲(chǔ)空間賦值
*p = 200;
指針變量的重指向:將?個(gè)已定義的指針變量賦值為
另?個(gè)變量的?地址稱之為指針變量的重指向
指針變量的算數(shù)運(yùn)算
強(qiáng)調(diào):指針不是類型,真正的類型是地址,指針(指針變量)
是指存儲(chǔ)地址這種數(shù)據(jù)類型的數(shù)據(jù)的變量
? 例如:
int number = 5;
? 5是整數(shù),?number是存儲(chǔ)該整數(shù)的變量。指針就好?number
變量,?地址就如5這個(gè)整數(shù)。
指針能夠進(jìn)?算數(shù)運(yùn)算本質(zhì)原因在于算數(shù)運(yùn)算是地址這種數(shù)據(jù)類
型的本能,正因?yàn)榈刂肪哂屑訙p運(yùn)算的能?,才使得指針作為存
放地址的變量也能夠進(jìn)?算數(shù)運(yùn)算,如number++
? 指針變量的數(shù)據(jù)類型:指針變量的數(shù)據(jù)類型只限定了指針在參
與算數(shù)運(yùn)算的時(shí)候?次偏移多少個(gè)字節(jié),通過*取內(nèi)容的時(shí)候
讀取多少個(gè)字節(jié) int number = 5;
int *p = &number;
四、指針變量與數(shù)組的關(guān)系
關(guān)于數(shù)組名
注意:數(shù)組名并不是指針
? ?例:
int array[10] = {0};
printf("array -> \t%p\n", array);
printf("&array -> \t%p\n", &array);
printf("array + 1 -> \t%p\n", array + 1);
printf("&array + 1 -> \t%p\n", &array + 1)
? 結(jié)果:
array -> 0x7fff5fbff840
&array -> 0x7fff5fbff840
array + 1 -> 0x7fff5fbff844
&array + 1 -> 0x7fff5fbff868
關(guān)于數(shù)組名
? 分析:
? array與&array指向同?個(gè)內(nèi)存地址,但其通過算數(shù)運(yùn)算后的結(jié)果不
同。array + 1偏移?個(gè)數(shù)據(jù)類型所占字節(jié)數(shù)(4個(gè)字節(jié)),&array +
1偏移整個(gè)array數(shù)組所占字節(jié)數(shù)(40個(gè)字節(jié))
printf("%ld\n", sizeof(array));
? 這?代碼會(huì)得到整個(gè)數(shù)組的內(nèi)存??,事實(shí)可以證明:&array獲取的
是整個(gè)數(shù)組的??。數(shù)組名取地址等價(jià)于對(duì)數(shù)組取地址。
? array與&array的結(jié)果都是取數(shù)組的?地址,但其數(shù)據(jù)類型不同;
? array表?&array[0],即表?數(shù)組?個(gè)元素的地址,array + 1表?數(shù)
組?地址 + sizeof(數(shù)組元素類型)。
? &array雖然值為數(shù)組?個(gè)元素的地址,但其數(shù)據(jù)類型實(shí)為:int (*)[10]
表?長度為10的?維整型數(shù)組指針類型,&array + 1表?數(shù)組?地址
+ 數(shù)組總??。
注意:數(shù)組名是?個(gè)符號(hào)地址常量,不是變量,所以不能?增,?減
指針與數(shù)組
int array[10] = {0};
int *p = array;
? p指針保存數(shù)組的?地址
? *p、*(p + 1)、(*p) + 1分別為多少
? 被賦值為數(shù)組?地址的指針p可以被當(dāng)作數(shù)組名來使?
? p[1] = 3;
? 等價(jià)于 array[1] = 3;
? 等價(jià)于 *(array + 1) = 3;
? 等價(jià)于 *(p + 1) = 3;
? 等價(jià)于 p[1] = 3;
四、指針與字符串
? C語???維字符數(shù)組來描述字符串的概念,故指針與字符串類似于
指針與數(shù)組的概念。
? 字符指針可以操作單個(gè)字符,也可以操作整個(gè)字符串。
string為數(shù)組名,同時(shí)也是?個(gè)代表數(shù)組?地址的地址常量
*/
char string[] = "lanou3g";
char *p = string;
//操作字符
*(p + 1) = 'A';
//操作字符串
printf("string: %s\n", p);
? %s格式控制符的作?:printf函數(shù)的格式串中如果包含%s格式控制
符,擇需要對(duì)應(yīng)?個(gè)指針,函數(shù)內(nèi)部會(huì)循環(huán)對(duì)指針做移位運(yùn)算來得到
每?個(gè)字符,知道遇到字符串的結(jié)束標(biāo)志符’\0’結(jié)束。