久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网

您好,歡迎進入深圳市穎特新科技有限公司官方網站!

您現在的位置:首頁 新聞資訊 >> 新聞頭條 >> 關于指針
新聞資訊
NEWS INFORMATION

關于指針

發布時間:2019-05-22

計算機中所有的數據都必須放在內存中,不同類型的數據占用的字節數不一樣,例如 int 占用4個字節,char 占用1個字節。為了正確地訪問這些數據,必須為每個字節都編上號碼,就像門牌號、身份證號一樣,每個字節的編號是唯一的,根據編號可以準確地找到某個字節。

下圖是 4G 內存中每個字節的編號(以十六進制表示):


我們將內存中字節的編號稱為地址(Address)或指針(Pointer)。地址從 0 開始依次增加,對于 32 位環境,程序能夠使用的內存為 4GB,最小的地址為 0,最大的地址為 0XFFFFFFFF。

下面的代碼演示了如何輸出一個地址:

#include <stdio.h>
int main(){
int a = 100;
char str[20] = "c.biancheng.net";
printf("%#X, %#X\n", &a, str);
return 0;
}

運行結果:
0X28FF3C, 0X28FF10

%#X表示以十六進制形式輸出,并附帶前綴0X。a 是一個變量,用來存放整數,需要在前面加&來獲得它的地址;str 本身就表示字符串的首地址,不需要加&

一切都是地址

C語言用變量來存儲數據,用函數來定義一段可以重復使用的代碼,它們最終都要放到內存中才能供 CPU 使用。

數據和代碼都以二進制的形式存儲在內存中,計算機無法從格式上區分某塊內存到底存儲的是數據還是代碼。當程序被加載到內存后,操作系統會給不同的內存塊指定不同的權限,擁有讀取和執行權限的內存塊就是代碼,而擁有讀取和寫入權限(也可能只有讀取權限)的內存塊就是數據。

CPU 只能通過地址來取得內存中的代碼和數據,程序在執行過程中會告知 CPU 要執行的代碼以及要讀寫的數據的地址。如果程序不小心出錯,或者開發者有意為之,在 CPU 要寫入數據時給它一個代碼區域的地址,就會發生內存訪問錯誤。這種內存訪問錯誤會被硬件和操作系統攔截,強制程序崩潰,程序員沒有挽救的機會。

CPU 訪問內存時需要的是地址,而不是變量名和函數名!變量名和函數名只是地址的一種助記符,當源文件被編譯和鏈接成可執行程序后,它們都會被替換成地址。編譯和鏈接過程的一項重要任務就是找到這些名稱所對應的地址。

假設變量 a、b、c 在內存中的地址分別是 0X1000、0X2000、0X3000,那么加法運算c = a + b;將會被轉換成類似下面的形式:

0X3000 = (0X1000) + (0X2000);

( )表示取值操作,整個表達式的意思是,取出地址 0X1000 和 0X2000 上的值,將它們相加,把相加的結果賦值給地址為 0X3000 的內存

變量名和函數名為我們提供了方便,讓我們在編寫代碼的過程中可以使用易于閱讀和理解的英文字符串,不用直接面對二進制地址,那場景簡直讓人崩潰。

需要注意的是,雖然變量名、函數名、字符串名和數組名在本質上是一樣的,它們都是地址的助記符,但在編寫代碼的過程中,我們認為變量名表示的是數據本身,而函數名、字符串名和數組名表示的是代碼塊或數據塊的首地址。

數據在內存中的地址也稱為指針,如果一個變量存儲了一份數據的指針,我們就稱它為指針變量。

在C語言中,允許用一個變量來存放指針,這種變量稱為指針變量。指針變量的值就是某份數據的地址,這樣的一份數據可以是數組、字符串、函數,也可以是另外的一個普通變量或指針變量。

現在假設有一個 char 類型的變量 c,它存儲了字符 'K'(ASCII碼為十進制數 75),并占用了地址為 0X11A 的內存(地址通常用十六進制表示)。另外有一個指針變量 p,它的值為 0X11A,正好等于變量 c 的地址,這種情況我們就稱 p 指向了 c,或者說 p 是指向變量 c 的指針。

定義指針變量

定義指針變量與定義普通變量非常類似,不過要在變量名前面加星號*,格式為:

datatype *name;

或者

datatype *name = value;

*表示這是一個指針變量,datatype表示該指針變量所指向的數據的類型 。例如:

  1. int *p1;

