簡體   English   中英

你如何處理NUL?

[英]How do you deal with NUL?

當我們談論NULL時,我會不時遇到與其他程序員的通信問題。 現在NULL可以

一個NULL指針
NUL角色
某種數據庫中的空數據元素。


NUL似乎是最令人困惑的。 它是ASCII字符0x00。
我傾向於在代碼中使用'\\ 0'來表示它。 我小組中的一些開發人員
傾向於簡單地使用0,並讓編譯器隱式地將它轉換為char。


您更喜歡NUL使用什么? 為什么?

我使用'\\0'作為nul-character,使用NULL作為指針,因為它在兩種情況下都是最清晰的。

順便說一句, 0'\\0'都是C中的int ,當存儲在char變量中時,任何一個都將轉換為char

我喜歡預定義的NULL宏,因為它保留了語義,而不是數字0的其他一些用法。

有許多英語單詞拼寫或說話相似,但有不同的含義。 與英語一樣,使用進行討論的上下文來指導您達到預期的含義。

  • 為了處理字符串,我總是將空字符表示為'\\ 0'。
  • 對於指針,我嘗試使用隱式轉換為布爾值(if(!myPtr)或if(myPtr))來指針無效。
  • 如果我需要指針的默認值,它是NULL,例如struct list_head = {0.0,NULL};)。

END_OF_STRING是愚蠢的,因為它是額外的間接,只會讓新讀者感到困惑(任何不能立即識別'\\ 0'的人都應該離開鍵盤)。

另一件事 - 我認為在討論數據建模時,空值和空值之間的區別非常重要。 在討論C風格的字符串或可空數據庫字段時尤其如此。 有人告訴你“我沒有名字”和“我的名字是”,這有很大的不同。

@BKB:

我在他的建議中看到了這一點,但“NULL”使得上下文更加清晰。 這就像在浮點值中使用“0.0”,在處理字符時使用'\\ 0'。 (同樣,如果在算術上下文中使用char,我更喜歡看到0。)

Bjarne在本FAQ中進一步說明NULL無論如何都是#defined為0,因此標准代碼應該沒有問題。 我同意全大寫符號是丑陋的,但我們必須等到0x(其中nullptr可用,作為關鍵字。)

如果我沒記錯的話,大多數C編譯器都會像這樣定義NULL:

#define NULL ((void*)0)

這是為了確保將NULL解釋為指針類型(在C中)。 但是,這可能會導致更嚴格的C ++版本的問題。 例如:

// Example taken from wikibooks.org
std::string * str = NULL; // Can't automatically cast void * to std::string *
void (C::*pmf) () = &C::func;
if (pmf == NULL) {} // Can't automatically cast from void * to pointer to member function.

因此,在當前的C ++標准中,空指針應該用文字0初始化。顯然因為人們習慣使用NULL定義我認為很多C ++編譯器要么默默地忽略該問題,要么在C ++代碼中將NULL重新定義為0。 例如:

#ifdef __cplusplus
#define NULL (0)
#else
#define NULL ((void*)0)
#endif

C ++ x0標准現在定義了一個nullptr關鍵字來表示空指針。 在將托管指針設置為null時,Visual C ++ 2005的CLI / C ++編譯器也使用此關鍵字。 在當前的編譯器中,您可以創建模板來模擬這個新關鍵字。

有一篇關於wikibooks.org討論這個問題的更詳細的文章。

A one-L NUL, it ends a string. 
A two-L NULL points to no thing. 
And I will bet a golden bull 
That there is no three-L NULLL. 



(The name of the original author is, alas, lost to the sands of time.)

數據庫為NULL,代碼為NIL。

我相當喜歡

#define ASCII_NUL ('\0')

我只是偶爾錯誤地將'\\ 0'輸入為'0'。 但是當我完成它時,我發現代碼檢查很難發現錯誤,帶來了搞笑的后果。 所以我不喜歡'\\ 0',並且更喜歡ASCII_NUL或0(當然后者在C ++中有錯誤的類型)。 顯然我使用'\\ 0',要求與現有代碼或樣式指南保持一致。

谷歌C ++風格指南,其中包含一些我喜歡的東西和一些我不喜歡的東西,但似乎大部分都是聲音,指針優先選擇NULL到0。 它指出NULL可能不會簡單地定義為0(或0L),尤其是在sizeof(void *)可能不是sizeof(int)(或sizeof(long int))的實現中。

0和NULL都被指定為整數類型,並且當轉換為指針類型時,它們都必須產生空指針值。 但它們不一定是相同的整體類型。 因此,在某些情況下,使用NULL可能會產生一些有用的警告或錯誤。

雖然總的來說,我建議使用命名常量,但這是一個例外。 對我來說,定義:

#define NULL 0
#define END_OF_STRING '\0'

與定義一樣有意義:

#define SEVEN 7

沒有。 是的,我知道編譯器已經定義了NULL,但我從不使用它。 對於指針,0; 對於字符,'\\ 0'。 更長並不總是意味着更具表現力。

相關的排序:Slashdot最近在關於空指針comp.lang.c FAQ部分有一個故事,我發現它非常有趣。

對於通信我使用NULL。 如果我正在與一個無法掌握不同數據類型的NULL概念的開發人員合作,那么我會擔心。

為了實現它是特定於案例的。 數字為0(浮點后固定f),指針為NULL,字符串為0。

不使用二進制0表示NULL的系統越來越難以找到。 它們也往往具有各種可移植性問題。 為什么? 因為在這些系統上,memset和calloc都不能清除包含正確指針的結構。

const char END_OF_STRING = '\0';

所以當你說:

str[i] = END_OF_STRING;

要么

if (*ptr == END_OF_STRING)

毫無疑問,你的意思是什么。

我們使用NULL作為指針,使用NULLCHAR作為字符

#define NULLCHAR '\0'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM