13 C語言提高(三)

2021-09-20 01:33:26 字數 2292 閱讀 7684

1.結構體中指標變數的深拷貝和淺拷貝

疑問點記錄:

char *p = (char *)malloc(100);

strcpy(p,"renzhenming");

這兩行**定義了乙個字元指標p,他指向堆記憶體中一段空間,這一段空間儲存了乙個字串renzhenming,那麼既然這個指標指向了這塊記憶體,那麼我通過取指標元素符號*應該就可以得到這塊記憶體中的元素了,也就是說按照猜想我列印*p

printf("%s",*p)
應該可以得到值renzhenming這個字串才對,事實上程式卻崩潰了,正確的寫法是這樣

printf("%s",p);
才能得到我們想要的結果:列印出renzhenming這個字串

為什麼?

我想很多初學者可能會有這種疑問,其實深入剖析一下你就會明白了,字元指標char *p他是指向字元的,看下邊的**

char a = 'c';

char *p=&a;

printf("%c",\*p);

這樣是可以列印出c這個字元,為什麼char *p是字元指標卻可以指向乙個字串?c語言是使用字元陣列來表示和儲存字串的,所以可以把字串和字元陣列等價起來,在陣列中,陣列名表示的就是陣列首元素的位址,那麼對字元陣列來說,陣列名表示的就是字元陣列中首個字元的位址,因為字元指標可以儲存字元的位址,那麼就可以使用字元指標來儲存字元陣列的首個字元的位址,也就是字元陣列名

也就是說

char temp[100] ="renzhenming"

和char p = "renzhenming"

表示是同乙個意思,那麼字元指標就是可以指向乙個字元陣列,也就是可以指向乙個字串。陣列名temp和p都是表示的字串renzhenming的第乙個字元 r 的位址。

那麼此時,你就會明白,為什麼p不能把整個字串列印出來了,因為*p表示的是第乙個字元r,你通過%s去接收乙個字元,會導致程式崩潰,如果你這樣列印

printf("%c",*p)
就能列印出r這個字元了。

為什麼通過%s去接收乙個字元會導致程式崩潰?

因為%s格式字串會從給定的記憶體空間開始向後逐個輸出字元,直到遇到\0結束。格式字串為%s時,後面的引數應該為乙個記憶體位址(指標),如果給出的是乙個字元變數,那麼會將字元變數中的值認作位址,例如字元變數ch中儲存的是字元'a',那麼printf會將'a'對應的ascii碼97作為記憶體位址,試圖轉到該位置讀出資料;而該位置的記憶體空間屬於作業系統,為保護段空間不可訪問,因而程式崩潰

那麼為什麼printf("%s",p)可以列印出整個字串?我們知道字串是以\0為結束標誌的,p表示字串第乙個字元的位址,當你通過%s去列印的時候,他會自動向後移動指標,直到找到\0結束符為止,將從p這個為止開始到結束符為止的字元全部列印出來,就是最終的結果了。

#define _crt_secure_no_warnings

#include #include #include typedef struct worker worker;

/* 淺拷貝

*/void lightcopy(worker *temp1, worker *temp2)

void deepcopy(worker *temp1, worker *temp2)

void main()

if (w2.alias != null)

system("pause");

}

簡單來說,深拷貝和淺拷貝針對的是指標,淺拷貝拷貝的是指標的位址值,而深拷貝是拷貝的指標指向的記憶體。

編譯器針對結構體中指向一塊堆記憶體空間的指標進行等號操作,既*p1 = *p2,操作的結果是將p2的位址拷貝到了p1上此時p2和p1指向同一塊記憶體空間。那麼此時,由於執行淺拷貝,當free空間的時候,先判斷if (w1.alias != null)滿足,則將alias指向的空間釋放,再判斷if (w2.alias != null) 仍然滿足,因為w2的alias指標和w1的alias指標並不是同乙個,但是所指向的空間是同乙個,這就導致free空間的時候由於已經被free,再次釋放發生崩潰。深拷貝則可以避免這個問題。

淺拷貝記憶體示意圖.png

深拷貝記憶體示意圖.jpg

13 C語言總結

pragma mark 第一章 c基礎 void func1 void func1 pragma mark 第二章 分支結構 void func2 void func2 printf autumn d autumn 結果 需要注意的是,列舉變數的值是上乙個值 1 autumn 5 pragma ma...

13 C 陣列和元組

如果需要使用同一型別的多個物件,陣列是一種資料結構,它包含同一型別的多個元素 一 一維陣列 1 陣列的宣告方法 int a 因為陣列是引用型別,引用型別有個特點是 宣告變數時不會馬上分配乙個記憶體,只有在用new關鍵字建立例項的時候,才會分配記憶體。2 建立乙個陣列例項 a new int 4 棧裡...

1 3 C 對C的擴充

asm bool true false wchar t namespace using class public protected private friend this inline virtual throw try catch new delete explicit mutable expo...