最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用C語言的泛型實(shí)現(xiàn)交換兩個(gè)變量值

 更新時(shí)間:2016年08月29日 16:10:04   投稿:daisy  
在日常編程里面經(jīng)常會(huì)遇到交換兩個(gè)變量的內(nèi)容的任務(wù),對(duì)于泛型類型而言有兩種泛型策略來實(shí)現(xiàn),下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)。

第一種,最常用的是創(chuàng)建一個(gè)中間變量來循環(huán)交換它們的值:

T a = ...;
T b = ...;
.
T tmp = a; a = b; a = tmp;

我們稱這種策略p99_swap1。在這里,編譯器必須嚴(yán)格實(shí)現(xiàn)三個(gè)任務(wù)的順序,否則,由此程序產(chǎn)生的結(jié)果將是不正確的。

第二種,叫它p99_swap2,試圖做類似的事情,但放松一些順序約束:

T a = ...;
T b = ...;
.
T tmpa = a; T tmpb = b;
a = tmpb; b = tmpa;

用更多的資源(??臻g或寄存器)可以產(chǎn)生更有效的代碼。兩個(gè)對(duì)象可以平行地加載和保存。但收益可能只在小對(duì)象上可以看到。所以將兩者結(jié)合起來是一個(gè)可能的嘗試

#define P99_SWAP(A, B) (sizeof(A) > sizeof(uintmax_t) ? P99_SWAP1(A, B) : P99_SWAP2(A, B))

但是如何實(shí)現(xiàn)兩個(gè) “子宏” P99_SWAP1 P99_SWAP2(A, B) ?如果我們想使用C的宏或者函數(shù)來實(shí)現(xiàn)的難度在于僅僅是傳遞參數(shù)A和B而不知道其類型,所以讓我們先寫函數(shù)和宏,忘記類型問題:

inline
void p00_swap2(void* a, void* b, void* tmpa, void* tmpb, size_t len) {
  memcpy(tmpa, a, len);
  memcpy(tmpb, b, len);
  memcpy(b, tmpa, len);
  memcpy(a, tmpb, len);
}
#define P00X_SWAP2(A, B) p00_swap2(
  &(A),                   \
  &(B),                   \
  (char[sizeof(A)]){ [0] = 0 },       \
  (char[sizeof(A)]){ [0] = 0 }, sizeof(A))

這個(gè)古怪的表達(dá)式: (char[sizeof(A)]){ [0] = 0 } 被稱為復(fù)合文字(C99新特性),為復(fù)制操作提供臨時(shí)對(duì)象。

這有幾個(gè)缺點(diǎn)。首先,我們甚至沒有檢查是否A和B與對(duì)象具有相同的大小,但我們很愉快地復(fù)制到他們。因此,首先,我們必須斷言它們至少具有相同的大小,避免引起不確定的行為。這樣就可以為兩個(gè)復(fù)合文字實(shí)現(xiàn)一些表達(dá)上的魔法:

(char[sizeof(A)]){ [(intmax_t)sizeof(A) - sizeof(B)] = 0 }

其中:intmax_t類型指定一個(gè)最大尺寸有符號(hào)整數(shù)

這里發(fā)生了什么?右邊的[]里面,一個(gè)指定的初始值,被用來初始化字符數(shù)組中的一個(gè)元素?,F(xiàn)在我們將比較兩者的大?。喝绻麅烧呦嗟龋瑒t表示位置0處的元素,如果sizeof(A) < sizeof(B) ,類型轉(zhuǎn)換 intmax_t 在編譯的期間將產(chǎn)生一個(gè)負(fù)數(shù)。

如果現(xiàn)在我們將上面的策略應(yīng)用于第二個(gè)復(fù)合文字,我們得到一個(gè)宏,在它調(diào)用兩個(gè)相同大小的對(duì)象的時(shí)候成功編譯,并在大小不同的時(shí)候在編譯期間產(chǎn)生錯(cuò)誤:

#define P00_SWAP2(A, B)
p00_swap2(                           \
   &(A),                            \
   &(B),                            \
   (char[sizeof(A)]){ [(intmax_t)sizeof(A) - sizeof(B)] = 0 }, \
   (char[sizeof(B)]){ [(intmax_t)sizeof(B) - sizeof(A)] = 0 }, \
   sizeof(A))

