麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > C > 正文

帶你了解C語(yǔ)言的指針

2020-02-24 14:24:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

對(duì)于C語(yǔ)言指針是不是很多小伙伴們都不了解呢?我們?cè)诹私庵羔樀臅r(shí)候多多少少會(huì)有一些比較復(fù)雜的,那么下面就讓武林小編帶你了解C語(yǔ)言的指針吧,希望本文內(nèi)容對(duì)你有所幫助。

指針、引用和取值

什么是指針?什么是內(nèi)存地址?什么叫做指針的取值?指針是一個(gè)存儲(chǔ)計(jì)算機(jī)內(nèi)存地址的變量。在這份教程里“引用”表示計(jì)算機(jī)內(nèi)存地址。從指針指向的內(nèi)存讀取數(shù)據(jù)稱作指針的取值。指針可以指向某些具體類(lèi)型的變量地址,例如int、long和double。指針也可以是void類(lèi)型、NULL指針和未初始化指針。本文會(huì)對(duì)上述所有指針類(lèi)型進(jìn)行探討。

根據(jù)出現(xiàn)的位置不同,操作符 * 既可以用來(lái)聲明一個(gè)指針變量,也可以用作指針的取值。當(dāng)用在聲明一個(gè)變量時(shí),*表示這里聲明了一個(gè)指針。其它情況用到*表示指針的取值。

&是地址操作符,用來(lái)引用一個(gè)內(nèi)存地址。通過(guò)在變量名字前使用&操作符,我們可以得到該變量的內(nèi)存地址。

?

?

// 聲明一個(gè)int指針
int *ptr;
// 聲明一個(gè)int值
int val = 1;
// 為指針?lè)峙湟粋€(gè)int值的引用
ptr = &val;
// 對(duì)指針進(jìn)行取值,打印存儲(chǔ)在指針地址中的內(nèi)容
int deref = *ptr;
printf("%d/n", deref);

?

第2行,我們通過(guò)*操作符聲明了一個(gè)int指針。接著我們聲明了一個(gè)int變量并賦值為1。然后我們用int變量的地址初始化我們的int指針。接下來(lái)對(duì)int指針取值,用變量的內(nèi)存地址初始化int指針。最終,我們打印輸出變量值,內(nèi)容為1。

第6行的&val是一個(gè)引用。在val變量聲明并初始化內(nèi)存之后,通過(guò)在變量名之前使用地址操作符&我們可以直接引用變量的內(nèi)存地址。

第8行,我們?cè)僖淮问褂?操作符來(lái)對(duì)該指針取值,可直接獲得指針指向的內(nèi)存地址中的數(shù)據(jù)。由于指針聲明的類(lèi)型是int,所以取到的值是指針指向的內(nèi)存地址存儲(chǔ)的int值。

這里可以把指針、引用和值的關(guān)系類(lèi)比為信封、郵箱地址和房子。一個(gè)指針就好像是一個(gè)信封,我們可以在上面填寫(xiě)郵寄地址。一個(gè)引用(地址)就像是一個(gè)郵件地址,它是實(shí)際的地址。取值就像是地址對(duì)應(yīng)的房子。我們可以把信封上的地址擦掉,寫(xiě)上另外一個(gè)我們想要的地址,但這個(gè)行為對(duì)房子沒(méi)有任何影響。

void指針、NULL指針和未初始化指針

一個(gè)指針可以被聲明為void類(lèi)型,比如void *x。一個(gè)指針可以被賦值為NULL。一個(gè)指針變量聲明之后但沒(méi)有被賦值,叫做未初始化指針。

?

