C 語言中的指針
C 語言的指針常常被人們認為是 C 語言中的靈魂所在,可以完成很多高難度的操作。但是更多的人感覺 C 語言的指針的存在如同噩夢一般,因為稍不注意,就會引起災難性的后果。
不管你是不是喜歡 C 語言中的指針,我們都要學習這種看起來很神奇的東西。因為指針這個概念不是 C 語言首創的,而是蘇聯的計算機科學家首創的。
1. 什么是指針?
指針是什么?這是來自靈魂的拷問。其實指針也是一種變量。我們之前也說過。只不過存儲的是另外一個變量的地址。變量地址是變量在內存中存儲的位置索引。
int *a;
int b=5;
a = &b;
這里我們定義了一個整數類型的指針 a
,可以看出指針的定義與變量的聲明是一致的,只不過需要在變量明前加上一個額外的字符 *
。
由于指針中存儲的應該是變量的地址,因此我們在賦值的時候需要獲得變量的地址,而不是變量本身所存儲的數值。這里我們采用的 &
來獲取變量的地址。將獲取到的地址賦值給指針變量。
要是想使用指針中存儲地址中所存儲的值,那么就需要在指針變量名前加 *
來獲取相應地址中存儲的值。
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;
}
運行結果:
示例中的運行結果中的十六進制所表示的地址每臺機器都會不太一樣,甚至每次運行都會發生變化。因為操作系統每次為系統分配的內存都不太一樣。
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
示例程序中聲明了一個整數類型的指針 a
,同時還聲明并初始化了一個整數類型的變量 b
。
我們首先展示了此時此刻指針變量 a
中存儲的值,也就是一個內存地址,這個地址為 0x7fffaf0005a0
,同時 a
變量本身的地址為 0x7fffd2942a28
,此時其存儲的內存地址中所存儲的值為 -1991643855
。這里需要說明的是, a
變量此時還沒有初始化,沒有賦值,里面存儲的數值是隨機的,所以其代表的值也是隨機的,必須在賦值以后才能使用。這點和所有的變量的使用是一致的。
變量 b
的存儲的數值為 100
,其內存的地址為 0x7fffd2942a24
。
指針變量 c
中存儲的數值是地址 0x7fffd2942b20
,其本身的地址是 0x7fffd2942a30
,里面存儲的地址中存儲的數值為 1
。
然后我們進行了一次賦值的操作。這里的賦值操作,就是將變量 b
的地址賦給了變量 a
。
這個時候你會發現變量 a
中存儲的數值變成了變量 b
的地址,而變量 a
自己的地址是沒有發生變化的,而變量 a
中所存儲的地址中的值也編程了變量 b
中所存儲的值 100
。
指針之間的賦值就比較直接,和普通變量的賦值是一樣的,只要直接賦值就可以了。
下面的表格展示了這一系列的變化
初始狀態
變量名 | 變量中數值 | 地址 | 指針地址中數值 |
---|---|---|---|
a | 0x7fffaf0005a0 | 0x7fffd2942a28 | -1991643855 |
b | 100 | 0x7fffd2942a24 | |
c | 0x7fffd2942b20 | 0x7fffd2942a30 | 1 |
賦值后
變量名 | 變量中數值 | 地址 |
---|---|---|
a | 0x7fffd2942a24 | 0x7fffd2942a28 |
b | 100 | 0x7fffd2942a24 |
c | 0x7fffd2942a24 | 0x7fffd2942a30 |
3. 小結
指針作為 C 語言中相對比較抽象的部分,是很多初學者最難逾越的部分。但是請大家放松心情。因為指針其實和普通變量沒有什么本質的區別,其實叫做指針變量更為貼切一點。指針是一個變量,里面存儲的內容是另外一個變量的內存地址。每個變量都會有地址,包括指針變量自己本身也是有地址存在的。我們在賦值的時候是將別的變量通過變量名獲得的該變量的地址存儲到指針變量里,而后獲取這個被存儲到指針變量里的地址的數值,或者繼續將該變量的地址賦值給另外一個指針變量。指針變量的存在只是一個變量的賦值,切記理解為玄學。