這現(xiàn)在已經(jīng)是更安全,但也許還不夠安全,因?yàn)檫@兩個(gè)對(duì)象可能有相同的大小,但仍然不是同一類型。我們可以做一個(gè)額外的檢查來確定這兩種類型是否是兼容的。這可以通過下面這樣的可能第一眼看起來有點(diǎn)hack

(1 ? &(A) : ((A = B), NULL))
#define P99_SWAP(A, B) (sizeof(A) > sizeof(uintmax_t) ? P99_SWAP1(A, B) : P99_SWAP2(A, B))

這里的條件總是真,所以它總是等于&(A)。第二個(gè)“假”部分在運(yùn)行時(shí)從未執(zhí)行,但只用來檢查它是否是正確的C代碼。如果A和B不會(huì)兼容,則表示不是正確的C代碼。

以上就是這篇文章的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)和工作能帶來幫助,如果有疑問可以留言交流。

相關(guān)文章

  • C語言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng)

    C語言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C語言?超詳細(xì)介紹與實(shí)現(xiàn)線性表中的無頭單向非循環(huán)鏈表

    C語言?超詳細(xì)介紹與實(shí)現(xiàn)線性表中的無頭單向非循環(huán)鏈表

    無頭單向非循環(huán)鏈表:結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來存數(shù)據(jù)。實(shí)際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多
    2022-03-03
  • 淺談關(guān)于指針作為參數(shù)并改變它的值的問題

    淺談關(guān)于指針作為參數(shù)并改變它的值的問題

    這篇文章介紹了關(guān)于指針作為參數(shù)并改變它的值的問題,有需要的朋友可以參考一下
    2013-10-10
  • C++多態(tài)特性之派生與虛函數(shù)與模板詳細(xì)介紹

    C++多態(tài)特性之派生與虛函數(shù)與模板詳細(xì)介紹

    這篇文章主要介紹了C++多態(tài)的特性派生與虛函數(shù)與模板,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • C++?std::copy與memcpy區(qū)別小結(jié)

    C++?std::copy與memcpy區(qū)別小結(jié)

    本文主要介紹了C++?std::copy與memcpy區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • 一起來了解一下C++中的指針

    一起來了解一下C++中的指針

    這篇文章主要為大家詳細(xì)介紹了C++的指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C語言逆向分析語法超詳細(xì)分析

    C語言逆向分析語法超詳細(xì)分析

    這篇文章主要介紹了C語言逆向分析語法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • 利用Qt實(shí)現(xiàn)仿QQ設(shè)置面板功能

    利用Qt實(shí)現(xiàn)仿QQ設(shè)置面板功能

    這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)仿QQ設(shè)置面板功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2022-12-12
  • C/C++ 運(yùn)用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    C/C++ 運(yùn)用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    UDP 是一種無連接、輕量級(jí)的傳輸層協(xié)議,與 TCP 相比,它不提供可靠性、流控制和錯(cuò)誤恢復(fù)機(jī)制,但卻更加簡(jiǎn)單且具有較低的開銷,這篇文章主要介紹了C/C++ 運(yùn)用Npcap發(fā)送UDP數(shù)據(jù)包,需要的朋友可以參考下
    2023-11-11
  • Qt實(shí)現(xiàn)網(wǎng)易云音樂進(jìn)度條效果

    Qt實(shí)現(xiàn)網(wǎng)易云音樂進(jìn)度條效果

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)網(wǎng)易云音樂進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08

最新評(píng)論

黄石市| 博野县| 巴南区| 颍上县| 贵阳市| 阳谷县| 东辽县| 万山特区| 漾濞| 荔浦县| 扶风县| 涿鹿县| 海门市| 沂南县| 化州市| 维西| 贵定县| 吴桥县| 苏尼特右旗| 榆树市| 铜鼓县| 济阳县| 遂平县| 宁远县| 定安县| 太康县| 武隆县| 钦州市| 呼伦贝尔市| 宽城| 华宁县| 陆良县| 河北区| 奉节县| 哈密市| 卫辉市| 兰西县| 安龙县| 临江市| 南京市| 县级市|