7 回答

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超11個(gè)贊
無(wú) ; 你沒(méi)有投射結(jié)果,因?yàn)椋?/p>
這是不必要的,因?yàn)?code>void *在這種情況下自動(dòng)且安全地提升到任何其他指針類(lèi)型。
它增加了代碼的混亂,轉(zhuǎn)換不是很容易閱讀(特別是如果指針類(lèi)型很長(zhǎng))。
它讓你重復(fù)自己,這通常很糟糕。
如果您忘記包含,它可以隱藏錯(cuò)誤
<stdlib.h>
。這可能會(huì)導(dǎo)致崩潰(或更糟的是,不導(dǎo)致崩潰,直到方式在后面的代碼的一些完全不同的部分)??紤]如果指針和整數(shù)的大小不同會(huì)發(fā)生什么; 那么你通過(guò)強(qiáng)制轉(zhuǎn)換隱藏了一個(gè)警告,可能會(huì)丟失你返回的地址。注意:從C11開(kāi)始,隱式函數(shù)從C中消失,并且這一點(diǎn)不再相關(guān),因?yàn)闆](méi)有自動(dòng)假設(shè)未聲明的函數(shù)返回int
。
作為澄清,請(qǐng)注意我說(shuō)“你不投”,而不是“你不需要投”。在我看來(lái),即使你做對(duì)了也沒(méi)有包括演員。這樣做沒(méi)有任何好處,但是一堆潛在的風(fēng)險(xiǎn),包括演員表明你不知道風(fēng)險(xiǎn)。
還要注意,正如評(píng)論員指出的那樣,上面談的是直C,而不是C ++。我非常堅(jiān)信C和C ++是不同的語(yǔ)言。
要進(jìn)一步添加,您的代碼會(huì)不必要地重復(fù)int
可能導(dǎo)致錯(cuò)誤的類(lèi)型信息()。最好取消引用用于存儲(chǔ)返回值的指針,將兩者“鎖定”在一起:
int *sieve = malloc(length * sizeof *sieve);
這也會(huì)移動(dòng)length
到前面以增加可見(jiàn)性,并刪除多余的括號(hào)sizeof
; 只有在參數(shù)是類(lèi)型名稱(chēng)時(shí)才需要它們。許多人似乎不知道(或忽略)這一點(diǎn),這使得他們的代碼更加冗長(zhǎng)。記?。?code>sizeof不是功能!:)
雖然移動(dòng)length
到前面可能會(huì)增加在某些極少數(shù)情況下的可見(jiàn)性,但是在一般情況下,應(yīng)該注意將表達(dá)式編寫(xiě)為:
int *sieve = malloc(sizeof *sieve * length);
因?yàn)?code>sizeof在這種情況下保持第一個(gè),所以確保乘法至少用size_t
數(shù)學(xué)來(lái)完成。
比較:malloc(sizeof *sieve * length * width)
與malloc(length * width * sizeof *sieve)
第二個(gè)可能溢出的length * width
時(shí)間width
和length
比較小的類(lèi)型size_t
。

TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊
在C中,您不需要轉(zhuǎn)換返回值malloc
。返回的void指針malloc
自動(dòng)轉(zhuǎn)換為正確的類(lèi)型。但是,如果您希望使用C ++編譯器編譯代碼,則需要進(jìn)行強(qiáng)制轉(zhuǎn)換。社區(qū)中的首選替代方案是使用以下內(nèi)容:
int *sieve = malloc(sizeof *sieve * length);
如果你改變了類(lèi)型,你還可以免去擔(dān)心改變表達(dá)式的右側(cè)sieve
。
人們已經(jīng)指出,演員陣容很糟糕。特別是指針轉(zhuǎn)換。

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
你做演員,因?yàn)椋?/p>
它使您的代碼在C和C ++之間更具可移植性,并且正如SO經(jīng)驗(yàn)所示,許多程序員聲稱(chēng)他們?cè)谟肅 ++(或C加本地編譯器擴(kuò)展)編寫(xiě)時(shí)正在用C語(yǔ)言編寫(xiě)。
如果不這樣做可以隱藏錯(cuò)誤:注意所有的混亂的SO例子,當(dāng)寫(xiě)
type *
對(duì)type **
。它讓你不會(huì)注意到你沒(méi)有找到
#include
合適的頭文件的想法錯(cuò)過(guò)了森林的樹(shù)木。這就像說(shuō)“不要擔(dān)心你沒(méi)有要求編譯器抱怨沒(méi)有看到原型這一事實(shí) - 那令人討厭的stdlib.h是真正重要的事情要記??!”它強(qiáng)制進(jìn)行額外的認(rèn)知交叉檢查。它將(聲稱(chēng)的)所需類(lèi)型放在您正在為該變量的原始大小進(jìn)行的算術(shù)旁邊。我敢打賭你可以做一個(gè)SO研究,它表明
malloc()
當(dāng)有一個(gè)演員時(shí),bug會(huì)被抓得更快。與斷言一樣,顯示意圖的注釋可以減少錯(cuò)誤。以機(jī)器可以檢查的方式重復(fù)自己通常是一個(gè)好主意。事實(shí)上,這就是一個(gè)斷言,并且使用強(qiáng)制轉(zhuǎn)換是一種斷言。斷言仍然是我們獲得正確代碼的最常用技術(shù),因?yàn)閳D靈在很多年前提出了這個(gè)想法。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
正如其他人所說(shuō),C不是必需的,而是C ++。如果您認(rèn)為要使用C ++編譯器編譯C代碼,出于某種原因,您可以使用宏,例如:
#ifdef __cplusplus# define NEW(type, count) ((type *)calloc(count, sizeof(type)))#else# define NEW(type, count) (calloc(count, sizeof(type)))#endif
這樣你仍然可以以非常緊湊的方式編寫(xiě)它:
int *sieve = NEW(int, 1);
它將為C和C ++編譯。

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個(gè)贊
在C中,您可以隱式地將void指針轉(zhuǎn)換為任何其他類(lèi)型的指針,因此不需要強(qiáng)制轉(zhuǎn)換。使用一個(gè)人可能會(huì)向不經(jīng)意的觀察者建議,有一些理由需要一個(gè),這可能會(huì)產(chǎn)生誤導(dǎo)。

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
你沒(méi)有強(qiáng)制轉(zhuǎn)換malloc的結(jié)果,因?yàn)檫@樣做會(huì)給你的代碼帶來(lái)無(wú)意義的混亂。
人們投射malloc結(jié)果的最常見(jiàn)原因是因?yàn)樗麄儾淮_定C語(yǔ)言是如何工作的。這是一個(gè)警告信號(hào):如果您不知道特定語(yǔ)言機(jī)制的工作原理,那么請(qǐng)不要猜測(cè)。查找或詢(xún)問(wèn)Stack Overflow。
一些評(píng)論:
可以將void指針轉(zhuǎn)換為/從任何其他指針類(lèi)型轉(zhuǎn)換而不進(jìn)行顯式轉(zhuǎn)換(C11 6.3.2.3和6.5.16.1)。
但是,C ++不允許在
void*
另一個(gè)指針類(lèi)型之間進(jìn)行隱式轉(zhuǎn)換。所以在C ++中,演員陣容是正確的。但是如果你用C ++編程,你應(yīng)該使用new
而不是malloc()。而且你永遠(yuǎn)不應(yīng)該使用C ++編譯器編譯C代碼。如果需要使用相同的源代碼同時(shí)支持C和C ++,請(qǐng)使用編譯器開(kāi)關(guān)來(lái)標(biāo)記差異。不要嘗試使用相同的代碼來(lái)區(qū)分兩種語(yǔ)言標(biāo)準(zhǔn),因?yàn)樗鼈儾患嫒荨?/p>
如果C編譯器由于忘記包含頭而無(wú)法找到函數(shù),那么您將收到編譯器/鏈接器錯(cuò)誤。因此,如果您忘記包含
<stdlib.h>
那些沒(méi)什么大不了的話,那么您將無(wú)法構(gòu)建您的程序。對(duì)于遵循超過(guò)25年的標(biāo)準(zhǔn)版本的古代編譯器,忘記包含
<stdlib.h>
將導(dǎo)致危險(xiǎn)的行為。因?yàn)樵谀莻€(gè)古老的標(biāo)準(zhǔn)中,沒(méi)有可見(jiàn)原型的函數(shù)隱式地將返回類(lèi)型轉(zhuǎn)換為int
。然后顯式地從malloc轉(zhuǎn)換結(jié)果將隱藏此錯(cuò)誤。但這確實(shí)不是問(wèn)題。您沒(méi)有使用25年的計(jì)算機(jī),那么為什么要使用25年的編譯器呢?
- 7 回答
- 0 關(guān)注
- 646 瀏覽
添加回答
舉報(bào)