• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 空指針究竟指向了內存的哪個地方?

    發表于:2007-05-25來源:作者:點擊數: 標簽:哪個指向指針內存地方
    大家都知道: [code:1:4094d314c8]int*p; p=NULL;[/code:1:4094d314c8] 是說明p為一個空指針。NULL在"stdio.h"中被宏定義為0(或其他什么常數〈視編譯器而定〉),而這樣又并不是說p指向的地址為0,那么各位大俠,這時p究竟指在哪兒呢?不會就這么懸著吧?!

    大家都知道:
    [code:1:4094d314c8]int *p;
    p = NULL;[/code:1:4094d314c8]
    是說明p為一個空指針。NULL在"stdio.h"中被宏定義為0(或其他什么常數〈視編譯器而定〉),而這樣又并不是說p指向的地址為0,那么各位大俠,這時p究竟指在哪兒呢?不會就這么懸著吧?!

    望高手告知其中的細節。不勝感激??!

     kj501 回復于:2005-05-13 11:48:51
    以前有過討論,搜索論壇看看。好象精華中也有。

     gngwzz 回復于:2005-05-13 12:44:25
    空指針指向你進程私有地址的0地址,,它不會被分配出去,,主要的不是null指在哪,而是如果指向null,我們的代碼就可以用if(ptr)來判斷它是不是有效的指針,不過,如果這個指針不是指向0,也有可能不是個有效的指針,,所以建議程序員在定義指針時把它初始化為0,

     hhlcjcj 回復于:2005-05-13 17:18:31
    受教

     FH 回復于:2005-05-13 17:25:39
    NULL不一定是0!這句話是俺今天第二次說。
    NULL只是一個概念,叫作空值,其值本身沒有任何含義,可以用0代替,也可以用1,...代替,只要這些值不會與系統實際的有效地址沖突即可。
    因此,本人在此再次強調,不要自作聰明地認為NULL就是0,要判斷的時候還是老老實實地與NULL做比較,別想當然地用什么!ptr之類的寫法,因為在某個特定環境下,NULL可能不是0,而系統函數返回的是NULL不是0,那時,你的函數就會出現莫名其妙的錯誤。所以,養成良好的習慣是非常重要的。
    忘了是誰第一個用了!ptr這樣的寫法,這個人該殺!害了多少人??!

     kj501 回復于:2005-05-13 17:29:34
    [quote:a34b12769f="FH"]
    別想當然地用什么!ptr之類的寫法,....[/quote:a34b12769f]
    印象中好象林銳寫的《高質量c/c++編程指南》上就是這么提倡的。

     win_hate 回復于:2005-05-13 23:42:52
    空指針保證不是一個合法地址,這是標準規定的。

     FH 回復于:2005-05-14 01:18:46
    [quote:f8f6d3ff5f="kj501"]
    印象中好象林銳寫的《高質量c/c++編程指南》上就是這么提倡的。[/quote:f8f6d3ff5f]

    那說明他就該殺!他的書是垃圾!審稿的人也是飯桶!

     qunying 回復于:2005-05-14 01:50:01
    你的說法并不正確. 

    請見翻譯:
    [url]http://c-faq-chn.sourceforge.net/ccfaq/node59.html[/url]
    特別是[url]http://c-faq-chn.sourceforge.net/ccfaq/node69.html[/url]

    [quote:7730b2a634="FH"]NULL不一定是0!這句話是俺今天第二次說。
    NULL只是一個概念,叫作空值,其值本身沒有任何含義,可以用0代替,也可以用1,...代替,只要這些值不會與系統實際的有效地址沖突即可。
    因此,本人在此再次強調,不要自?..........[/quote:7730b2a634]

     FH 回復于:2005-05-14 01:55:04
    沒覺得樓上引用的文字與俺的見解有什么沖突,相反,說得比俺更過火。比如:“每種指針類型都有一個空指針, 而不同類型的空指針的內部表示可能不盡相同?!痹偃纾骸翱罩羔樀膬炔?nbsp;(或運行期) 表達形式, 這可能并不是全零, 而且對不用的指針類型可能不一樣?!?br>
     qunying 回復于:2005-05-14 02:01:03
    也許這一段可能更適合 對 if (!ptr) 的討論[url]http://c-faq-chn.sourceforge.net/ccfaq/node62.html[/url]

     qunying 回復于:2005-05-14 02:13:45
    [quote:450a3da0e5="FH"]沒覺得樓上引用的文字與俺的見解有什么沖突,相反,說得比俺更過火。比如:“每種指針類型都有一個空指針, 而不同類型的空指針的內部表示可能不盡相同?!痹偃纾骸翱罩羔樀膬炔?nbsp;(或運行期) 表達形式, 這可能并不是全..........[/quote:450a3da0e5]
    我舉個例子:
    例如  (假設指針的長度為4個字節, 又假設這個機器上的空指針表達為"0x10000000".
    union {
    char a[4];
    int *p;
    } u;
    當你用 memset(u.a, 0, 4); 設a為全0時, 并不能假設 p 是空指針 (我們的空指針是0x10000000) . 可是你可以用 if (p == 0) 來判斷 p 是否為空指針. 編譯器會自動把 0 轉換為 0x10000000 與 p 進行比較.

    是不是覺得有點暈? 我也是理解了好久才明白.

     FH 回復于:2005-05-14 03:40:03
    “memset(u.a, 0, 4); 設a為全0時, 并不能假設 p 是空指針”
    誰說這樣就能夠讓p為空指針了?memset里面說了?概念簡直一塌糊涂。

     qunying 回復于:2005-05-14 03:49:49
    也許我沒講清楚, 我并不是說這樣就可以設 p 為空指針, 而只是為了更好的說明 空指針本身的內部表達和 進行 if (p) 的判斷的不同.  在我們虛構的機器上 (if p == 0) 返回的是否, 而不是真.

    另外 可以用 u.p = 0 將 p 初始化為空指針, 但 p 的值由編譯器轉化為了 0x10000000
    我門是不需要知道機器內部是怎樣表達空指針的, 這是編譯器的工作.

     win_hate 回復于:2005-05-14 09:32:55
    [quote:fa3af42415="FH"]

    那說明他就該殺!他的書是垃圾!審稿的人也是飯桶![/quote:fa3af42415]


    上次有個誰來著,說那本書是 <<c/c++ 高質量笑話>>. :D

     win_hate 回復于:2005-05-14 09:44:53
    我對 if (p) 的看法:

    1、(char *)0, (void *)0... 均為所謂的``零指針''

    2、在指針上下文 0 會被提升為相應的 ``零指針'',其部表示取決于機器

    3、if (p == 0) 是合法的

    (p==0) 為指針類型與常數 0 比較,常數 0必須被提升,提升為相應類型的“零指針”(type *) 0

    4、if(p) 也是合法的:
    因為 if(p) 會被編譯器處理為 if (p == 0),然后歸結到 3

    至于風格的問題,我就不討論了。

     gvim 回復于:2005-05-14 11:32:08
    NULL是編譯器處理的,靠上下文判斷,概念就是“空”。編譯器做的不符合標準的,程序錯誤的讀取或修改(void*)0指向的地址,可能不會造成錯誤(也可能會,主要看機器結構對絕對0地址的處理方式)。而好的編譯器,幾乎都有這樣的檢查,來避免對0地址的讀寫。(如果你非要把NULL當成 0 地址的話)

     kernelxu 回復于:2005-05-14 20:55:16
    [quote:250e81197d="win_hate"]我對 if (p) 的看法:

    1、(char *)0, (void *)0... 均為所謂的``空指針常數''

    2、在指針上下文 0 會被提升為相應的 ``空指針常數'',其部表示取決于機器

    3、if (p == 0) 是合法的

    (p==0) 為指針類型與常..........[/quote:250e81197d]

    同意!
    在stdio.h頭文件中,NULL被宏定義為0,所以程序在編譯時將NULL替換成0,
    1、若NULL本身不是被宏定義成0,那么在此時使用NULL就不是表示空指針了,對嗎?
    2、若在程序中使用了null來表示空指針,因為只有NULL被宏定義為0,所以null不能表示空指針,對嗎?
    3、若1、2都對的話,是不是可以說標準C語言就是以p==0來判斷p為空指針,用p = 0 使p空指針?
    4、在指針上下文 0 會被提升為相應的 ``空指針常數'',其內部表示取決于機器

     qunying 回復于:2005-05-15 03:56:19
    [quote:a41422e576="kernelxu"]

    同意!
    在stdio.h頭文件中,NULL被宏定義為0,所以程序在編譯時將NULL替換成0,
    在stdio.h頭文件中,NULL被宏定義為0,所以程序在編譯時將NULL替換成0,
    1、若NULL本身不是被宏定義成0,那么在此時使用NULL就不是表示空指針了,對嗎?
    2、若在程序中使用了null來表示空指針,因為只有NULL被宏定義為0,所以null不能表示空指針,對嗎?
    3、若1、2都對的話,是不是可以說標準C語言就是以p==0來判斷p為空指針,用p = 0 使p空指針?
    4、在指針上下文 0 會被提升為相應的 ``空指針常數'',其內部表示取決于機器
    [/quote:a41422e576]

    1. 標準中 NULL 被定義為 0 或 (void *)0,判斷也是用 if (p == 0) 進行的。如果你用的系統 NULL 不是定義為0 或 (void *)0, 那就不是標準C,我懷疑是否有這樣的C. 除非你自己重定義了 NULL, 那此NULL就不是彼NULL了,那可是存心找自己麻煩。

    2. null 只是英文里用來表示空的意思,在C語言中沒有意義。除非自己定義了名為“null"的變量或宏,能不能表示空指針就看具體定義了,不過一般人不會這么無聊,不用標準NULL,而用自定義的null。

    3. 標準C語言就是以p==0來判斷p為空指針,用p = 0 使p空指針.
    4. 對

     kernelxu 回復于:2005-05-15 21:39:09
    理解!
    謝謝各位指點! :em02:  :em02:

     我不懂C++ 回復于:2005-05-16 19:38:03
    [quote:2276ec4906="FH"]NULL不一定是0!這句話是俺今天第二次說。
    NULL只是一個概念,叫作空值,其值本身沒有任何含義,可以用0代替,也可以用1,...代替,只要這些值不會與系統實際的有效地址沖突即可。
    因此,本人在此再次強調,不要自?.........[/quote:2276ec4906]
    我完全同意FH關于“NULL不一定是0”的觀點。NULL本身就是一個宏。
    #define NULL "FH"
    #define NULL "abc"
    #define NULL printf
    ...
    這些都是合法的C/C++預處理語句。
    正因為這點,所以,在我們比較指針是否為空的時候,一個更好的方法是把它和0比較。譬如說:
    if ( str == 0 )
        abort();//傳進來的字符串是空的,叫人怎么活?
    這是因為如果你寫
    if ( str == NULL )
    萬一有某個好事之徒像FH說的那樣把NULL定義成1、2、3、...了,那怎么辦?(雖然這種人該殺)
    因此,結論就是,推薦使用0作為空指針初始化以及判斷的標準。

    愿上帝與你同在,阿門!

     yuxh 回復于:2005-05-16 19:40:36
    宏定義是個約定,如果誰都可以隨便推翻這些約定的話,那還有什么語言?

     keenor 回復于:2005-05-16 20:25:13
    NULL指針的值一定是0,這點可參照C語言標準。以下來自C99(WG14/N843 1998):
    [quote:38ae1b66c1]
           [#3] An integer constant expression with  the  value  0,  or
           such  an  expression  cast  to type void *, is called a null
           pointer constant.46)  If a null pointer constant is assigned
           to or compared for equality to a pointer,  the  constant  is
           converted to a pointer of that type.  Such a pointer, called
           a null pointer,  is  guaranteed  to  compare  unequal  to  a
           pointer to any object or function.
    [/quote:38ae1b66c1]
    .....
    [quote:38ae1b66c1]
           46)The macro NULL is defined in <stddef.h> as a null pointer
              constant; see 7.17.
    [/quote:38ae1b66c1]
    第一段說得很清楚,值一定是0,而類型可以是void *,也可以是int。
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n843.htm

     gvim 回復于:2005-05-16 21:56:01
    no,no,no
    NULL只是一個表示“空”“無”的概念,可是計算機不能用一個"實物"來表示“空”“無”等概念,所以只有借助輔助的手段。最常用的,而且數學中表示這個概念的,也就是0了??墒?在計算機里面一些場合卻又表示一個實際存在的東西,也就是說要一個實際存在的實體表示一個概念,這個似乎有些矛盾。怎么辦?那么只能由編譯器來解決,在上下文環境中來判斷0應該是什么東西。比如在指針環境里,就把0當成“空”這樣一個概念,在其他比如數值環境里面,就把0當成實數0。
    而如果錯誤是用NULL,(在C語言里面也就是實數0,此時0有兩種含義),當然會造成錯誤。

    至于NULL是不是0,答案是不一定。因為NULL表示概念,0卻可以表示實數0。所以在數據庫中,NULL就不是用0表示(這句話是我上學的時候從老師那里聽來的)

    notice,NULL is just a conception not a real number!

     qunying 回復于:2005-05-17 02:36:17
    我們討論的是C語言. 在標準C里NULL就是被定義為0或(void*)0的. 不要混淆了概念空和C中的NULL宏定義. 我們這邊討論的NULL指的是宏定義. 而機器的實際空指針值,一般是不需要知道的.

    數據庫中的定義是另一回事.

    如果一個"程序員"自己定義了另一個非零的NULL , 那他是在違反標準,給自己和他人找麻煩.

     aero 回復于:2005-05-17 08:44:58
    [quote:f7476044ef="FH"]

    那說明他就該殺!他的書是垃圾!審稿的人也是飯桶![/quote:f7476044ef]

    ^_^,9494,可就是還有很多人推薦,唉,看起來像那么回事而已。

     aero 回復于:2005-05-17 08:56:28
    ^_^,大家說的都是一回事啊。

    FH可能做的是嵌入式部分,經常要自己實現C標準,所以,必須要了解到NULL是“空”的概念,而不一定是0地址。

    而一般情況下,對0的上下文發翻譯(是否翻譯成0地址),可以由編譯器去做。所以,上了一個層次,就可以簡單的認為NULL的值就是0了,這也就是標準中說的這個意思。

    風格建議上,還是盡量多使用if(p == NULL)這樣的寫法,畢竟,這更加靠近本質。

     lchhcllch 回復于:2005-05-17 11:30:49
    說到空,就想到了空即是色,色即是空了.題外了.
    對于返回,還是以NULL為主了,對于標準函數的返回指針也明確是返回NULL(意思),不必強行在是不是等于零上下功夫.
    畢竟不要跳過宏定義去劃等號.

     wolf0403 回復于:2005-05-17 18:22:36
    C 中 NULL 表示為 (void*)0,并且可以用 if ( p ) 和 if ( !p ) 來判斷一個指針是否為空,好像是在 TCPL 中規定的通用方法。規定 NULL 為別的什么東西,就像規定 strcmp 為復制字符串一樣可笑。

    扯遠一點,C++ 98 標準中規定空指針就是 0,甚至不用 NULL 這個宏或者 (void*) 0 這種類型修飾符。

     我不懂C++ 回復于:2005-05-17 20:29:10
    [quote:1a257c0a21="keenor"]
    第一段說得很清楚,值一定是0,而類型可以是void *,也可以是int。
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n843.htm[/quote:1a257c0a21]
    這個,標準有說“NULL指針的值一定是0”嗎?

     wolf0403 回復于:2005-05-17 20:39:33
    因為 NULL 必須是通用類型的,所以 C 規定是 (void*)0 。C++ 中直接以 0 作為特殊值處理。

     Imt1024 回復于:2005-05-17 23:27:54
    我估計NULL應該是這樣實現的,
    首先應該保證 NULL所指向的內存,不在用戶空間,而是在內核,
    如果我們對空指針操作,就會引發一個中斷,因為user沒有權限
    在內核空間操作,系統可能會中斷該用戶程序,報告segment fault
    之類錯誤.  實現中可能是系統將整個虛地址空間分成用戶和系統兩部分,
    NULL所對應的空間應該映射在內核空間,不知道理解對不?

     wolf0403 回復于:2005-05-18 00:41:21
    虛擬內存是有權限控制的。0x0 這個位置是規定了不可讀寫,因此試圖讀寫的時候必然引發 Access Volitation

     qunying 回復于:2005-05-18 00:41:41
    感覺我們的討論把 空指針(null pointer) 和 NULL 宏定義混在一起了. 有時把NULL當作概念用,有時把NULL當作宏定義用.

    NULL作為宏定義肯定是為零的. 這是標準C規定的,不然有很多代碼都不能工作了. 即使在嵌入式系統中, 如果真的需要知道并了解空指針的值, 那也應該另外定義一個宏,而不是重新定義標準. 但大多數情況我們根本不許要知道空指針的值是什么.

     Solaris12 回復于:2005-05-18 15:17:44
    [quote:4e168948ef="wolf0403"]C 中 NULL 表示為 (void*)0,并且可以用 if ( p ) 和 if ( !p ) 來判斷一個指針是否為空,好像是在 TCPL 中規定的通用方法。規定 NULL 為別的什么東西,就像規定 strcmp 為復制字符串一樣可笑。

    扯遠一點,C++ 98..........[/quote:4e168948ef]

    忍不住說上一句,標準和實現往往是兩回事,
    如果寫代碼的時候把NULL和0混用,
    恐怕會吃虧的。
    尤其是做kernel和嵌入式系統的程序員。

     win_hate 回復于:2005-05-18 15:33:52
    [quote:10d51b3e48="Solaris12"]

    忍不住說上一句,標準和實現往往是兩回事,
    如果寫代碼的時候把NULL和0混用,
    恐怕會吃虧的。
    尤其是做kernel和嵌入式系統的程序員。[/quote:10d51b3e48]

    哪我該怎么辦?用 0 還是用 NULL。

    如果一個實現修改了0 的含義(注意這時它不能稱為一個c 編譯系統),if (p) 這種寫法可能會完蛋,但如果另一個實現修改了  NULL 的含義, if(p == NULL) 也會完蛋的。


    我覺得只要按標準寫就行了,出了問題不是還有手冊嗎? 改就是了。

     我不懂C++ 回復于:2005-05-18 19:20:36
    [quote:d2ad3447fe="qunying"]NULL作為宏定義肯定是為零的. 這是標準C規定的[/quote:d2ad3447fe]
    應該沒有這樣的規定吧?

     flw 回復于:2005-05-18 21:27:52
    win_hate qunying xiaoming FH 的看法我都贊同.

    FH 對 qunying 有一次誤會。

    to FH:
    唯一不甚明了的一點就是
    if ( !ptr )
    這種寫法應該是正確的吧?

    我發現大家爭論的原因所在了:都是語言表達不清惹的禍
    現在撥號,就不說了。
    明天寫個總結。

     gvim 回復于:2005-05-18 23:14:19
    哎,把原理說出來,反而說我混淆是非。。。
    計算機說白了就是數學。NULL只不過是數學概念的計算機表示(represent)
    有否想過何為NULL?它表示什么?為何要定義為0而不是-1,-2。。?
    java的NULL是數字0嗎?SQL的NULL是數字0嗎?其他類似語言的概念表示是怎樣?
    怎么都只看ansi C的表象認為NULL就是0呢?
    只有了解了NULL的本質,才不會問出“空指針究竟指向了內存的哪個地方 
    ”這樣的問題。
    借用對象概念:NULL就是一個數學類,#define NULL 0 只是一個C++語言的NULL的實例化(instance),#define NULL (vois*)0 又是C語言的實例化,SQL的NULL實例化為另外一個。。等等,ni不能說NULL就是0,也不能說0就是NULL。

    概念已說明,多說無益,各位繼續。。

     ChinaDream 回復于:2005-05-18 23:26:24
    [quote:d29bcf7a57="kernelxu"]是說明p為一個空指針。NULL在"stdio.h"中被宏定義為0(或其他什么常數〈視編譯器而定〉),而這樣又并不是說p指向的地址為0,那么各位大俠,這時p究竟指在哪兒呢?不會就這么懸著吧?!

    望高手告知其中的細節。不..........[/quote:d29bcf7a57]

    在MEM中有個地址轉換表!空指針指向一個內核保留的只讀地址!由MEM(內存管理)完成映射

     qunying 回復于:2005-05-19 01:48:34
    空指針究竟指向了內存的哪個地方?這個問題本身沒有意義. 在概念上空指針代表一個不指向任何地方的指針. 實現上, 空指針在系統中有個特殊值, 但一般上我們不需要知道這個特殊值. 我們只要記住在C里 if(ptr) 和 if(ptr != NULL) ,
    if (ptr == 0) 和 if (ptr == NULL) 的判斷完全等價, 這兩種形式都是正確的, 唯一區別在于風格. 

    即使在嵌入式系統中, 如果你不是直接實用匯編語言, 你也不需要知道空指針的值, 只要編譯器還是支持標準C,那 if(ptr) 和 if(ptr != NULL) ,
    if (ptr == 0) 和 if (ptr == NULL) 的判斷還是一樣的. 如果某一接口設備用了特殊值(而編譯器不知道)代表空, 那也是應該另外定義一個代表形式, 而不是改寫NULL的定義. 這里NULL只表示C中的宏定義.

     思一克 回復于:2005-05-19 09:16:55
    如果 “if(ptr) 和 if(ptr != NULL) ,”等價,
    那么NULL就一定是(void*)0

     win_hate 回復于:2005-05-19 09:35:11
    我又把標準看了一下,發現很有趣的描述。


    1、0, (void *0) 是零指針常數,用于指針比較時,不等于任何有意義的指針(指向合法位置的指針)。

    2、NULL 被規定為: 實現指定的零指針常數,在 stddef.h 中定義。(沒有說是否就一定為0。)

    從這兩點我們至少可以知道,按標準

    if (!p), if (p==NULL) 都是合法的,如果遇到了不標準的實現,自認倒霉好了。


    注意一點:NULL 是``實現定義的零指針常數''。
    隱含如下的意思:NULL 不必為0,除了指定零指針常數外,具體實現還可以定義別的零指針常數。一個標準的編譯器必須同時能支持這兩種零指針常數,盡管它們可能是一樣的。

     kernelxu 回復于:2005-05-19 09:39:37
    [quote:1496cb9185="ChinaDream"]

    在MEM中有個地址轉換表!空指針指向一個內核保留的只讀地址!由MEM(內存管理)完成映射[/quote:1496cb9185]

    說到點子上,謝謝!

     kav 回復于:2005-05-19 10:00:57
    學習

     我不懂C++ 回復于:2005-05-19 11:36:38
    to yuxh:
    我很同意宏定義是一個約定,但是我想說的是,違反了宏定義,和語言本身并沒有關系。宏定義雖然和語言有千絲萬縷的關系,但是嚴格的說,還是在語言之外的。

    to keenor以及后面的某些人:
    我想指出你的一個小小的邏輯錯誤。你這兩段話,只能說明,在stddef.h里面定義的NULL必須是那個null pointer constant。但是標準從來沒有說過,如果我在另一個不相關的頭文件里面定義一個NULL,并且定義為其它東西,就會不符合標準。雖然我承認那樣做的可能性很小,但是邏輯上,我們不能用你的話得出這個推斷。
    這就好像如果在一本法典里面規定:
    1.暴露行為:=裸體|方便
    2.在公共場所有暴露行為,就是有傷風化罪
    從這兩條,我們不能判定出,在家里洗澡也有傷風化。

    to qunying:
    我承認一個人把NULL定義為其它東西,是給自己和別人找麻煩,但是我不同意這是違反標準的。理由同上。

    有人可能會說,為什么不用宏呢?直接使用常量不是一個不好的習慣嗎?問題在于,我們為什么用宏呢?我覺得宏有三個作用:助記/抽象,簡化輸入。NULL和0相比,簡化輸入是肯定不可能的。至于助記抽象的話,這就要看了。我們都看到過這樣的宏:
    #define PAGE_SIZE (32*1024)
    有誰看到過這樣的宏?
    #define ONE_HUNDRED_AND_TEN (110)
    前面的一個宏很好,它賦予數字更多的意義。后面的那個宏很爛,因為沒有賦予什么意義。而現在ANSI的意思就是,大家就都把0認為是null吧,別再助記了。也就是說
    #define NULL (0)
    某種意義上說,和前面第二個宏差不多。

    有人說,既然一般沒毛病的,都會把NULL定義為0,那么我們也就這樣用好了。但是這的確會偶然產生問題。譬如說:
    https://lists.openafs.org/pipermail/openafs-devel/2002-March/007721.html
    http://lists.gnu.org/archive/html/uisp-dev/2004-10/msg00008.html
    既然他們可能出問題,別人也可能出。更不用說,我寫一個測試程序來測試某個語法特性,如果不包含任何頭文件,使用NULL就不會通過。

    事實上,我也同意說,大多數情況下,NULL都會被定義為0,這個大多數情況甚至可能是99.99%。問題在于,既然直接使用0可以100%解決問題(我們不需要include任何頭文件,不需要考慮是不是兼容,不需要考慮有什么惡心事件的發生),為什么我們不直接用0呢?

    btw:我最討厭三種人,會數數的和不會數數的:D
    btw:“在MEM中有個地址轉換表!空指針指向一個內核保留的只讀地址!由MEM(內存管理)完成映射”,這沒有踩到本質的點上。

     思一克 回復于:2005-05-19 11:51:10
    有誰可以給出C中空指針不用0地址的例子?

     win_hate 回復于:2005-05-19 13:00:31
    我不懂C++  說得很對。

    不過把NULL 定義為別的東西,雖然不能比擬為犯法,但定性為道德敗壞絕對是沒有問題的。

    我把我前面貼子中的

    NULL 規定為一個現實定義的零指針常數

    改為:

    ANSI C 標準中所提及的 NULL 是一個現實定義的零指針常數

    這樣總沒有問題了。其實,我們前面所討論的NULL,指的正是編譯系統提供的NULL,而不是自己另外定義的。

    ps. 法律也會有漏洞,標準也會有自相矛盾的地方。

     我不懂C++ 回復于:2005-05-19 20:03:55
    我不太能夠指出C語言里面NULL不等于0的情況,因為我對C其實不很了解。
    但是在C++里面,這肯定會是一個問題。這里的問題在于名字碰撞。C++傾向于盡量少用宏,而多用常量,這是因為常量的名字不會撞倒。
    譬如說我寫一個SQL模塊,里面我想定義一些標志位:
    namespace SQL
    {
    enum Flags
    {
        NULL = 0,
        LOCK,
        ...
    };
    // other definitions omitted
    }
    那如果像現在這樣,就會撞上,最終導致編譯錯誤,所以我只能定義成:SQL_NULL?;蛟SC語言里面這樣做有理由,但是在C++里面,SQL::SQL_NULL就和CStudent::mStudentName一樣,通常是不好的習慣。
    當然,NULL不可能成為一個常量,否則編譯錯誤會更多。
    我想C++里面的新的關鍵字null之所以用小寫,或許也考慮了一般人定義常量都是全大寫(獨家猜測:D)。
    我同意win_hate關于道德敗壞的定義,但是標準只規定了某個政府部門不能道德敗壞,并沒有規定其它政府部門不能道德敗壞......

    _________________
    愿耶穌基督、穆罕默德、釋迦牟尼與你同在!

     bonnytan 回復于:2005-05-25 14:39:16
    許多程序設計風格的意見只是意見。通常卷入 ``風格戰爭" 是毫無意義的。某些問題 爭辯的雙方是不可能同意, 認同對方的不同或者是停止爭論的。此為引用http://c-faq-chn.sourceforge.net/ccfaq/node286.html#q:17.10

     flw 回復于:2005-05-25 14:52:26
    [quote:afc7635823="bonnytan"]許多程序設計風格的意見只是意見。通常卷入 ``風格戰爭" 是毫無意義的。某些問題 爭辯的雙方是不可能同意, 認同對方的不同或者是停止爭論的。此為引用http://c-faq-chn.sourceforge.net/ccfaq/node286.html#q:17.10[/quote:afc7635823]
    這不是一個風格戰爭。

    BTW:拜托所有清完嗓子準備發言的朋友,先喝杯茶然后將別人的發言都看一遍,
    不要斷章取義。

     sfi 回復于:2005-05-25 15:53:22
    建議不要在這里談論風格問題,風格都是公司規定的。

    現實生活中,null就是無、啥也沒有的意思,可以向少林寺方丈請教一下。

    在C語言中,NULL(stddef.h里定義為大寫)表示一個無效的指針,但總要具體實現吧。所以[b:d975946d92][color=blue:d975946d92]許多[/color:d975946d92][/b:d975946d92]實現將其定義為(void *)0,stddef.h里就是這樣定義的,有些也定義為0,兩者在具體用到的時候效果一樣。NULL表示[color=blue:d975946d92]無效指針[/color:d975946d92],但它不是無,因為它有自己的值。
    你可以改變NULL的定義,例如你可以重新定義
    #ifdef NULL
    #undef NULL
    #endif
    #define NULL (void *)1
    也就是說,系統規定的無效地址可能跟你定義的無效地址不一致,這時你的無效可能真的就無效了。

    最后回答一下樓主的問題:
    p指向了一個[color=blue:d975946d92]被定義為無效[/color:d975946d92]的地址。

     leon_leon 回復于:2005-05-25 17:16:07
    學到知識了。

     asdmonster 回復于:2005-05-25 21:02:07
    我的一點理解加上剛才做的一個小實驗,說出來請大家指點:

    1,int * p;
        當declare一個指針的時候(非函數指針),我在redhat9自帶的gcc上看到的是編譯器申請了一個空間,然后賦 $0,我沒有明白這個 $0到底是代表了 $0 還是 NULL(in stdio.h)。
    2,if(p) if(!p)
         if()中出現的只能是邏輯變量,true or false,其實p經歷了兩次轉換(cast):第一次轉化為int,第二次轉換是 (int)0 == false,
         if(p)這樣的寫法建立在兩個假設的基礎之上的:第一,NULL宏被定義為 (void*)0,第二,計算機只有0,1,沒有true,false,第二個假設就是false用0表示,而不是-1(我記得以前學習的時候遇到過這樣的表示法)
    3,NULL
          NULL表示的邏輯意義并不是 0(指針),而是[color=blue:66cc41fa4b]指向內容不確定(指針)[/color:66cc41fa4b] ,

    個人覺得,無論規范怎么定義,if( NULL == p)要優于 if(p),后者除了習慣,幾十年來c程序員中的習慣(不可否認習慣是程序的一部分),我看不出任何額外的益處。

    當然,在林銳的書上這么寫,要用 if( p) 而不是 if( NULL == p),面試的時候我也會告訴面試官 if(p),畢竟這樣更c style一點。 :em11: 

    哎。

     win_hate 回復于:2005-05-25 22:18:48
    請后繼發貼者看清前面的貼子再接, 我把一些我認為正確的觀點再寫一下:

    1、0 和 (viod *)0 是零指針常數
    2、0 或 (void *)0 轉換為 (type *)0 后,稱為零指針
    3、零指針與任何指向有效地址的指針比較一定不等
    4、stddef.h 中有一個標準的宏 NULL,該宏被規定為 實現定義的零指針常數.

    以上 4 條均是 ANSI C 標準的規定,一個符合 ANSI 標準的編譯器必須支持它們。根據以上4條,if (p) 與 if (p != NULL) 等價。

    感謝 我不懂C++ 兄, 他指出,標準并未規定:你不可以用自己定義的 NULL 去覆蓋 stddef.h 中的 NULL, 所以用 if (P == NULL)  不好。

    我同意此觀點的根據,但不同意其結論。NULL 的作用在于 [color=red:0b65db81b1]``提示此為一指針''[/color:0b65db81b1],是否用 NULL,是一個風格的問題。而且 NULL 的用法在 c 里已經是事實標準。

    重定義 NULL 是很稀奇的事。如果你認為重定義一個宏沒什么大不了,請注意 NULL 是一個 ANSI C 規定實現的標準宏。

    重定義 NULL 與重定義標準庫函數可以相提并論。與宏一樣,函數庫也并非語言的一部份,但 ANSI C 還是規定了一些標準庫。沒人可以禁止你實現自己的 printf,并覆蓋 stdio 中的 printf,而你自己實現的 printf 可以調用一個 abort 使程序崩潰 。

     asdmonster 回復于:2005-05-25 22:35:44
    個人覺得:
    if( p )  不等于 if( NULL != p)
    因為有兩種情況:
    1,ansi c的enhance(升級?)。
    2,某些標準和ansi c的不一致,比如 posix和ansi c的某些不一致。
    唯一能確定的是,有這么一個NULL存在,或者說NULL是定義,(void *)0是實現。

    軟件世界中沒有none的概念, NULL想表達的是不確定而不是沒有,就像 NULL != NULL一樣。

    恩,可能上面我的回復讓人誤解了。我想說的是這個。

    ps:
           我找了半天沒有找到ansi c,該怎么找,請教下。

     BadSnail 回復于:2005-05-25 22:58:14
    特別是http://c-faq-chn.sourceforge.net/ccfaq/node69.html 
    這本書叫什么名字啊
    老大

     huang0610 回復于:2005-05-26 01:30:01
    堅決認為賦null而不是0,雖然c定義了null的值為0。具體為什么,我想聽聽譚老師的解釋吧
     “指針變量可以有空值,即該指針變量不指向任何變量,可以這樣表示:p=null,實際上null是整數0,它使p的存儲單元中所有二進位均為0,也就是使p指向地址為0的單元。系統保證使改單元不做他用(不存放有效數據),即有效數據的指針不指向0單元。實際上是先定義null,即:#define null  0.........p=null;  在<stdio.h>頭文件中就有以上null的定義,它是一個符號常量,人們習慣上不用"p=0;"而是用"p=null;",這樣可讀性比較好”
    原文?。?!

     kernelxu 回復于:2005-05-26 11:19:18
    [quote:208e343015="huang0610"]堅決認為賦null而不是0,雖然c定義了null的值為0。具體為什么,我想聽聽譚老師的解釋吧
     “指針變量可以有空值,即該指針變量不指向任何變量,可以這樣表示:p=null,實際上null是整數0,它使p的存儲單元中所有二進..........[/quote:208e343015]
    老兄,說幾點:
    1、是NULL不是null
    2、牛人說的不一定完全正確,可能有些系統0地址不寫有效數據,但并不是說所有的系統0地址都不寫有效數據,特別是在嵌入式系統中系統會榨干每一個bit的內存。
    3、同意win_hate老大

     aero 回復于:2005-05-26 11:21:27
    [quote:fb3f2c9c6e="kernelxu"]
    老兄,說幾點:
    1、是NULL不是null
    2、牛人說的不一定完全正確,可能有些系統0地址不寫有效數據,但并不是說所有的系統0地址都不寫有效數據,特別是在嵌入式系統中系統會榨干每一個bit的內存。
    3、同意win_hate?..........[/quote:fb3f2c9c6e]

    后面回帖的很多人,壓根也沒看前面大家辛辛苦苦的回帖。上來就說,丟臉的自是他們。兄不必與之計較,^_^,win_hate總結的的確非常好。

     mirnshi 回復于:2005-05-26 11:27:10
    如果僅僅聲明一個指針,而沒有任何賦值,那么這個指針是野指針,它會指到VM的任何位置,碰到異常操作,比如對只讀區寫操作,就會引起硬件中斷產生core,也就是通常的段錯誤。
    良好的編程風格是將指針永遠都可控,也就是這個指針的地址,程序可控,通常,對于不使用或初始的指針都將其地址置為0,這是約定俗成的,就如同,我們經常使用的進制一樣,你非用一個別人都不用的進制表示數,那也隨你,只是別人覺得怪而已。再比如,用free釋放完指針后,相信大家都會將指針置成NULL或0,就是為了再使用這個指針時,便于判斷。指針的地址為0,操作起來就非常方便,比較位操作等,都可對應到機器碼,這也就體現了“高級匯編”的美譽。用NULL宏,僅僅是為了可讀性,編譯器會進行優化的。
    對于將NULL定義成某個地址,然后進行比較,相對NULL為0地址,然后比較,性質是相同的,在執行過程中,如果重新定義的地址為可操作,可能會對程序的邏輯流程產生影響。

    另,譚老師的書,還是少看,會誤人子弟,他的理解都是dos年代的,適合用tc2.0編程,32位的OS上,很多提法是不對的。

     kernelxu 回復于:2005-05-26 11:40:04
    aero老大說的即是!
    請求將此貼設為精華?!
    頂!

     wolf0403 回復于:2005-05-26 16:10:46
    在 TCPL 第二版中文版中 5.4 節地址算術運算 中有這樣一句 (p86 line4)
    [quote:a1ed323f93]C 語言保證 0 不是數據的有效地址[/quote:a1ed323f93]
    還有下面 line6-7
    [quote:a1ed323f93]指針與整數不能相互轉換,但0例外:常量0可以賦給指針……程序中經常使用符號常量NULL代替常量0,這樣有助于更清楚地記住常量0是指針的一個特殊值[/quote:a1ed323f93]

    根據這個說法,特殊的是0,而不是NULL:NULL只是常量0的一個助記符。不用說什么“某些平臺不以0為特殊值”云云;如果要說,請給出明確的例證。否則,我還是更傾向于相信 Denies Ritchie 和 Brian Kernighan 在書中的斷言。

    ps,很奇怪的是,我在附錄A中沒有找到可以印證這個說法的條款。誰有 TCPL 第二版新版或者 C99 標準文檔的,可以看看。

     stonejar 回復于:2005-05-31 17:06:30
    林銳的書沒有說!ptr,只說了ptr==NULL和ptr!=NULL,別誣陷人家

     blazewater 回復于:2005-06-02 17:31:08
    林銳那本垃圾書也有人看,笑話,那里面錯誤一大堆;
    要看就看那些經典的書

     smileyg 回復于:2005-06-04 14:16:11
    同意FH的看法。NULL并不一定是0,有些程序員想當然用!ptr去判斷指針是否為
    NULL。嚴格來說,這完全是一廂情愿的做法。在一些編譯不嚴格的系統里面有可能能夠編譯通過,但是假如碰上相反的情況,我們又會去埋怨系統了。鄙人就碰上過類似的情況,最后把別人程序中的!ptr改成null完全搞定。所以說,養成良好的編程習慣,按照c語言的語法規則編寫代碼是解決類似問題的最好方法。

     高峰 回復于:2005-07-19 16:36:32
    這是一個哲學問題,在這里討論不合適。

     AndyFastow 回復于:2005-07-20 05:12:51
    as time goes on, 
    people think NULL == 0 is bad expression (in c)
    so...
    in Java We create a new nulltype, that is not a primitive type.

     SirFang 回復于:2005-07-20 10:37:54
    null是一個概念,NULL是這個概念的一個實現,NULL=0是實現的一個方法,但不是唯一的方法。

     mik 回復于:2005-07-20 14:34:28
    0 與 空(NULL) 在概念上是兩碼事

    0 是實數,是一個實物數
    空 概念上是無,不包括任何東西,當然也不包括0啦.

    以上闡述的是概念上的問題,

    實際上: 在代碼中沒有什么分別. 定義上已經將 0 定義為 NULL, 
    實際上也沒必要分得那么細, 倒不如,實實在在的在代碼算法等多思考

    在 linux 及 windows 系統上編程不可能地避免使用它們的宏定義.
    這屬于編程風格上的問題.

    typedef struct date {
            ......
           .....
    } DATE;

    DATE m_date1;

    這樣的代碼風格,個人認為不好.

    個人比較喜歡定義為:  struct date m_date1; 這樣有利于理解變量本質..

    而: char *p; p = NULL;

    倒不如直接定義為: char *p = 0; 簡單明了.....

     FH 回復于:2005-07-20 14:53:51
    [quote:d6e88395a3="mik"] char *p; p = NULL; 

    倒不如直接定義為: char *p = 0; 簡單明了[/quote:d6e88395a3]

    malloc為什么不在失敗的時候返回0而是返回NULL呢?
    為什么所有系統和標準函數對指針型都不是返回0而是返回NULL呢?
    到底哪個才是[color=red:d6e88395a3]簡單明了[/color:d6e88395a3]的表述不是很清楚了嗎?
    簡單明了不是個人習慣!

     mik 回復于:2005-07-20 15:15:37
    [quote:ecba7bbefd="FH"]謀硎霾皇嗆芮宄?寺穡?
    簡單明了不是個人習慣malloc為什么不在失敗的時候返回0而是返回NULL呢? 
    為什么所有系統和標準函數對指針型都不是返回0而是返回NULL呢? 
    到底哪個才是簡單明了的表述不是很清楚了嗎? 
    簡單明了不是個人習慣??![/quote:ecba7bbefd]

    char *p = (char *)malloc(sizeof(char) * N);

    if (p == NULL)  與 if(!p) 效果一樣

    malloc 返回 是0 是 NULL 有什么區別???

     FH 回復于:2005-07-20 15:36:06
    誰說malloc返回0?哪份文檔上寫著?

     mq110 回復于:2005-07-20 15:43:59
    >>if (p == NULL)  與 if(!p) 效果一樣 

    以前FH 都講的很清楚了. 又弄出來了..~~

     gvim 回復于:2005-07-20 15:55:00
    [quote:225068be76="FH"]誰說malloc返回0?哪份文檔上寫著?[/quote:225068be76]

    對于NULL這個問題 不用說那么多了,這個問題不是簡單的數學問題,象1+1=2可以講明白。
    而如果固執的人 在對這個問提的本質上沒有理解,僅僅從表面去理解與0有什么關系的話,你說這么多就象是對一群工科學生將哲學。你費再多的唇舌不過是對牛彈琴,雖然你講的是更深一個層次的東西,可是他們不能體會。所以有些東西只可意會,不可言傳呢 :mrgreen:  :mrgreen:

     mik 回復于:2005-07-20 16:03:47
    [quote:5609debd8d="FH"]誰說malloc返回0?哪份文檔上寫著?[/quote:5609debd8d]

    malloc 分配不成功,不返回 0 返回什么?

    返回NULL????

    char *p = (char *)malloc(sizeof(char) * N);
    if (!p) 有錯么?

     mq110 回復于:2005-07-20 16:07:18
    [quote:d0302e7551="mik"]

    malloc 分配不成功,不返回 0 返回什么?

    返回NULL????

    char *p = (char *)malloc(sizeof(char) * N);
    if (!p) 有錯么?[/quote:d0302e7551]

    [quote:d0302e7551]For calloc() and malloc(), the value returned is a pointer to the allo-
           cated  memory,  which  is suitably aligned for any kind of variable, or
           NULL if the request fails.[/quote:d0302e7551]

     mik 回復于:2005-07-20 16:14:05
    [quote:bca921867b="mq110"][/quote:bca921867b]

    本身 NULL 就是 0 的定義

    返回 0 并沒什么不妥


    while (*p)   與 while (*p != '\0')  本質是一樣的.只是風格與精簡的問題.

    *p = '\0';   與 *p = 0;  本質上也是一樣的. 在編譯器看來,并不分別.編譯后,內

    存單元都為 0

     mq110 回復于:2005-07-20 16:16:16
    誰告訴 你的NULL 是0??

    我就此 保持沉默. 
    你錯誤理解 與我無關.把你弄明白了 有我什么好處?

     gvim 回復于:2005-07-20 16:18:20
    [quote:7506918e07="mq110"]誰告訴 你的NULL 是0??

    我就此 保持沉默. 
    你錯誤理解 與我無關.把你弄明白了 有我什么好處?[/quote:7506918e07]

    呵呵, 兄弟醒悟了。。。。 :mrgreen:  :m01:

     高峰 回復于:2005-07-20 16:20:47
    善哉善哉!都怪我,沉下去的帖子被我捅了起來。
    阿彌陀佛。

     mq110 回復于:2005-07-20 16:25:11
    [quote:9177d9c798="gvim"]

    呵呵, 兄弟醒悟了。。。。 :mrgreen:  :m01:[/quote:9177d9c798]

    兄弟 其實我挺愛幫助人的. 不過最近胡攪蠻纏的人比較多.

     mik 回復于:2005-07-20 16:25:18
    :) 算了不吵也罷, 我是從本質上看問題...

    有些人初初看linuxunix內核源代碼,不少人說代碼是很難讀懂....

    并非是標準C... gcc本身就不完全是標準C....若linux一定要用標準C來寫的話.那

    就不是linux了

    另一方面,也阻礙了C的發展

     surfzsl 回復于:2005-07-20 16:48:43
    [quote:84c11e69e3="mik"]

    malloc 分配不成功,不返回 0 返回什么?

    返回NULL????

    char *p = (char *)malloc(sizeof(char) * N);
    if (!p) 有錯么?[/quote:84c11e69e3]
    man 3 malloc
    說的很明白
    有什么好爭的

     gvim 回復于:2005-07-20 16:51:54
    [quote:92d4b7fe0d="mq110"]

    兄弟 其實我挺愛幫助人的. 不過最近胡攪蠻纏的人比較多.[/quote:92d4b7fe0d]

    呵呵,遇到講道理,懂禮貌的誰都愿意幫,哪怕自己麻煩點。
    遇到“胡攪蠻纏”的,呵呵,還是及早醒悟的好。

     mike_chen 回復于:2005-07-20 16:53:12
    [quote:1d1e44f930="mik"]

    malloc 分配不成功,不返回 0 返回什么?

    返回NULL????

    char *p = (char *)malloc(sizeof(char) * N);
    if (!p) 有錯么?[/quote:1d1e44f930]
    malloc 分配不成功,當然是返回NULL了,man malloc!

     mike_chen 回復于:2005-07-20 17:00:15
    這個問題討論的還真是激烈! :mrgreen:

     mik 回復于:2005-07-20 22:54:17
    在 linux 下, malloc 函數在 glibc 庫中..

    查看 glibc 下 malloc 的實現代碼,可以得知:

    代碼中定義了: 
    #define __malloc_ptr_t  (void *)
    ....
    #define NULL  ((__malloc_ptr_t)0)
    ......

    而 malloc 的實現代碼中,出錯時只是簡單地 return 0;

    也就是說簡單地將 0 賦給了 __malloc_ptr_t  類型

    整個源代碼中,并沒有看見過 return NULL; 
    或是: return (__malloc_ptr_t)0; 之類的.

    雖然,在malloc的手冊上說明失敗時返回 NULL:
    事實上,只是將0作為返回值...

     AndyFastow 回復于:2005-07-21 00:47:35
    NULL is a pointer,it is ambiguous using (void *)0 to express it
    in C.
    so, for the latest languages, people fixed it.

     z16304607 回復于:2005-07-23 19:25:07
    1,按照標準來說NULL和0是一樣的int *p=new int(0)和int *p=new int(NULL)結果是一樣的。

    2,int *p=NULL和int *p=0;都是定義指針p并初始化指針p為指向0x00000000的地址(至少WINDOWS操作系統是這樣的)?!?x00000000”此地址可理解為空地址。當然你也可以自己寫個操作系統或編譯器把該地址定為“0xFFFFFFFF",甚至更變態的地址

    3,我們沒有必要討論NULL和0的區別。討論不出結果的,因為操作系統,編譯器已經做成這樣子了。

    char *p1=new char('1');
    char *p2="123456";
    cout<<p1<<endl;cout<<*p1<<endl;cout<<p2<<endl;cout<<*p2;
    char *p3="NULL";char *p3='0';
    char *p3=NULL;   char *p3=0;

    int *p6=0;int *p7=new int(0);
    cout<<p7<<endl;
    cout<<*p7<<endl;
    搞清楚以上這些就行了。
    int *p=0;
    int *p=1;//這個是錯的;

     z16304607 回復于:2005-07-23 19:28:12
    char *p3='0';更正char *p3="0";

     technologier 回復于:2005-07-23 20:37:51
    我記得標準C++,提倡使用0而不是NULL

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>