溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用C++中的long long與__int64

發(fā)布時(shí)間:2021-11-03 15:10:38 來(lái)源:億速云 閱讀:612 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“怎么使用C++中的long long與__int64”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1、long long 和 __int64

C++ Primer當(dāng)中提到的64位的int只有long long,但是在實(shí)際各種各樣的C++編譯器當(dāng)中,64位的int一直有兩種標(biāo)準(zhǔn)。一種是long long,還有一種是__int64,非主流的VC甚至還支持_int64。

對(duì)于一般的C++開(kāi)發(fā)者來(lái)說(shuō),其實(shí)這個(gè)問(wèn)題不那么要緊,因?yàn)樵趯?shí)際開(kāi)發(fā)當(dāng)中,絕大多數(shù)情況使用32位的int就足夠應(yīng)付了。很少會(huì)出現(xiàn)超過(guò)int范圍的情況,但是對(duì)于算法玩家來(lái)說(shuō),這是一個(gè)必須考量的問(wèn)題。因?yàn)楹芏囝}目會(huì)故意把范圍弄得很大,考察選手對(duì)于數(shù)據(jù)范圍的敏感。

關(guān)于long long__int64,我們有非常多的問(wèn)題要討論,我們一個(gè)一個(gè)來(lái)說(shuō)。

2、歷史遺留問(wèn)題

首先是聊聊這個(gè)問(wèn)題的背景,為什么會(huì)有兩種標(biāo)準(zhǔn)呢?這并不是C++的標(biāo)準(zhǔn)不嚴(yán)謹(jǐn),或者是各大編譯器亂來(lái),背后是有一個(gè)歷史遺留問(wèn)題的。

long long最早是C99標(biāo)準(zhǔn)引進(jìn)的,然而VC6.0推出于1998年,在C99標(biāo)準(zhǔn)之前。所以當(dāng)時(shí)微軟就自己搞出來(lái)一個(gè)變量叫做__int64來(lái)表示64位整數(shù)。很多同學(xué)使用的第一個(gè)C++的編譯器就是VC6.0,所以記得在VC6.0當(dāng)中要使用__int64而非long long。

既然VC6.0搞出了__int64,那么微軟后續(xù)的C++版本顯然就必須要兼容它。所以在win系統(tǒng)當(dāng)中,這個(gè)__int64的變量類(lèi)型就一直沿用了下來(lái)。當(dāng)然,由于C++標(biāo)準(zhǔn)的更新,當(dāng)然最新的visual studio已經(jīng)支持long long了。

GCC并不是基于windows系統(tǒng)的,自然支持long long。win平臺(tái)下的一些其他IDE如dev C++ CodeBlocks等也支持long long,因?yàn)樗鼈優(yōu)榱撕臀④浀南到y(tǒng)兼容,所以也支持__int64。所以一個(gè)比較簡(jiǎn)單的區(qū)分方法是,判斷編譯器運(yùn)行的操作系統(tǒng)是否是windows,如果是windows使用__int64,否則使用long long。

3、cin、cout和scanf、printf的選擇問(wèn)題

這個(gè)問(wèn)題對(duì)于C++開(kāi)發(fā)工程師來(lái)說(shuō)同樣不是個(gè)問(wèn)題,沒(méi)有任何選擇的必要,無(wú)腦用cin、cout就完事了。但對(duì)于算法競(jìng)賽玩家來(lái)說(shuō),這依然是一個(gè)要考慮的問(wèn)題。

因?yàn)樵谒惴ǜ?jìng)賽當(dāng)中,尤其是當(dāng)數(shù)據(jù)量很大的時(shí)候,讀入和輸出占據(jù)的時(shí)間是非??捎^(guān)的??雌饋?lái)只是cin coutscanfprintf的差別,但是兩者的性能差異非常大。

