一、變量、地址、變量值
二、直接上代碼,一邊看上圖,一邊講解
#include <stdio.h>
struct Hello
{
int a;
int b;
};
int main()
{
struct Hello h;
h.a = 10;
h.b = 20;
struct Hello *hp;
hp = &h;
printf("1: h的地址是%d,hp地址是%d \n", &h, &hp);
printf("2: h的地址是%p,hp地址是%p \n", h, hp);
return 0;
}
輸出結(jié)果如下:
1: h的地址是6291096,hp地址是6290920
2: h的地址是000000140000000a,hp地址是00000000005ffe98
先看這一行
printf("1: h的地址是%d,hp地址是%d \n", &h, &hp);
都知道& 是取址符是吧,好,&h 是取h結(jié)構(gòu)體的地址,結(jié)果沒問題,參照上圖。
接著,&hp,hp是一個(gè)指針,指向了h所在的地址(hp = &h),注意:&hp是取hp變量的地址,而不是h的地址,所以打印出來的是 6290920。(printf %d是打印數(shù)字,這里輸出的是10進(jìn)制的結(jié)果)
再看第二行
printf("2: h的地址是%p,hp地址是%p \n", h, hp);
此處的 %p 是指打印指針變量的值,好,先看第二個(gè)參數(shù)hp,它本身是一個(gè)指針變量,值是 0x5ffe98,所以打印出的結(jié)果也是沒問題的。再看第一個(gè)h的打印結(jié)果,000000140000000a 這明顯是一個(gè)不太正常的結(jié)果。原因是,這里的用法有問題,h是一個(gè)結(jié)構(gòu)體,不是一個(gè)指針變量。但程序既然把h傳進(jìn)來了,就按照h存儲(chǔ)的值進(jìn)行打印,所以推斷出h處的變量值是 000000140000000a
上面的虛線框內(nèi)的邏輯是錯(cuò)的,實(shí)際不存在的。通過這個(gè)圖能表達(dá)出上面的錯(cuò)誤寫法。
回顧一下:
printf 1 中的&h、 printf 2 中的 hp,它倆是一樣的作用,結(jié)果也是對(duì)的,就是h結(jié)構(gòu)體的地址,只不過一個(gè)10進(jìn)制、一個(gè)16進(jìn)制輸出。
printf 1 中的&hp
6290920 是 hp指針變量自己的地址
printf2 中的h
000000140000000a 一看這個(gè)值是不太正常,是因?yàn)楸旧硎莻€(gè)錯(cuò)誤用法,把h這個(gè)結(jié)構(gòu)體對(duì)象當(dāng)成指針傳入 printf 了。
三、深入 &
所謂的取址運(yùn)算符,其實(shí)不準(zhǔn)確,會(huì)有誤導(dǎo)的成分在。
看代碼:
#include <stdio.h>
struct Hello
{
int a;
int b;
};
int main()
{
struct Hello h;
h.a = 10;
h.b = 20;
struct Hello harry[20];
harry[0] = h;
int address1 = &(harry[0]);
printf("address1 is:%d", address1);
return 0;
}
定義了一個(gè)Hello結(jié)構(gòu)體數(shù)組,我想取第一個(gè)元素所在的地址。以上代碼可以正常運(yùn)行,結(jié)果如下:
address1 is:6290928
但是,編譯器會(huì)在 &(harry[0]) 這里報(bào)出一個(gè)問題:
initialization of 'int' from 'struct Hello *' makes integer from pointer without a cast [-Wint-conversion]
就是說,類型不適配,為什么不適配呢?上面第一段代碼運(yùn)行時(shí),&打印出了一個(gè)10進(jìn)制的地址,這里用一個(gè)int 類型變量承接,沒問題啊。
莫非 & 的返回值類型不是 int ?
確實(shí):
在C語言中,&操作符用于獲取變量的內(nèi)存地址。它的返回值類型是 void*,即一個(gè)指向任何類型的指針。
具體來說,如果&操作符用于一個(gè)整數(shù)變量,它將返回一個(gè)指向該整數(shù)的指針。同樣地,如果它用于一個(gè)浮點(diǎn)數(shù)變量,它將返回一個(gè)指向該浮點(diǎn)數(shù)的指針。因此,&操作符的返回值類型取決于它所操作的變量類型。
需要注意的是,返回值類型為 void*,這意味著在使用返回的指針之前,通常需要將其轉(zhuǎn)換為正確的指針類型,以便正確地訪問和操作內(nèi)存地址。
正確的寫法,應(yīng)該是這樣:
struct Hello* ptr = &(harry[0]);
printf("Address of the 0 element is:%p", ptr);
使用一個(gè)指針 ptr 去承接 &的返回值,然后將指針的值打印出來,就是數(shù)組第一個(gè)元素的地址了。
就這么簡單??!
喜歡請(qǐng)關(guān)注、收藏、分享 ~(~ ̄▽ ̄)~文章來源:http://www.zghlxwxcb.cn/news/detail-782745.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-782745.html
到了這里,關(guān)于C語言 - 最簡單,最易懂的指針、引用講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!