C指针1:基础
看了很多遍的指針,決定自己總結(jié)記錄一下。
先明確兩個概念:
1.指針:也就是內(nèi)存的地址。
2.指針變量:也就是保存了內(nèi)存地址的變量。
在計算機中所有的數(shù)據(jù)都必須放在內(nèi)存中,然而不同類型的數(shù)據(jù)占用不同的字節(jié)數(shù)。比如int占用4個字節(jié),char占用1個字節(jié),當這些數(shù)據(jù)載入內(nèi)存之后為了能夠正確的找到并訪問這些數(shù)據(jù),我們就需要為每個字節(jié)編上號碼,就像每個人都有一個身份證一樣,字節(jié)的編號也是唯一的,根據(jù)這些編號我們就可以準確的找到某個字節(jié)。
在32位的環(huán)境下,一個指針或地址占用4個字節(jié)的內(nèi)存,共有32位,理論上能夠訪問的虛擬內(nèi)存空間大小為2^32 =?0X100000000 Bytes(2表示2進制即0、1(每一位上有兩種可能0或者1)一種組合就代表一個地址),即4GB,有效虛擬地址范圍是 0 ~ 0XFFFFFFFF。
(2的32次方 等于4294967296)(2的32次方中0或者1的組合,每一種組合都代表一組地址)
(100000000(十六進制) = 4294967296(十進制))
(FFFFFFFF(十六進制) = 4294967295(十進制))
下面是4G內(nèi)存中每個字節(jié)的編號(用16進制來表示)
上圖中我們將內(nèi)存中字節(jié)的編號稱為地址(Address)或者指針(Pointer),地址是從0開始依次增加的,對于32位環(huán)境程序能夠使用的內(nèi)存為4GB,最小的地址為0,最大的地址為0XFFFFFFFF。
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {int a = 100;char str[20] = "liminhao";int b[6] = {0,1,5,9,3,6};string c[5] = {"a","b","k","f","g"};//string是一個類printf("%#X, %#X\n", &a, str);cout << "a的地址:" << &a << endl;cout << "字符串名字str:" << str << endl;cout << "字符串str第一個元素str[0]:" << str[0] << endl;cout << "字符串str第一個元素地址:" << &str <<" , "<<&str[0]<< endl;cout << "數(shù)組名b:" << b << endl;cout << "數(shù)組b第一個元素的地址:" << &b[0] << endl;cout<< "b[0]:"<<b[0] << endl;cout << "字符串名字c:" << c << endl;cout << "字符串c第一個元素地址:" << &c << " , " << &c[0] << endl;return 0;
}
結(jié)果:
%#X表示以十六進制形式輸出,并附帶前綴0X。a 是一個變量,用來存放整數(shù),需要在前面加&來獲得它的地址;str 本身就表示字符串的首地址,不需要加&。 但是在上述c++中我們可以看到,字符串名字并不表示字符串首地址,而是輸出的整個字符。
在C語言中用變量來存儲數(shù)據(jù),用函數(shù)來定義一段可以重復(fù)使用的代碼,他們最終都要放到內(nèi)存中才能共CPU使用(數(shù)據(jù)和代碼都以二進制的形式存儲到內(nèi)存中,計算機無法從格式上區(qū)分某塊內(nèi)存到底存儲的是數(shù)據(jù)還是代碼。當程序被加載到內(nèi)存后,操作系統(tǒng)會給不同的內(nèi)存塊指定不同的權(quán)限,擁有讀取和執(zhí)行權(quán)限的內(nèi)存塊就是代碼,而擁有讀取和寫入權(quán)限(也可能只有讀取權(quán)限)的內(nèi)存塊就是數(shù)據(jù)。),正如之前在內(nèi)存中所介紹的一樣,一段程序經(jīng)過編譯之后變量名函數(shù)名都不存在,只剩下數(shù)據(jù),地址和指令。
程序經(jīng)過編譯后,CPU只能通過地址來獲取內(nèi)存中的代碼和數(shù)據(jù),程序在執(zhí)行過程中會告知 CPU 要執(zhí)行的代碼以及要讀寫的數(shù)據(jù)的地址。
CPU 訪問內(nèi)存時需要的是地址,而不是變量名和函數(shù)名!變量名和函數(shù)名只是地址的一種助記符,當源文件被編譯和鏈接成可執(zhí)行程序后,它們都會被替換成地址。編譯和鏈接過程的一項重要任務(wù)就是找到這些名稱所對應(yīng)的地址。
需要注意的是,雖然變量名、函數(shù)名、字符串名和數(shù)組名在本質(zhì)上是一樣的,它們都是地址的助記符,但在編寫代碼的過程中,我們認為變量名表示的是數(shù)據(jù)本身,而函數(shù)名、字符串名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址。
參考:C語言中文網(wǎng)
總結(jié)