我曾經(jīng)做過(guò)實(shí)驗(yàn),同樣的數(shù)據(jù),使用scanfprintf的效率大約是cin、cout的十倍以上。在小數(shù)據(jù)量的時(shí)候當(dāng)然沒(méi)有差別,但數(shù)據(jù)量很大的時(shí)候影響非常大。很有可能導(dǎo)致同樣的題目,同樣的算法,別人通過(guò)了,但是我們卻超時(shí)了的情況。

關(guān)于性能差異的原因,主要有兩種解釋。一種解釋是說(shuō)cin為了與scanf混用,而不用擔(dān)心指針混亂,加上了綁定,總是會(huì)與stdin保持同步。正是這一步操作消耗了大量的時(shí)間。同理,cout也會(huì)有類(lèi)似的問(wèn)題。第二種解釋是cout在輸出之前會(huì)把要輸出的內(nèi)容先存入緩存區(qū),中間多了一個(gè)步驟,也會(huì)帶來(lái)性能的降低。

關(guān)于cin與stdin同步帶來(lái)的開(kāi)銷(xiāo),我們是有辦法解決的,只需要在加上這一行代碼:

std::ios::sync_with_stdio(false);

這行代碼的意思是取消cin、coutstdin、stdout的指針同步,會(huì)使得cin、cout的性能大大提升,達(dá)到和scanf、printf相差無(wú)幾的程度。當(dāng)然,更好的方法是使用scanfprintf代替。

而要使用scanfprintf又有一個(gè)問(wèn)題,它們是C語(yǔ)言的標(biāo)準(zhǔn)輸入輸出方式,需要提供標(biāo)識(shí)符來(lái)代表變量的類(lèi)型,那么問(wèn)題來(lái)了long long__int64的標(biāo)識(shí)符是什么呢?

這個(gè)其實(shí)一查就知道了,long long的標(biāo)識(shí)符是lld,所以我們使用scanf讀入一個(gè)long long類(lèi)型的數(shù)寫(xiě)成:

long long a;
scanf("%lld", &a);

__int64的標(biāo)識(shí)符是I64d,注意這里是大寫(xiě)的i,不是l。

__int64 a;
scanf("%I64d", &a);

但是這里面有一個(gè)很大的坑點(diǎn),前面說(shuō)了,目前在windows平臺(tái)的編譯器已經(jīng)兼容了long long類(lèi)型。但是即便如此,在2013年之前的版本里,我們輸出的時(shí)候還是要使用%I64d,這是因?yàn)槲④浱峁┑膍svcrt.dll庫(kù)只支持%I64d的方式。相當(dāng)于從底層上斷絕了使用%lld輸出的可能。2013年微軟修復(fù)了這個(gè)問(wèn)題,添加了對(duì) %lld 的支持。

所以比較簡(jiǎn)單的區(qū)分方法就是看操作系統(tǒng),如果是windows系統(tǒng),那么一律使用__int64準(zhǔn)沒(méi)錯(cuò)。如果是linux或者是Mac系統(tǒng),那么統(tǒng)一使用long long

我在網(wǎng)上找到了大神做的總結(jié)表,也可以直接參考下表:

變量定義輸出方式gcc(mingw32)g++(mingw32)gcc(linux i386)g++(linux i386)MicrosoftVisual C++ 6.0
long long“%lld”錯(cuò)誤錯(cuò)誤正確正確無(wú)法編譯
long long“%I64d”正確正確錯(cuò)誤錯(cuò)誤無(wú)法編譯
__int64“l(fā)ld”錯(cuò)誤錯(cuò)誤無(wú)法編譯無(wú)法編譯錯(cuò)誤
__int64“%I64d”正確正確無(wú)法編譯無(wú)法編譯正確
long longcout非C++正確非C++正確無(wú)法編譯
__int64cout非C++正確非C++無(wú)法編譯無(wú)法編譯
long longprintint64()正確正確正確正確無(wú)法編譯

“怎么使用C++中的long long與__int64”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI