国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C語(yǔ)言指針強(qiáng)制類(lèi)型轉(zhuǎn)換

2019-11-06 06:30:43
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

概要:

C語(yǔ)言中,任何一個(gè)變量都必須占有一個(gè)地址,而這個(gè)地址空間內(nèi)的0-1代碼就是這個(gè)變量的值。不同的數(shù)據(jù)類(lèi)型占有的空間大小不一,但是他們都必須有個(gè)地址,而這個(gè)地址就是硬件訪問(wèn)的依據(jù),而名字只是提供給程序員的一種記住這個(gè)地址的方便一點(diǎn)的方法。但是,不同的變量在機(jī)器中都是0-1代碼,所以,我們不能簡(jiǎn)單的通過(guò)檢查一個(gè)值的位來(lái)判斷它的類(lèi)型。

例如,定義如下:

int a;

 float b;

double c;

 long double d;

(假設(shè)它們所占的字節(jié)分別是4、8、8、10,而且連續(xù)存儲(chǔ)于某個(gè)地址空間,起始地址是100,則我們可以得到如下內(nèi)存分布)

a變量就是由以地址100開(kāi)始到103結(jié)束的4個(gè)字節(jié)內(nèi)存空間內(nèi)的0-1代碼組成。b變量則是由以地址104開(kāi)始到112結(jié)束的8個(gè)字節(jié)內(nèi)存空間內(nèi)的0-1代碼組成。而在機(jī)器中,這些內(nèi)存都是連續(xù)的0-1代碼,機(jī)器并不知道100~103是整型而104~111是float型,所有這些類(lèi)型都是編譯器告知的。當(dāng)我們用a時(shí),由于前面把a(bǔ)定義為int型,則編譯器知道從a的地址開(kāi)始向后取4個(gè)字節(jié)再把它解釋成int型。那么(float)a,就是先按照int類(lèi)型取出該數(shù)值,再將該數(shù)值按照int to float的規(guī)則轉(zhuǎn)換成float型。所以強(qiáng)制類(lèi)型轉(zhuǎn)換就是按照某個(gè)變量的類(lèi)型取出該變量的值,再按照***to***的規(guī)則進(jìn)行強(qiáng)制轉(zhuǎn)轉(zhuǎn)換。如果是(類(lèi)型名)常數(shù),則是將該常數(shù)按照常數(shù)to類(lèi)型 的規(guī)則進(jìn)行強(qiáng)制轉(zhuǎn)換。

指針也是一個(gè)變量,它自己占據(jù)一個(gè)4個(gè)字節(jié)的地址空間(由于程序的尋址空間是2^32次方,即4GB,所以用4個(gè)字節(jié)表示指針就已經(jīng)能指向任何程序能夠?qū)ぶ返降目臻g了,所以指針的大小為4字節(jié)),他的值是另一個(gè)東西的地址,這個(gè)東西可以是普通變量,結(jié)構(gòu)體,還可以是個(gè)函數(shù)等等。由于,指針的大小是4字節(jié),所以,我們可以將指針強(qiáng)制轉(zhuǎn)換成int型或者其他類(lèi)型。同樣,我們也可以將任何一個(gè)常數(shù)轉(zhuǎn)換成int型再賦值給指針。所有的指針?biāo)嫉目臻g大小都是4字節(jié),他們只是聲明的類(lèi)型不同,他們的值都是地址指向某個(gè)東西,他們對(duì)于機(jī)器來(lái)說(shuō)沒(méi)有本質(zhì)差別,他們之間可以進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換。指針 to 指針的強(qiáng)制類(lèi)型轉(zhuǎn)換是指將指針?biāo)傅膬?nèi)容的類(lèi)型由原先的類(lèi)型轉(zhuǎn)換為后面的類(lèi)型。

int a = 1;

int *p = &a;

float *p1 = (float*)p;

則p和p1的值都是&a,但是*p是將&a地址中的值按照int型變量進(jìn)行解釋?zhuān)?p1則是將&a地址中的值按照f(shuō)loat型變量進(jìn)行解釋。

鑒于指針之間這種靈活的強(qiáng)制類(lèi)型轉(zhuǎn)換的需求和出于簡(jiǎn)化代碼的考慮,ANSI C引入了空指針即void*。void指針又名萬(wàn)能指針,在現(xiàn)在的很多程序中,當(dāng)參數(shù)不確定時(shí)就用萬(wàn)能指針代替,這一類(lèi)的指針在線程/進(jìn)程函數(shù)里特別常見(jiàn)。