int *uninit; // int指針未初始化
int *nullptr = NULL; // 初始化為NULL
void *vptr; // void指針未初始化
int val = 1;
int *iptr;
int *castptr;
?
// void類(lèi)型可以存儲(chǔ)任意類(lèi)型的指針或引用
iptr = &val;
vptr = iptr;
printf("iptr=%p, vptr=%p/n", iptr, vptr);
?
// 通過(guò)顯示轉(zhuǎn)換,我們可以把一個(gè)void指針轉(zhuǎn)成
// int指針并進(jìn)行取值
castptr = (int *)vptr;
printf("*castptr=%d/n", *castptr);
?
// 打印null和未初始化指針
printf("uninit=%p, nullptr=%p/n", uninit, nullptr);
// 不知道你會(huì)得到怎樣的返回值,會(huì)是隨機(jī)的垃圾地址嗎?
// printf("*nullptr=%d/n", nullptr);
// 這里會(huì)產(chǎn)生一個(gè)段錯(cuò)誤
// printf("*nullptr=%d/n", nullptr);

?

執(zhí)行上面的代碼,你會(huì)得到類(lèi)似下面對(duì)應(yīng)不同內(nèi)存地址的輸出。

?

?

iptr=0x7fff94b89c6c, vptr=0x7fff94b89c6c
*castptr=1
uninit=0x7fff94b89d50, nullptr=(nil)

?

第1行我們聲明了一個(gè)未初始化int指針。所有的指針在賦值為NULL、一個(gè)引用(地址)或者另一個(gè)指針之前都是未被初始化的。第2行我們聲明了一個(gè)NULL指針。第3行聲明了一個(gè)void指針。第4行到第6行聲明了一個(gè)int值和幾個(gè)int指針。

第9行到11行,我們?yōu)閕nt指針賦值為一個(gè)引用并把int指針賦值為void指針。void指針可以保存各種其它指針類(lèi)型。大多數(shù)時(shí)候它們被用來(lái)存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)。可以注意到,第11行我們打印了int和void指針的地址。它們現(xiàn)在指向了同樣的內(nèi)存地址。所有的指針都存儲(chǔ)了內(nèi)存地址。它們的類(lèi)型只在取值時(shí)起作用。

第15到16行,我們把void指針轉(zhuǎn)換為int指針castptr。請(qǐng)注意這里需要顯示轉(zhuǎn)換。雖然C語(yǔ)言并不要求顯示地轉(zhuǎn)換,但這樣會(huì)增加代碼的可讀性。接著我們對(duì)castptr指針取值,值為1。

第19行非常有意思,在這里打印未初始化指針和NULL指針。值得注意的是,未初始化指針是有內(nèi)存地址的,而且是一個(gè)垃圾地址。不知道這個(gè)內(nèi)存地址指向的值是什么。這就是為什么不要對(duì)未初始化指針取值的原因。最好的情況是你取到的是垃圾地址接下來(lái)你需要對(duì)程序進(jìn)行調(diào)試,最壞的情況則會(huì)導(dǎo)致程序崩潰。

NULL指針被初始化為o。NULL是一個(gè)特殊的地址,用NULL賦值的指針指向的地址為0而不是隨機(jī)的地址。只有當(dāng)你準(zhǔn)備使用這個(gè)地址時(shí)有效。不要對(duì)NULL地址取值,否則會(huì)產(chǎn)生段錯(cuò)誤。

指針和數(shù)組

C語(yǔ)言的數(shù)組表示一段連續(xù)的內(nèi)存空間,用來(lái)存儲(chǔ)多個(gè)特定類(lèi)型的對(duì)象。與之相反,指針用來(lái)存儲(chǔ)單個(gè)內(nèi)存地址。數(shù)組和指針不是同一種結(jié)構(gòu)因此不可以互相轉(zhuǎn)換。而數(shù)組變量指向了數(shù)組的第一個(gè)元素的內(nèi)存地址。

一個(gè)數(shù)組變量是一個(gè)常量。即使指針變量指向同樣的地址或者一個(gè)不同的數(shù)組,也不能把指針賦值給數(shù)組變量。也不可以將一個(gè)數(shù)組變量賦值給另一個(gè)數(shù)組。然而,可以把一個(gè)數(shù)組變量賦值給指針,這一點(diǎn)似乎讓人感到費(fèi)解。把數(shù)組變量賦值給指針時(shí),實(shí)際上是把指向數(shù)組第一個(gè)元素的地址賦給指針。

?

?