p1 是一個指向 int 類型數據的指針變量,至于 p1 究竟指向哪一份數據,應該由賦予它的值決定。再如:

  1. int a = 100;
  2. int *p_a = &a;

在定義指針變量 p_a 的同時對它進行初始化,并將變量 a 的地址賦予它,此時 p_a 就指向了 a。值得注意的是,p_a 需要的一個地址,a 前面必須要加取地址符&,否則是不對的。

和普通變量一樣,指針變量也可以被多次寫入,只要你想,隨時都能夠改變指針變量的值,請看下面的代碼:

  1. //定義普通變量
  2. float a = 99.5, b = 10.6;
  3. char c = '@', d = '#';
  4. //定義指針變量
  5. float *p1 = &a;
  6. char *p2 = &c;
  7. //修改指針變量的值
  8. p1 = &b;
  9. p2 = &d;

*是一個特殊符號,表明一個變量是指針變量,定義 p1、p2 時必須帶*。而給 p1、p2 賦值時,因為已經知道了它是一個指針變量,就沒必要多此一舉再帶上*,后邊可以像使用普通變量一樣來使用指針變量。也就是說,定義指針變量時必須帶*,給指針變量賦值時不能帶*

假設變量 a、b、c、d 的地址分別為 0X1000、0X1004、0X2000、0X2004,下面的示意圖很好地反映了 p1、p2 指向的變化:

需要強調的是,p1、p2 的類型分別是float*char*,而不是floatchar,它們是完全不同的數據類型,讀者要引起注意。

指針變量也可以連續定義,例如:

  1. int *a, *b, *c; //a、b、c 的類型都是 int*

注意每個變量前面都要帶*。如果寫成下面的形式,那么只有 a 是指針變量,b、c 都是類型為 int 的普通變量:

  1. int *a, b, c;

通過指針變量取得數據

指針變量存儲了數據的地址,通過指針變量能夠獲得該地址上的數據,格式為:

*pointer;

這里的*稱為指針運算符,用來取得某個地址上的數據,請看下面的例子:

  1. #include <stdio.h>
  2. int main(){
  3. int a = 15;
  4. int *p = &a;
  5. printf("%d, %d\n", a, *p); //兩種方式都可以輸出a的值
  6. return 0;
  7. }

運行結果:
15, 15

假設 a 的地址是 0X1000,p 指向 a 后,p 本身的值也會變為 0X1000,*p 表示獲取地址 0X1000 上的數據,也即變量 a 的值。從運行結果看,*p 和 a 是等價的。

上節我們說過,CPU 讀寫數據必須要知道數據在內存中的地址,普通變量和指針變量都是地址的助記符,雖然通過 *p 和 a 獲取到的數據一樣,但它們的運行過程稍有不同:a 只需要一次運算就能夠取得數據,而 *p 要經過兩次運算,多了一層“間接”。

假設變量 a、p 的地址分別為 0X1000、0XF0A0,它們的指向關系如下圖所示:

程序被編譯和鏈接后,a、p 被替換成相應的地址。使用 *p 的話,要先通過地址 0XF0A0 取得變量 p 本身的值,這個值是變量 a 的地址,然后再通過這個值取得變量 a 的數據,前后共有兩次運算;而使用 a 的話,可以通過地址 0X1000 直接取得它的數據,只需要一步運算。

也就是說,使用指針是間接獲取數據,使用變量名是直接獲取數據,前者比后者的代價要高。

指針除了可以獲取內存上的數據,也可以修改內存上的數據,例如:

  1. #include <stdio.h>
  2. int main(){
  3. int a = 15, b = 99, c = 222;
  4. int *p = &a; //定義指針變量
  5. *p = b; //通過指針變量修改內存上的數據
  6. c = *p; //通過指針變量獲取內存上的數據
  7. printf("%d, %d, %d, %d\n", a, b, c, *p);
  8. return 0;
  9. }

運行結果:
99, 99, 99, 99

*p 代表的是 a 中的數據,它等價于 a,可以將另外的一份數據賦值給它,也可以將它賦值給另外的一個變量。

*在不同的場景下有不同的作用:*可以用在指針變量的定義中,表明這是一個指針變量,以和普通變量區分開;使用指針變量時在前面加*表示獲取指針指向的數據,或者說表示的是指針指向的數據本身。

也就是說,定義指針變量時的*和使用指針變量時的*意義完全不同。以下面的語句為例:

  1. int *p = &a;
  2. *p = 100;

第1行代碼中*用來指明 p 是一個指針變量,第2行代碼中*用來獲取指針指向的數據。