ANSI C規(guī)定,void指針可以復(fù)制給其他任意類(lèi)型的指針,其他任意類(lèi)型的指針也可以復(fù)制給void指針,他們之間復(fù)制不需要強(qiáng)制類(lèi)型轉(zhuǎn)換。當(dāng)然任何地址也可以復(fù)制給void型指針。我們?cè)凇毒W(wǎng)絡(luò)編程》中經(jīng)常會(huì)看到accept(socket, (struct sockaddr *)&saddr_c, &lenth)之類(lèi)的語(yǔ)句在&saddr_c之前需要增加代碼(struct sockaddr *)是因?yàn)楫?dāng)此函數(shù)被設(shè)計(jì)的時(shí)候ANSI C還沒(méi)有提出void*的概念。所有的地址統(tǒng)一用struct sockaddr類(lèi)型標(biāo)識(shí),該函數(shù)的第二個(gè)參數(shù)也是指向struct sockaddr類(lèi)型的指針,此處是強(qiáng)制類(lèi)型轉(zhuǎn)換。

當(dāng)然,在某些編譯器中不同類(lèi)型的指針也可以進(jìn)行直接賦值,但一般情況下會(huì)給出類(lèi)型不匹配的警告。要求程序員顯示的給出指針強(qiáng)制類(lèi)型轉(zhuǎn)換可以提醒程序員小心使用指針,對(duì)于明確程序目的具有一定的好處。

1、指針類(lèi)型強(qiáng)制轉(zhuǎn)換:

int m;

int *pm = &m;

char *cp = (char *)&m;

pm指向一個(gè)整型,cp指向整型數(shù)的第一個(gè)字節(jié)

2、結(jié)構(gòu)體之間的強(qiáng)制轉(zhuǎn)換

struct str1 a;

struct str2 b;

a=(struct str1) b;                  //this is wrong

a=*((struct str1*)&b);         //this is correct

3、關(guān)于一個(gè)程序的解釋

int main(void)

{

    int a[4] = {1, 2, 3, 4};

    int *ptr1=(int *)(&a+1);

    int *ptr2=(int *)((int)a+1);

    int *c = *(a + 1);

    PRintf("%x, %x,%x/n", ptr1[-1], *ptr2,*c);

    return 0;

}

輸出分別為4 和2000000,2

式子&a+1表示的是指針加法運(yùn)算,而不是普通的數(shù)值加法運(yùn)算

vs2008下,其中a = 0x001bfc18(&a + 1) = 0x001bfc28而 a+1 = 0x001bfc1c

 &a + 1 的值取決于a的類(lèi)型如果a申明int a;則&a + 1 = 0xFFFF5704  = a + 1如果 int a(ArryLen);則&a + 1 = 0xFFFF5700 + 4 * ArryLen <> a + 1

a 表示數(shù)組的起始地址,(int ) a 表示將a的地址轉(zhuǎn)化為一個(gè)整形數(shù),(int)a + 1 表示普通的數(shù)值加法運(yùn)算,(int *)((int)a + 1)表示把(int )a + 1轉(zhuǎn)化為整型指針的地址。該地址指向數(shù)組a(0)的第一個(gè)字節(jié)(從0計(jì)數(shù)),因?yàn)槭莍nt型的 所以需要四個(gè)字節(jié)的解釋?zhuān)越Y(jié)果是a(0)的后三個(gè)字節(jié)和a(1)的第一個(gè)字節(jié)組成的值,該值受大小端的影響。

 *(a + 1)  此時(shí)的a已經(jīng)是一個(gè)常指針了,這個(gè)表達(dá)式計(jì)算出a所指向元素后面的第2個(gè)元素的地址,然后對(duì)它解引用得到相應(yīng)的值。這個(gè)表達(dá)式等價(jià)于

int last = a[1]


上一篇:ES6 函數(shù)擴(kuò)展

下一篇:五桶油

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 南投市| 兴仁县| 南靖县| 分宜县| 同仁县| 葫芦岛市| 广灵县| 曲阳县| 皋兰县| 邹平县| 志丹县| 原平市| 临安市| 阳曲县| 勃利县| 东平县| 永新县| 罗田县| 来宾市| 古蔺县| 崇左市| 莱西市| 佳木斯市| 治多县| 延边| 漯河市| 沙田区| 奉新县| 温宿县| 宝清县| 黄石市| 靖边县| 木兰县| 新蔡县| 寿光市| 徐水县| 玉山县| 罗城| 贵定县| 漯河市| 凤山县|