免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
指針的一些問題

1、c++/c語言中不少地方,數(shù)組和指針可以相互替換使用,容易讓人產(chǎn)生一種錯覺,指針和數(shù)組是等價的。

數(shù)組要么在靜態(tài)存儲區(qū)域創(chuàng)建,如全局?jǐn)?shù)組;要么在棧上創(chuàng)建如函數(shù)內(nèi)的數(shù)組。數(shù)組的名稱對應(yīng)著(而不是指向)一塊內(nèi)存,它的地址和容量在其生命周期內(nèi)保持不變,數(shù)組的內(nèi)容可變。

指針可以指向任意類型的內(nèi)存塊,它的特征是可變的,所以常常用指針來操作動態(tài)內(nèi)存,指針比數(shù)組靈活,當(dāng)時容易出錯。

char a[] = "hello";a[0] = 'x';cout<<a<<endl;char *p = "world";  //這里的p指向的是常量字符串p[0] = 'x';  //編譯器不能發(fā)現(xiàn)該錯誤cout<<p;

如上邊一段代碼,a是容量為6的字符數(shù)組,a中的內(nèi)容是可以改變的,如a[0]='x'。指針p指向的是一個常量字符串“world”(位于靜態(tài)存儲區(qū)),常量字符串的內(nèi)容是不能夠被修改的。但是從語法的角度看,編譯器并不知道p[0]='x'有什么問題,但是該語句在企圖執(zhí)行時,就會出錯。

char a[] = "hello";char *p = "world"; cout<<sizeof(a)<<endl;             //6cout<<sizeof(p)<<endl;             //4cout<<sizeof(char *)<<endl;     // 4cout<<sizeof(void *)<<endl;      //4cout<<sizeof(int *)<<endl;        //4  cout<<sizeof(short *)<<endl;    //4

 

另外指針和數(shù)組的容量計算也是有區(qū)別的。以上一段代碼為例,sizeof(a)的值為6,但是sizeof(p)的值為4,這是因為sizeof(a)可以計算出數(shù)組的字節(jié)數(shù),但是sizeof(p)得到的是一個指針變量的字節(jié)數(shù),相當(dāng)于sizeof(char *),而不是p所指向的內(nèi)存容量。c++、c語言是沒有辦法知道指針?biāo)赶虻膬?nèi)存容量,除非在申請內(nèi)存時記住。

 

void test(char p[100]){    cout<<sizeof(p)<<endl;//4}

 

注意:當(dāng)數(shù)組作為函數(shù)的參數(shù)進行傳遞時,該數(shù)組自動退化為同類型的指針。如上邊的代碼,sizeof(p)的大小為4。

2、指針參數(shù)傳遞內(nèi)存

void GetMemory(char *p){    p = (char *)malloc(100);}int main(){      char *str = NULL;      GetMemory(str);      strcpy(str,"hello");      printf("%s",str);   //運行出錯      free(str);}

這段代碼運行出錯,原因出自函數(shù)Getmemory中。編譯器總是要為函數(shù)的每個參數(shù)制作臨時副本,指針參數(shù)p的副本是_p,編譯器使_p=p。如果函數(shù)體內(nèi)的程序修改了_p的內(nèi)容,就導(dǎo)致了參數(shù)p的內(nèi)容作相應(yīng)的修改。這就是指針可以用作輸出參數(shù)的原因。但是在本例中,_p申請了新的內(nèi)存,只是把_p所指向的內(nèi)存地址改變了,但是p絲毫未變。所以函數(shù)GetMemory并不能輸出任何東西,每次執(zhí)行一次GetMemory就會泄露一塊內(nèi)存。因為沒有執(zhí)行free釋放內(nèi)存。

void GetMemory2(char **p,int num){    *p = (char *)malloc(num);}

如果一定要使用指針參數(shù)去申請內(nèi)存,那么可以使用指向指針的指針,如上邊的代碼。當(dāng)然也可以使用函數(shù)返回值來傳遞動態(tài)內(nèi)存,如:

char *GetMemory3(int num){    char *p = (char *)malloc(num);    return p;  }

但是值得注意的是,我們這里使用返回值返回的是動態(tài)分配的堆內(nèi)存,不是棧內(nèi)存,如果不小心返回的是棧內(nèi)存,就會出錯,因為在函數(shù)結(jié)束時,棧內(nèi)存自動消亡了。

char *GetMemory4(){    char p[] ="hello world!"    return p;   //編譯器會發(fā)出警告  }

對上邊的程序稍作修改

char *GetMemory5(){    char *p ="hello world!"    return p;   }

這時候p指向的是字符串常量,位于靜態(tài)存儲區(qū),生命周期恒定不變,那么此時返回的是一個只讀的內(nèi)存塊。

 

3、結(jié)構(gòu)體的存儲分配

struct Align1{       int a;       char b;       char c;};struct Align2{       char b;       int a;       char c;};

如上邊所示兩個結(jié)構(gòu)體的數(shù)據(jù)元素一樣,但是位置順序不同,那么他們占用的內(nèi)存大小不同。在32位機器中整型4個字節(jié),并且他的起始存儲位置必須能夠被4整除。所以以上兩個結(jié)構(gòu)體在內(nèi)存中分配如圖所示

編譯器按照成員列表的順序一個接著一個的給每個成員分配內(nèi)存。只有當(dāng)成員之間滿足正確的對齊要求時,成員之間才會出現(xiàn)用于填充的額外內(nèi)存空間。有些時候,我們有充分的理由決定不對數(shù)據(jù)結(jié)構(gòu)成員進行重排,減少因邊界對齊帶來的空間損失。例如,我們可能想把相關(guān)的結(jié)構(gòu)成員存儲到一起,提高程序的可維護性和可讀性。但是,如果不存在這樣的理由,結(jié)構(gòu)成員應(yīng)該根據(jù)他們的邊界進行重排,減少因為邊界對齊而造成的內(nèi)存損失。當(dāng)程序創(chuàng)建幾百個甚至上千個結(jié)構(gòu)時,減少內(nèi)存浪費的要求就比程序的可讀性更為緊迫了。在這種情況下,在聲明中增加注釋可以彌補可讀性方面的損失。

運行結(jié)果:

 

 

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
【c++】指針參數(shù)是如何傳遞內(nèi)存的
指針參數(shù)是如何傳遞內(nèi)存的
又被C/C 的內(nèi)存坑了?5個黃金規(guī)則請謹(jǐn)記!
C 內(nèi)存管理詳解
指針數(shù)組,數(shù)組指針,指針函數(shù),函數(shù)指針,二級指針詳解
常見筆試/面試題目(四)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服