需要注意的是,給指針變量本身賦值時不能加*。修改上面的語句:

  1. int *p;
  2. p = &a;
  3. *p = 100;

第2行代碼中的 p 前面就不能加*

指針變量也可以出現在普通變量能出現的任何表達式中,例如:

  1. int x, y, *px = &x, *py = &y;
  2. y = *px + 5; //表示把x的內容加5并賦給y,*px+5相當于(*px)+5
  3. y = ++*px; //px的內容加上1之后賦給y,++*px相當于++(*px)
  4. y = *px++; //相當于y=(*px)++
  5. py = px; //把一個指針的值賦給另一個指針


【示例】通過指針交換兩個變量的值。

  1. #include <stdio.h>
  2. int main(){
  3. int a = 100, b = 999, temp;
  4. int *pa = &a, *pb = &b;
  5. printf("a=%d, b=%d\n", a, b);
  6. /*****開始交換*****/
  7. temp = *pa; //將a的值先保存起來
  8. *pa = *pb; //將b的值交給a
  9. *pb = temp; //再將保存起來的a的值交給b
  10. /*****結束交換*****/
  11. printf("a=%d, b=%d\n", a, b);
  12. return 0;
  13. }

運行結果:
a=100, b=999
a=999, b=100

從運行結果可以看出,a、b 的值已經發生了交換。需要注意的是臨時變量 temp,它的作用特別重要,因為執行*pa = *pb;語句后 a 的值會被 b 的值覆蓋,如果不先將 a 的值保存起來以后就找不到了。

關于 * 和 & 的謎題

假設有一個 int 類型的變量 a,pa 是指向它的指針,那么*&a&*pa分別是什么意思呢?

*&a可以理解為*(&a)&a表示取變量 a 的地址(等價于 pa),*(&a)表示取這個地址上的數據(等價于 *pa),繞來繞去,又回到了原點,*&a仍然等價于 a。

&*pa可以理解為&(*pa)*pa表示取得 pa 指向的數據(等價于 a),&(*pa)表示數據的地址(等價于 &a),所以&*pa等價于 pa。

對星號*的總結

在我們目前所學到的語法中,星號*主要有三種用途:

    • 表示乘法,例如int a = 3, b = 5, c;  c = a * b;,這是最容易理解的。
    • 表示定義一個指針變量,以和普通變量區分開,例如int a = 100;  int *p = &a;
    • 表示獲取指針指向的數據,是一種間接操作,例如int a, b, *p = &a;  *p = 100;  b = *p;

 

上一篇:NUC972 linux 燒錄

下一篇:關于固件

聯系方式0755-82591179

郵箱:ivy@yingtexin.net

地址:深圳市南山區桃源街道平山社區平山一路2號南山云谷創業園二期11棟410-411

