C 語言中的指針
C 語言的指針常常被人們認(rèn)為是 C 語言中的靈魂所在,可以完成很多高難度的操作。但是更多的人感覺 C 語言的指針的存在如同噩夢(mèng)一般,因?yàn)樯圆蛔⒁猓蜁?huì)引起災(zāi)難性的后果。
不管你是不是喜歡 C 語言中的指針,我們都要學(xué)習(xí)這種看起來很神奇的東西。因?yàn)橹羔樳@個(gè)概念不是 C 語言首創(chuàng)的,而是蘇聯(lián)的計(jì)算機(jī)科學(xué)家首創(chuàng)的。
1. 什么是指針?
指針是什么?這是來自靈魂的拷問。其實(shí)指針也是一種變量。我們之前也說過。只不過存儲(chǔ)的是另外一個(gè)變量的地址。變量地址是變量在內(nèi)存中存儲(chǔ)的位置索引。
int *a;
int b=5;
a = &b;
這里我們定義了一個(gè)整數(shù)類型的指針 a
,可以看出指針的定義與變量的聲明是一致的,只不過需要在變量明前加上一個(gè)額外的字符 *
。
由于指針中存儲(chǔ)的應(yīng)該是變量的地址,因此我們?cè)谫x值的時(shí)候需要獲得變量的地址,而不是變量本身所存儲(chǔ)的數(shù)值。這里我們采用的 &
來獲取變量的地址。將獲取到的地址賦值給指針變量。
要是想使用指針中存儲(chǔ)地址中所存儲(chǔ)的值,那么就需要在指針變量名前加 *
來獲取相應(yīng)地址中存儲(chǔ)的值。
2. 示例程序
#include <stdio.h>
int main()
{
int *a, b = 100, *c;
printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a);
printf("b value = %d, b address = %p\n", b, &b);
printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c);
a = &b;
printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a);
c = a;
printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c);
printf("b value = %d, b address = %p\n", b, &b);
return 0;
}
運(yùn)行結(jié)果:
示例中的運(yùn)行結(jié)果中的十六進(jìn)制所表示的地址每臺(tái)機(jī)器都會(huì)不太一樣,甚至每次運(yùn)行都會(huì)發(fā)生變化。因?yàn)椴僮飨到y(tǒng)每次為系統(tǒng)分配的內(nèi)存都不太一樣。
a value = 0x7fffaf0005a0, a address = 0x7fffd2942a28, a point value = -1991643855
b value = 100, b address = 0x7fffd2942a24
c value = 0x7fffd2942b20, c address = 0x7fffd2942a30, c point value = 1
a value = 0x7fffd2942a24, a address = 0x7fffd2942a28, a point value = 100
c value = 0x7fffd2942a24, c address = 0x7fffd2942a30, c point value = 100
b value = 100, b address = 0x7fffd2942a24
示例程序中聲明了一個(gè)整數(shù)類型的指針 a
,同時(shí)還聲明并初始化了一個(gè)整數(shù)類型的變量 b
。
我們首先展示了此時(shí)此刻指針變量 a
中存儲(chǔ)的值,也就是一個(gè)內(nèi)存地址,這個(gè)地址為 0x7fffaf0005a0
,同時(shí) a
變量本身的地址為 0x7fffd2942a28
,此時(shí)其存儲(chǔ)的內(nèi)存地址中所存儲(chǔ)的值為 -1991643855
。這里需要說明的是, a
變量此時(shí)還沒有初始化,沒有賦值,里面存儲(chǔ)的數(shù)值是隨機(jī)的,所以其代表的值也是隨機(jī)的,必須在賦值以后才能使用。這點(diǎn)和所有的變量的使用是一致的。
變量 b
的存儲(chǔ)的數(shù)值為 100
,其內(nèi)存的地址為 0x7fffd2942a24
。
指針變量 c
中存儲(chǔ)的數(shù)值是地址 0x7fffd2942b20
,其本身的地址是 0x7fffd2942a30
,里面存儲(chǔ)的地址中存儲(chǔ)的數(shù)值為 1
。
然后我們進(jìn)行了一次賦值的操作。這里的賦值操作,就是將變量 b
的地址賦給了變量 a
。
這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)變量 a
中存儲(chǔ)的數(shù)值變成了變量 b
的地址,而變量 a
自己的地址是沒有發(fā)生變化的,而變量 a
中所存儲(chǔ)的地址中的值也編程了變量 b
中所存儲(chǔ)的值 100
。
指針之間的賦值就比較直接,和普通變量的賦值是一樣的,只要直接賦值就可以了。
下面的表格展示了這一系列的變化
初始狀態(tài)
變量名 | 變量中數(shù)值 | 地址 | 指針地址中數(shù)值 |
---|---|---|---|
a | 0x7fffaf0005a0 | 0x7fffd2942a28 | -1991643855 |
b | 100 | 0x7fffd2942a24 | |
c | 0x7fffd2942b20 | 0x7fffd2942a30 | 1 |
賦值后
變量名 | 變量中數(shù)值 | 地址 |
---|---|---|
a | 0x7fffd2942a24 | 0x7fffd2942a28 |
b | 100 | 0x7fffd2942a24 |
c | 0x7fffd2942a24 | 0x7fffd2942a30 |
3. 小結(jié)
指針作為 C 語言中相對(duì)比較抽象的部分,是很多初學(xué)者最難逾越的部分。但是請(qǐng)大家放松心情。因?yàn)橹羔樒鋵?shí)和普通變量沒有什么本質(zhì)的區(qū)別,其實(shí)叫做指針變量更為貼切一點(diǎn)。指針是一個(gè)變量,里面存儲(chǔ)的內(nèi)容是另外一個(gè)變量的內(nèi)存地址。每個(gè)變量都會(huì)有地址,包括指針變量自己本身也是有地址存在的。我們?cè)谫x值的時(shí)候是將別的變量通過變量名獲得的該變量的地址存儲(chǔ)到指針變量里,而后獲取這個(gè)被存儲(chǔ)到指針變量里的地址的數(shù)值,或者繼續(xù)將該變量的地址賦值給另外一個(gè)指針變量。指針變量的存在只是一個(gè)變量的賦值,切記理解為玄學(xué)。