成人AV在线无码|婷婷五月激情色,|伊人加勒比二三四区|国产一区激情都市|亚洲AV无码电影|日av韩av无码|天堂在线亚洲Av|无码一区二区影院|成人无码毛片AV|超碰在线看中文字幕

c語言動(dòng)態(tài)結(jié)構(gòu)體分配內(nèi)存 1.C語言結(jié)構(gòu)體類型變量在程序執(zhí)行期間?

1.C語言結(jié)構(gòu)體類型變量在程序執(zhí)行期間?B因?yàn)樗袛?shù)據(jù)存起來在使用時(shí)調(diào)用哪一個(gè),根據(jù)條件查找到就在內(nèi)存中駐留 C語言常見數(shù)據(jù)類型有哪些?英文方式如何表示?并分別說出它們所占的內(nèi)存長(zhǎng)度?字符型 char

1.C語言結(jié)構(gòu)體類型變量在程序執(zhí)行期間?

B

因?yàn)樗袛?shù)據(jù)存起來

在使用時(shí)調(diào)用哪一個(gè),根據(jù)條件查找到

就在內(nèi)存中駐留

C語言常見數(shù)據(jù)類型有哪些?英文方式如何表示?并分別說出它們所占的內(nèi)存長(zhǎng)度?

字符型 char 1 字節(jié)

整型 int 2 字節(jié)

長(zhǎng)整型 long 4 字節(jié)

單精度 float 4 字節(jié)

雙精度 double 8 字節(jié)

這是在TURBO C 里面的

在VC 里為了方便都是4個(gè)字節(jié) 也就是一個(gè)字長(zhǎng)

還有

結(jié)構(gòu)體struct、聯(lián)合體union 內(nèi)存由結(jié)構(gòu)體中數(shù)據(jù)決定。

C語言中復(fù)制一個(gè)結(jié)構(gòu)體只能使用memcpy的方法嗎?感覺有些麻煩,有別的方法嗎?

謝邀。

這個(gè)問題和我之前發(fā)的文章有些相似,上周我在我的C語言學(xué)習(xí)圈子里簡(jiǎn)要介紹了一個(gè)小竅門,粗略來說就是使用C語言結(jié)構(gòu)體的賦值語法,代替memcpy()語句,以精簡(jiǎn)代碼,大致如下圖所示:

有讀者看到后,認(rèn)為C語言結(jié)構(gòu)體的賦值并不等價(jià)于 memcpy,也有朋友評(píng)論說 ba 是“淺拷貝”,還有讀者提到結(jié)構(gòu)體賦值效率沒有memcpy高,那么 b a 語句被執(zhí)行后,究竟發(fā)生了什么呢?

編寫測(cè)試C語言代碼得到答案最簡(jiǎn)單直接的方法就是實(shí)驗(yàn),因此這里給出一段較為完整的C語言代碼,用于測(cè)試結(jié)構(gòu)體的賦值語句,如下所示。為了討論主題,下面C語言代碼比較精簡(jiǎn):

上面這段C語言代碼很簡(jiǎn)單,main() 函數(shù)定義了 3 個(gè)結(jié)構(gòu)體變量 a, b, c,其中 a 被初始化為 {3, 5},并通過賦值語句拷貝給 b,memcpy() 拷貝給 c??疾?a,b,c 占用的內(nèi)存里的值,從最終“拷貝效果”上分析賦值語句和memcpy()的異同。

查看內(nèi)存值查看上述C語言程序中的變量 a, b, c 的值方法很多,最直接的方法就是使用 printf() 函數(shù)逐字節(jié)打印,不過這樣就略顯繁瑣了,使用 GDB 工具調(diào)試C語言程序更簡(jiǎn)單些。

首先,輸入 gcc t.c -g 編譯上述C語言代碼,得到可執(zhí)行文件 a.out。接著,就可以使用 gdb 調(diào)試了:

首先在 main() 函數(shù)處下斷點(diǎn),然后輸入 run 命令讓C語言程序運(yùn)行起來:

可以發(fā)現(xiàn)程序停在第 10 行了,此時(shí)變量 a,b, c 還沒有被賦值或者 memcpy。我們先看一下結(jié)構(gòu)體 s 的 size,可以直接在 gdb 環(huán)境查看:

發(fā)現(xiàn) sizeof(struct s) 等于 16,這主要是因?yàn)镃語言編譯器為了提升效率,對(duì)結(jié)構(gòu)體 s 的兩個(gè)成員做了內(nèi)存對(duì)齊處理。所以,雖然 char 型的 c 成員實(shí)際上只需 1 個(gè)字節(jié)內(nèi)存空間,但是因?yàn)槌蓡T l 占用 8 字節(jié)內(nèi)存空間,所以編譯器在 c 后面預(yù)留了 7 個(gè)字節(jié)。

讀者 @Romi1984 認(rèn)為 C語言結(jié)構(gòu)體賦值拷貝和 memcpy 拷貝不等價(jià),因?yàn)椤百x值的話,對(duì)齊字節(jié)不會(huì)拷貝”。他的意思應(yīng)該是 c 后面預(yù)留的 7 個(gè)字節(jié)不會(huì)被拷貝,那是不是如此呢?在執(zhí)行 b a 語句之前,我們先來查看 a,b,c 在內(nèi)存里的值:

能夠看出,此時(shí)變量 a,b,c 的內(nèi)存值并不完全相同。輸入 next 命令,使C語言程序運(yùn)行到第 16 行,也即 return 0 語句處,此時(shí)賦值語句以及 memcpy 語句都被執(zhí)行完畢,再查看 a,b,c 的內(nèi)存值,得到如下輸出:

發(fā)現(xiàn)變量 a, b, c 的值完全相同,包括結(jié)構(gòu)體 s 的 c 成員后內(nèi)存對(duì)齊的 7 個(gè)字節(jié),這說明讀者 @Romi1984 說的“對(duì)齊字節(jié)不會(huì)被拷貝”是不準(zhǔn)確的,至少就本例而言,C語言結(jié)構(gòu)體 s 的賦值拷貝和 memcpy 拷貝效果上是等價(jià)的。

效率問題

雖然通過 gdb 查看內(nèi)存值,我們發(fā)現(xiàn)C語言結(jié)構(gòu)體的賦值拷貝和 memcpy 拷貝效果是等價(jià)的,但是,讀者 @quser225816904 認(rèn)為,這兩種的效率是不一樣的。

那究竟是否如此呢?得到答案最直接的辦法就是衡量這兩條語句的執(zhí)行時(shí)間。不過由于這一“執(zhí)行時(shí)間”很短,難以計(jì)量,我們采取其他方法:輸入下面的命令,查看C語言程序的匯編代碼。

# objdump -dS a.out

從C語言程序的匯編代碼可以看出,b a 和 memcpy() 語句都是 4 條 mov 語句,這說明兩種拷貝的效率相差無幾,所以讀者 @quser225816904 的說法也是不準(zhǔn)確的。另外,從C語言程序的匯編代碼也能更直觀的看出 b a 和 memcpy() 是等價(jià)的。

讀者也可以通過多次執(zhí)行 b a 和 memcpy 語句,對(duì)比兩種拷貝的效率。

“深拷貝”和“淺拷貝”前面兩位讀者分別從執(zhí)行效果和執(zhí)行效率兩個(gè)角度質(zhì)疑了C語言結(jié)構(gòu)體賦值拷貝和memcpy拷貝的等價(jià)性,也有讀者認(rèn)為賦值拷貝只是“淺拷貝”,那么究竟是否如此呢?

首先,先要明白“淺拷貝”和“深拷貝”概念,這兩個(gè)概念 Java,C ,js 等編程語言程序員應(yīng)該比較熟悉,在C語言中倒是不怎么常提。細(xì)究這兩個(gè)概念的區(qū)別并不是本文的重點(diǎn),所以這里粗略的對(duì)“淺拷貝”和“深拷貝”做如下區(qū)分,對(duì)于把變量 a 拷貝給 b:

如果拷貝后,b 的內(nèi)容完全等于 a,并且兩個(gè)變量在內(nèi)存中是獨(dú)立的,則稱此次拷貝為“深拷貝”。如果靠背后,只是通過 b 能夠訪問 a 中的內(nèi)容,a 的內(nèi)容改變時(shí),b 的“內(nèi)容”也隨之改變,則稱此次拷貝為“淺拷貝”。

這樣看來,就本例而言,b a;顯然是一次“深拷貝”,因?yàn)?a, b 在內(nèi)存中彼此獨(dú)立,并且拷貝后,b 的內(nèi)容和 a 的內(nèi)容完全相同。那C語言的結(jié)構(gòu)體賦值拷貝一定是“深拷貝”嗎?我們將結(jié)構(gòu)體 s 新增一個(gè)指針成員 buf:

對(duì) a 的初始化也做相應(yīng)修改,相關(guān)C語言代碼如下,請(qǐng)看:

為了討論主題,上述C語言代碼沒有做錯(cuò)誤處理?,F(xiàn)在 b a 還是“深拷貝”嗎?讀者如果做了實(shí)驗(yàn),應(yīng)該會(huì)發(fā)現(xiàn),b 的 buf 成員本身在內(nèi)存中的確獨(dú)立于 a 的 buf 成員,但是它指向的內(nèi)存卻與 a 的 buf 成員指向的內(nèi)存是同一塊,所以這時(shí) b a 不再是純粹的“深拷貝”了。

小結(jié)本節(jié)主要討論了C語言結(jié)構(gòu)體的賦值語法可以用于拷貝,并針對(duì)之前讀者的幾個(gè)典型問題做了較為詳細(xì)的實(shí)例探討。不過,C語言是一門非常靈活的編程語言,可能同樣的一條語句,在不同的環(huán)境下執(zhí)行結(jié)果是不一樣的,這一點(diǎn)本文最后的討論就是一個(gè)實(shí)例。應(yīng)該明白,本文舉的例子僅是為了拋磚引玉,展示遇到問題該如何分析的方法,學(xué)習(xí)C語言,應(yīng)該樂于做實(shí)驗(yàn)嘗試才對(duì)。

歡迎在評(píng)論區(qū)一起討論,質(zhì)疑。文章都是手打原創(chuàng),每天最淺顯的介紹C語言、linux等嵌入式開發(fā),喜歡我的文章就關(guān)注一波吧,可以看到最新更新和之前的文章哦。