久久精品99久久_亚洲一区二区综合_狠狠色伊人亚洲综合成人_亚洲综合爱爱久久网
女人被男人躁得好爽免费视频| 黄色三级中文字幕| 免费看国产曰批40分钟| 小泽玛利亚av在线| 18视频在线观看娇喘| 一本—道久久a久久精品蜜桃| 精品999在线| 国内国产精品天干天干| 亚洲精品国产久| 天天在线免费视频| 国产精品999视频| 不卡av免费在线| www.这里只有精品| 国内自拍中文字幕| 能在线观看的av| 欧美伦理片在线观看| 艳母动漫在线免费观看| 欧美在线一区视频| 日本新janpanese乱熟| 亚洲精品综合在线观看| 黄色一级片黄色| 丰满人妻中伦妇伦精品app| 欧美一级特黄a| 99久久久精品视频| av在线无限看| 免费在线看黄色片| 亚洲综合日韩欧美| 男女啪啪免费视频网站| 高清av免费看| 草草久久久无码国产专区| 天堂视频免费看| 无码粉嫩虎白一线天在线观看| 久久国产乱子伦免费精品| 永久免费黄色片| 茄子视频成人免费观看| 久久久成人精品一区二区三区 | 人人妻人人澡人人爽欧美一区| 青青青免费在线| 老司机av福利| 精品久久久久久中文字幕2017| 视色,视色影院,视色影库,视色网| 欧美黄色免费影院| 日韩精品免费一区| 肉色超薄丝袜脚交| 高清一区在线观看| 国产高清精品在线观看| 成人小视频在线观看免费| 亚洲免费黄色录像| 国产三级三级看三级| 99精品人妻少妇一区二区| 日本xxxxx18| 一本之道在线视频| 91人人澡人人爽人人精品| 奇米影视亚洲色图| 和岳每晚弄的高潮嗷嗷叫视频| 日本三级福利片| 亚洲一级片av| 日韩av影视大全| 1314成人网| 亚洲欧美一区二区三区不卡| 超碰人人草人人| 色91精品久久久久久久久| 天天影视综合色| 9久久婷婷国产综合精品性色| 国产成人a亚洲精v品无码| 加勒比成人在线| 精品国产免费av| 日韩一级片播放| 成年网站在线播放| 亚洲色图欧美自拍| 最新av在线免费观看| 国产激情片在线观看| 成人午夜视频免费观看| 免费看国产曰批40分钟| 国产偷人视频免费| 在线观看免费的av| 五月天色婷婷综合| 人人妻人人做人人爽| 国产精品沙发午睡系列| 蜜臀视频一区二区三区| 极品粉嫩美女露脸啪啪| 激情图片qvod| 任你操这里只有精品| 视色视频在线观看| www.好吊操| 99草草国产熟女视频在线| 色91精品久久久久久久久| 三级在线免费观看| 国产午夜福利视频在线观看| 欧美美女一级片| 日日摸日日碰夜夜爽无码| 欧美亚洲日本在线观看| 51xx午夜影福利| 午夜dv内射一区二区| 300部国产真实乱| 久久久久免费精品| 欧美高清中文字幕| 婷婷免费在线观看| 国产在线青青草| 性久久久久久久久久久久久久| 欧美日韩在线一| 亚洲涩涩在线观看| 欧美a在线视频| 久久久久久久香蕉| 国产农村妇女精品久久| 日本三级免费观看| 国产精品久久久久9999爆乳| 911福利视频| 免费观看成人网| 国产精品自拍片| 国产精品无码免费专区午夜| 最新天堂在线视频| 青青青在线播放| 日本中文字幕亚洲| 国产精品av免费观看| 五月激情婷婷在线| 超碰在线人人爱| 91香蕉视频污版| 日韩视频第二页| 色欲av无码一区二区人妻| 精品国产一区二区三区无码| 久久av喷吹av高潮av| 午夜福利123| www,av在线| 久久久一二三四| 黄色污污在线观看| 亚洲小视频在线播放| 在线观看17c| 精品一区二区三区无码视频| 肉大捧一出免费观看网站在线播放| 天堂中文av在线| 国产系列第一页| 日本福利视频网站| 99久久国产综合精品五月天喷水| 欧洲精品在线播放| 男人日女人下面视频| 亚洲午夜无码av毛片久久| 欧美国产亚洲一区| 黄色片在线免费| 超碰91在线播放| 激情五月婷婷六月| 97视频在线免费播放| 在线观看的毛片| www.51色.com| 国产 欧美 日韩 一区| 国产亚洲精品网站| 手机看片一级片| 欧美 日韩 国产精品| 香港三级韩国三级日本三级| 色婷婷狠狠18| 中国一级黄色录像| 男人的天堂99| 手机在线免费毛片| 欧美综合在线播放| 中文字幕在线观看日| 精品人妻人人做人人爽| 91视频免费版污| 91免费版看片| 国产九九在线视频| 欧美极品少妇无套实战| 国产福利影院在线观看| 天堂av在线中文| 青青青在线视频免费观看| 国产手机视频在线观看| 日韩欧美在线免费观看视频| 久久99国产精品一区| 成人羞羞国产免费网站| 黄色影视在线观看| 日韩精品无码一区二区三区免费| 天天色天天干天天色| 日韩精品一区二区三区久久| 成人在线观看毛片| 久久国产这里只有精品| 日韩伦理在线免费观看| 一二三av在线| 免费看污污网站| 日韩中文字幕三区| 国产精品久久久久9999爆乳| 亚洲五月激情网| 亚洲欧美视频二区| 欧美少妇性生活视频| 日本中文字幕网址| 热久久最新地址| 九一免费在线观看| 日韩一二区视频| 婷婷中文字幕在线观看| 中文字幕国内自拍| 超碰av在线免费观看| 国产xxxxx视频| 国产精品天天av精麻传媒| 国产天堂在线播放| 黄色片一级视频| 东京热加勒比无码少妇| 欧美成人xxxxx| 日韩精品免费播放| 国内外成人免费在线视频| 亚洲综合av在线播放| theporn国产精品| 日本美女爱爱视频| 久久久久久久久久久综合|