int myarray[4] = {1,2,3,0};
int *ptr = myarray;
printf("*ptr=%d/n", *ptr);
?
// 數(shù)組變量是常量,不能做下面的賦值
// myarray = ptr
// myarray = myarray2
// myarray = &myarray2[0]

?

第1行初始化了一個(gè)int數(shù)組,第2行用數(shù)組變量初始化了一個(gè)int指針。由于數(shù)組變量實(shí)際上是第一個(gè)元素的地址,因此我們可以把這個(gè)地址賦值給指針。這個(gè)賦值與int *ptr = &myarray[0]效果相同,顯示地把數(shù)組的第一個(gè)元素地址賦值到了ptr引用。這里需要注意的是,這里指針需要和數(shù)組的元素類(lèi)型保持一致,除非指針類(lèi)型為void。

指針與結(jié)構(gòu)體

就像數(shù)組一樣,指向結(jié)構(gòu)體的指針存儲(chǔ)了結(jié)構(gòu)體第一個(gè)元素的內(nèi)存地址。與數(shù)組指針一樣,結(jié)構(gòu)體的指針必須聲明和結(jié)構(gòu)體類(lèi)型保持一致,或者聲明為void類(lèi)型。

?

?

struct person {
? int age;
? char *name;
};
struct person first;
struct person *ptr;
?
first.age = 21;
char *fullname = "full name";
first.name = fullname;
ptr = &first;
?
printf("age=%d, name=%s/n", first.age, ptr->name);

?

第1至6行聲明了一個(gè)person結(jié)構(gòu)體,一個(gè)變量指向了一個(gè)person結(jié)構(gòu)體和指向person結(jié)構(gòu)體的指針。第8行為age成員賦了一個(gè)int值。第9至10行我們聲明了一個(gè)char指針并賦值給一個(gè)char數(shù)組并賦值給結(jié)構(gòu)體name成員。第11行我們把一個(gè)person結(jié)構(gòu)體引用賦值給結(jié)構(gòu)體變量。

第13行我們打印了結(jié)構(gòu)體實(shí)例的age和name。這里需要注意兩個(gè)不同的符號(hào),'.' 和 ‘->' 。結(jié)構(gòu)體實(shí)例可以通過(guò)使用 ‘.' 符號(hào)訪問(wèn)age變量。對(duì)于結(jié)構(gòu)體實(shí)例的指針,我們可以通過(guò) ‘->' 符號(hào)訪問(wèn)name變量。也可以同樣通過(guò)(*ptr).name來(lái)訪問(wèn)name變量。

上文中小編帶你了解C語(yǔ)言的指針之后你是否明白了呢?希望這份簡(jiǎn)短的概述能夠有助于了解不同的指針類(lèi)型。在后續(xù)的博文中我們會(huì)探討其它類(lèi)型的指針和高級(jí)用法。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 久久久久亚洲美女啪啪 | wwwxxx视频 | 一区二区高清视频在线观看 | 亚洲午夜免费 | 日日草夜夜 | 欧美激情性色生活片在线观看 | 日本成人一区二区 | 99成人在线 | 国产九色在线观看 | 色欧美视频 | 日韩午夜片 | 欧美色另类 | 激情小视频在线观看 | 一级黄片毛片免费看 | 亚洲欧美一区二区三区在线观看 | 日韩在线毛片 | 素人视频在线观看免费 | 麻豆视频国产在线观看 | 国产激情精品一区二区三区 | 久久久三级免费电影 | 国产91九色| 一区二区三区视频在线观看 | 精品一区二区三区四区在线 | 欧美成人免费小视频 | 欧美老外a级毛片 | 99麻豆久久久国产精品免费 | 久久精品com| 成人免费在线观看视频 | 国产免费永久在线观看 | 久久久综 | 一级大片久久 | 久久久久国产成人精品亚洲午夜 | 羞羞视频免费入口网站 | 男男啪羞羞视频网站 | 精品成人网 | 免费国产 | 久久精品视频一区二区三区 | 手机国产乱子伦精品视频 | 99影视在线视频免费观看 | 嫩草91在线 | 欧美aⅴ视频|