日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

require,memcpy


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

require,memcpy


謝邀 。這個問題和我之前發(fā)的文章有些相似,上周我在我的C語言學(xué)習(xí)圈子里簡要介紹了一個小竅門,粗略來說就是使用C語言結(jié)構(gòu)體的賦值語法,代替memcpy()語句,以精簡代碼,大致如下圖所示:有讀者看到后,認(rèn)為C語言結(jié)構(gòu)體的賦值并不等價于 memcpy,也有朋友評論說 b=a 是“淺拷貝”,還有讀者提到結(jié)構(gòu)體賦值效率沒有memcpy高,那么 b = a 語句被執(zhí)行后,究竟發(fā)生了什么呢?編寫測試C語言代碼得到答案最簡單直接的方法就是實(shí)驗(yàn),因此這里給出一段較為完整的C語言代碼,用于測試結(jié)構(gòu)體的賦值語句,如下所示 。
為了討論主題,下面C語言代碼比較精簡:上面這段C語言代碼很簡單,main() 函數(shù)定義了 3 個結(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語言程序更簡單些 。首先,輸入 gcc t.c -g 編譯上述C語言代碼,得到可執(zhí)行文件 a.out 。接著,就可以使用 gdb 調(diào)試了:首先在 main() 函數(shù)處下斷點(diǎn),然后輸入 run 命令讓C語言程序運(yùn)行起來:可以發(fā)現(xiàn)程序停在第 10 行了,此時變量 a,b,c 還沒有被賦值或者 memcpy 。
我們先看一下結(jié)構(gòu)體 s 的 size,可以直接在 gdb 環(huán)境查看:發(fā)現(xiàn) sizeof(struct s) 等于 16,這主要是因?yàn)镃語言編譯器為了提升效率,對結(jié)構(gòu)體 s 的兩個成員做了內(nèi)存對齊處理 。所以,雖然 char 型的 c 成員實(shí)際上只需 1 個字節(jié)內(nèi)存空間,但是因?yàn)槌蓡T l 占用 8 字節(jié)內(nèi)存空間,所以編譯器在 c 后面預(yù)留了 7 個字節(jié) 。
讀者 @Romi1984 認(rèn)為 C語言結(jié)構(gòu)體賦值拷貝和 memcpy 拷貝不等價,因?yàn)椤百x值的話,對齊字節(jié)不會拷貝” 。他的意思應(yīng)該是 c 后面預(yù)留的 7 個字節(jié)不會被拷貝,那是不是如此呢?在執(zhí)行 b =a; 語句之前,我們先來查看 a,b,c 在內(nèi)存里的值:能夠看出,此時變量 a,b,c 的內(nèi)存值并不完全相同 。
輸入 next 命令,使C語言程序運(yùn)行到第 16 行,也即 return 0; 語句處,此時賦值語句以及 memcpy 語句都被執(zhí)行完畢,再查看 a,b,c 的內(nèi)存值,得到如下輸出:發(fā)現(xiàn)變量 a, b, c 的值完全相同,包括結(jié)構(gòu)體 s 的 c 成員后內(nèi)存對齊的 7 個字節(jié),這說明讀者 @Romi1984 說的“對齊字節(jié)不會被拷貝”是不準(zhǔn)確的,至少就本例而言,C語言結(jié)構(gòu)體 s 的賦值拷貝和 memcpy 拷貝效果上是等價的 。
效率問題雖然通過 gdb 查看內(nèi)存值,我們發(fā)現(xiàn)C語言結(jié)構(gòu)體的賦值拷貝和 memcpy 拷貝效果是等價的,但是,讀者 @quser225816904 認(rèn)為,這兩種方式的效率是不一樣的 。那究竟是否如此呢?得到答案最直接的辦法就是衡量這兩條語句的執(zhí)行時間 。不過由于這一“執(zhí)行時間”很短,難以計量,我們采取其他方法:輸入下面的命令,查看C語言程序的匯編代碼 。
# objdump -dS a.out 從C語言程序的匯編代碼可以看出,b = a; 和 memcpy() 語句都是 4 條 mov 語句,這說明兩種拷貝方式的效率相差無幾,所以讀者 @quser225816904 的說法也是不準(zhǔn)確的 。另外,從C語言程序的匯編代碼也能更直觀的看出 b = a; 和 memcpy() 是等價的 。
讀者也可以通過多次執(zhí)行 b = a 和 memcpy 語句,對比兩種拷貝方式的效率 。“深拷貝”和“淺拷貝”前面兩位讀者分別從執(zhí)行效果和執(zhí)行效率兩個角度質(zhì)疑了C語言結(jié)構(gòu)體賦值拷貝和memcpy拷貝的等價性,也有讀者認(rèn)為賦值拷貝只是“淺拷貝”,那么究竟是否如此呢?首先,先要明白“淺拷貝”和“深拷貝”概念,這兩個概念 Java,C,js 等編程語言程序員應(yīng)該比較熟悉,在C語言中倒是不怎么常提 。

推薦閱讀