flw 回復于:2004-09-10 16:45:16 |
在 VC 中,把鼠標挪到“NULL”這個字上面,它就原形畢露了。 |
ljttlf 回復于:2004-09-10 16:47:54 |
c里面好象定義為(void *)0 ,但這個不是嚴謹的定義,在哪本書上看見的更復雜,記不太清楚了. |
shitalone 回復于:2004-09-10 16:50:50 |
呵呵,多謝。我看到了,原來是0
或者是(void *)0 |
aero 回復于:2004-09-10 16:53:14 |
^_^,樓主的推論蠻有意思的,不過是錯誤的,讓p = NULL只不過是一種習慣而已。你可以指向別的,但不能說NULL 可以是很多值哦。
下面是/usr/include/linux下的stddef.h文件中的NULL定義: [code:1:7f6e418f04] #undef NULL #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0) #endif [/code:1:7f6e418f04] |
converse 回復于:2004-09-10 17:26:45 |
>>意思是讓指針失效,那么這時候p的值是多少?
此時p的值是0,c語言規定,對0指針的訪問無效 >>也就是說,只要p指向的地址程序不可訪問,p就是NULL。 >>所以NULL可以是很多不同的值。 p == NULL 那么p指向的地址程序不可訪問,反之不然,因為不可訪問的地址很多,NULL值就是零,沒有別的值. 標準規定了NULL指針,它作為一個特殊的指針變量,表示不指向任何東西,要使一個指針變量為NULL,可以給它賦一個零值,為了測試一個指針變量是否為NULL,可以將它與零值比較.之所以選擇零值是因為一個源代碼約定,就機器內部而言,指針的實際值可能與此不同.在這種情況下,編譯器負責零值和內部值之間的翻譯轉換. --上面這段話選自<<c和指針>>p96 |
JohnBull 回復于:2004-09-11 11:53:06 |
NULL完全就是(void*)0,并不特殊.
C語言沒有任何對于NULL的特殊語法和語義定義. 參見stddef.h: [code:1:a18bc77e85] #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0) #endif [/code:1:a18bc77e85] |
ljttlf 回復于:2004-09-11 12:12:43 |
>>NULL完全就是(void*)0,并不特殊.
有特殊,而且NULL ((void *)0)不是適合所有平臺的寫法,也就是說不是嚴謹的寫法,幾年以前我看了篇文章專門討論NULL ((void *)0) 的問題,外國人寫的,名字我忘了,當時 對c 的理解不到位沒有看懂,只記得NULL ((void *)0)不嚴謹這句話。 我再翻翻書看是什么文章,找到的話我給大家貼出來。 |
win_hate 回復于:2004-09-12 21:00:02 |
in c:
1、The NULL is nothing but (void *)0 because the standard say that is. 2、In different implementation, if p = (void *)0, p may be not all bits zero. It seem to be odd, but look at this, if double x = 0, x may be not all bits zero. |
ljttlf 回復于:2004-09-12 21:52:10 |
Many programs and utilities were written using UNIX on VAX computers. On this
computer, the first byte of any program is 0. Many programs written on this computer contain a bug—they use the null pointer as a string. For example: #ifndef NULL #define NULL ((char *)0) #endif NULL char *string; string = NULL; printf("String is '%s'\n", string); This code is actually an illegal use of string. Null pointers should never be dereferenced. On the VAX, this error causes no problems. Because byte of the program is 0, string points to a null string. This result is due to luck, not design. On a VAX, the following result is produced: String is '' On a Celerity computer, the first byte of the program is a 'Q'. When this program is run on a C1200, it produces: String is 'Q' On other computers, this type of code can generate unexpected results. Many of the utilities ported from a VAX to a Celerity exhibited the 'Q' bug. Many of the newer compilers will now check for NULL and print: String is (null) This message does not mean that printing NULL is not an error. It means that the error is so common that the compiler makers decided to give the programmer a safety .net. The idea is that when the error oclearcase/" target="_blank" >ccurs, the program prints something reasonable instead of crashing. |
ljttlf 回復于:2004-09-12 21:53:25 |
移植性問題。我看得文章就是基于這個問題討論的,但是我現在找不到原文了。
這個議題保留,我再看看找的到不。 |
JohnBull 回復于:2004-09-13 14:28:31 |
1. It says that define NULL as (void*)0 is not a good idea on UNIX.
But the bad idea is the TRUTH. 2. I said "C語言沒有任何對于NULL的特殊語法和語義定義" which means that NULL is not a keyword of C. Most C implementations define it as a macro not anything INSIDE C. |
win_hate 回復于:2004-09-13 16:36:19 |
[quote:1c8c9debf3="ISO/IEC 9899:1999(E)"]
7 library 7.17 Commnd definitions <stddef.h> 3 The macros are (pg 253) NULL which expands to an implementation-defined null pointer constant; 6. Language 6.3.2.3 Pointers (pg 47) 3 An interger constant expression with the value 0, or such an expression cast to type void * is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guarranteed to compare unequal to a pointer to any object or function. [/quote:1c8c9debf3] |
win_hate 回復于:2004-09-13 16:46:02 |
[quote:55b1deaa2b="ljttlf"]移植性問題。我看得文章就是基于這個問題討論的,但是我現在找不到原文了。
這個議題保留,我再看看找的到不。[/quote:55b1deaa2b] from Your post : [quote:55b1deaa2b] Many programs written on this computer contain a bug—they use the null pointer as a string. ......... This code is actually an illegal use of string. Null pointers should never be dereferenced. [/quote:55b1deaa2b] It says [color=red:55b1deaa2b]use the null pointer as a string[/color:55b1deaa2b] is a bug, but It dose not say NULL = (void *)0 is a bug. right? waitting for you post, :D ps> the null pointer constant is (void *)0 now, not (char *)0. |
思一克 回復于:2004-09-13 16:54:08 |
這本來不是什么問題值得討論的。
如果要說,JohnBull 和 win_hate 都是對的。NULL其實不是C語言本身的內容,僅僅是人們編程是的習慣定義。在*.h文件中的#define出來的常量都不是語言本身的內容。 ljttlf 你這句話是什么意思? On this computer, the first byte of any program is 0. |
ming_study 回復于:2004-09-13 17:23:43 |
在AIX Version 5中的定義是這樣的
#ifndef NULL #define NULL 0 #endif |
ming_study 回復于:2004-09-13 17:35:23 |
The symbolic constant NULL is often used in place of zero. as a mnemonic to indecate more clearly that this is a special value for a pointer. |
Blacklac 回復于:2004-09-13 18:07:53 |
is 0 |
ljttlf 回復于:2004-09-13 20:57:51 |
>>but It dose not say NULL = (void *)0 is a bug. right
是的, 我只是說了 NULL = (void *)0 是個不嚴謹的定義,沒有說是個BUG :) >>It says that define NULL as (void*)0 is not a good idea on UNIX.But the bad idea is the TRUTH. 確實,計算機科學本身就是折中的結果,比如速度與價格,才會發展出幾級緩寸的問題,如果是理想的話,內存直接用寄存器做就是了. 文章是說的C1200上(void *)0就會有問題了,而且只是移植上的問題,相信我們沒有幾個人用過這個玩意. ps:這篇文章是<實用c語言編程里面的> |
win_hate 回復于:2004-09-13 21:16:24 |
[quote:bcac8a5669="ljttlf"]>>but It dose not say NULL = (void *)0 is a bug. right
是的, 我只是說了 NULL = (void *)0 是個不嚴謹的定義,沒有說是個BUG icon_smile.gif [/quote:bcac8a5669] I study your post carefully. I think the main idea is "use the null pointer as a string" is illegal, nothing elae. It dose not say (voidr *0) is good or bad. [quote:bcac8a5669] 移植性問題。我看得文章就是基于這個問題討論的,但是我現在找不到原文了。 這個議題保留,我再看看找的到不。 [/quote:bcac8a5669] still, I waitting for this. :D |
win_hate 回復于:2004-09-13 21:23:05 |
[quote:9e74610376="ming_study"]在AIX Version 5中的定義是這樣的
#ifndef NULL #define NULL 0 #endif[/quote:9e74610376] What you say is c++ or c? In my opinion, the implemention should obey the standard. If that C compiler on AIX define NULL as 0, it's not ANSI conformance。 make NULL a 0, will arose some subtile bug in some platform. |
ljttlf 回復于:2004-09-13 21:34:06 |
>>make NULL a 0, will arose some subtitle bug in some platform
可是C++他爸爸建議大家 make NULL a 0 ?為什么呢? >>Many programs written on this computer contain a bug—they use the null pointer as a string 換句話說,如果(void*)0嚴謹的話,就不會出現問題?。海┒还軐ull做為什么,不是嗎? 就象一個數學的定義,嚴謹的方式是需要論述所有方面的。正因為硬件的多樣性,才不可能保證所有事情的嚴謹性,不是C++委員會也是不段修改所有抹零兩可的地方嗎:) |
ljttlf 回復于:2004-09-13 21:36:21 |
從頭到尾,我也沒有說過(void*)0的寫法是錯誤的,我只是說是個不嚴謹的定義,不是嗎,如果嚴謹,可能不會有上面那段話,至于我看的文章, 我再盡力找找, 我現在在上學,只有等國慶回家看看以前的書。 |
win_hate 回復于:2004-09-13 21:41:56 |
[quote:521d19fd35="ljttlf"]>>make NULL a 0, will arose some subtitle bug in some platform
可是C++他爸爸建議大家 make NULL a 0 ?為什么呢? [/quote:521d19fd35] c++ and c, are different. I just talk about c, not c++. [quote:521d19fd35] 換句話說,如果(void*)0嚴謹的話,就不會出現問題?。海┒还軐ull做為什么,不是嗎? [/quote:521d19fd35] no, no, no, in any situation, "Null pointers should never be dereferenced" |
win_hate 回復于:2004-09-14 00:44:22 |
to ljttlf:
你說的問題我查到了: [quote:59bd833121="《c陷阱與缺陷》"] 7. 可移植性缺陷 7.6 內存位置 0 null 指針并不指向任何對象。因此,除非是用于賦值或比較運算,出于其他任何目的使用null指針都是非法的。例如,如果p 或q 是一個null,那么strcmp (p,q)的值就是未定義的。 在這種情況下究竟會得到什么結果呢?不同的編譯器有不同的結果。某些c語實現對內存位置0強加了硬件級的讀保護,在其上工作的程序如果錯誤使用了一個null指針,將立即終止執行。其他一些c語言實現對內存位置0只允許讀,不允寫。在這種情況下,一個null指針似乎指向的是某個字符串,但其內容通常不過是一堆“垃圾信息”。還有一些c語言實現對內存0位置既允許讀,又允許寫。在這種實現上面工作的程序如果錯誤使用了一個null指針,則很可能覆蓋了操作系統的部分內容,造成徹底的災難。 [color=red:59bd833121]嚴格來說,這并非一個可移植性問題:在所有的c程序中,誤用null指針的結果都是未定義的。[/color:59bd833121]然而,這樣的程序有可能在某個c語言實現上“似乎”能正常工作,只有當該程序轉移到另一臺機器上運行時才會暴露出問題來。 要檢查出這類問題的最簡單辦法就是,把程序移到不允許讀取內存位置0的機器上運行。下面的程序將揭示出某個c語言實現是任何處理內存地址0的: [code:1:59bd833121] #include <stdio.h> main() { char *p; p = NULL; printf ("Location 0 contains %d\n", *p); } [/code:1:59bd833121] 在禁止讀取內存地址0的機器上,這個程序會執行失敗。在其他機器上,這個程序會以10進制的格式打印出內存位置0中存儲的字符內容。 [/quote:59bd833121] 從上面的內容可以看出,如果說有誰不嚴謹了,那必定是讀取內存位置0的程序員,而不是c。c 的設計哲學之一是:程序員知道自己在干什么-----沒有安全帶。 |
FH 回復于:2004-09-14 09:25:32 |
[quote:3c891bc4e8="win_hate"]從上面的內容可以看出,如果說有誰不嚴謹了,那必定是讀取內存位置0的程序員,而不是c。c 的設計哲學之一是:程序員知道自己在干什么-----沒有安全帶。[/quote:3c891bc4e8]
贊同! |
ljttlf 回復于:2004-09-14 10:28:12 |
呵呵, 等我找到文章再說了:)
這個問題當然仁者見仁了, 你看的是《c陷阱與缺陷》,我找的是《實用C語言編程》, 我也只是說“在移植問題上的不嚴謹”,而我讀的文章只是討論如何找到一個定義,適合所有的硬件使他在諸如c2100上沒有所謂的“Q”BUG問題。 >>c 的設計哲學之一是:程序員知道自己在干什么-----沒有安全帶 正因為如此,才會有如此多的緩沖區益處問題,你說對嗎? 而我們現在討論NULL的問題,也只是想找到一個方法避免誤用null帶來的潛在的危險(我看的文章也是基于這個論點,才的出的論點是NULL定義不嚴謹)。 就象一個物理定義一樣,我們可以定義“時間是永恒,不變的”,這是真理,但是我們還可以定義“時間是可辯的,當速度接近光速時”。那你可以說上面那個真理是嚴謹的嗎?當然可以為他加上時間限制。那么我們至少可以這樣認為“((void*)0)”不是適合所有平臺的定義。 呵呵,小弟最近在學自然辨證法, 發表的觀點有點饒口哈。 我想我們現在沒有必要為這個討論,當大家在現實中遇到問題的時候再討論不是更有意義,畢竟實踐是檢驗真理的唯一標準。 |
win_hate 回復于:2004-09-14 10:56:40 |
NULL 的出現估計是有部分程序員敲 ((void *)0) 敲煩了, 用 NULL 來代替。
>> 那么我們至少可以這樣認為“((void*)0)”不是適合所有平臺的定義。 ((void *)0) 不必是零,其物理表示由具體的平臺,實現決定-----如果在哪個平臺上出了問題,那多半是實現的問題。我強調一點:按標準, ((void *)0) 是個抽象的東西,區別于其他指針,確保與任何地址相比較而不等。 >>就象一個物理定義一樣,我們可以定義 物理的定義受物理世界的約束,但計算機的很多東西是人為制定,沒有什么理由的。 >>正因為如此,才會有如此多的緩沖區益處問題 c 特別容易出這個問題, 它當然不是完美的。不過,dereferenced 一個零指針可是一個低級錯誤哦。 >>我想我們現在沒有必要為這個討論,當大家在現實中遇到問題的時候再討論不是更有意義,畢竟實踐是檢驗真理的唯一標準。 ok. |
lixuzhang 回復于:2004-09-14 14:14:16 |
我的理解:
出現NULL的原因或它的意義在于需要有一個表示指向并不存在的東西的指針。但這總得用某一個數來表示呀。所以具體實現就是選用零地址來代替的,因為不可能有變量或東西是放在零地址的。這相當于一個協定。如果我們當初協定(void*)1是代表并不存在的東西同樣也可以呀。但只是用0來表示比用1表示更恰當而已。正如true和false是用1和0表示,還是用枚舉來表示是一樣的道理。關鍵在于,一旦確定,大家必須遵守相同的規則。 因為NULL代表是不存在的東西,所以求存放于NULL地址的數值也就沒有意義了,具體到實現就是沒有定義,沒有人知道NULL地址會是什么東西。 我們用指針,當它不指向任何東西的時候,就得讓它變成NULL。不然它就是一個“野”指針。我們使用指針時也同樣得先判斷它是不是NULL,必須不是NULL了才可以使用它,這個指針才有意義。 如果指針不應該指向任何東西,卻沒有設為NULL,也成為就是野指針時;調用者或使用者怎么知道你這個指針是不是有意義呢?所以使用者一旦對你這個“野”指針求值(*p)或賦值,就有可能出錯——讀錯數據或寫錯地方。 |
bitstream 回復于:2004-09-14 15:14:54 |
在C里面是 #define NULL 0
在C++里面是 #define NULL ((void *)0) |
ming_study 回復于:2004-09-14 20:26:01 |
我認為:
NULL是針對指針而言的,來表明這個指針不指向任何東西, 指針為空 |
step_by_step 回復于:2004-09-22 15:08:12 |
這種問題有什么好吵的啊.
看標準就是了 |
夢藍 回復于:2004-09-22 17:59:11 |
p是一個指針,在系統中有4個字節(32位系統下)保存它的值,這個值是一個內存的地址,通過這個地址可以訪問到目的數據。
當我們把它的值賦為NULL時,也就是它把指向一個不存在的內存地址,這樣才能保證讀取的不是臟數據。 |
stkeke 回復于:2004-09-23 09:18:25 |
APUE Page 525
ANSI C并不保證整數0和浮點0相同,也不保證整數0與NULL指針相同。 |
dingdangbear 回復于:2004-09-24 16:00:53 |
(void*) 0 是什么意思?
和0有什么區別? |
Joinhack 回復于:2004-09-24 19:07:05 |
NULL其實用字符來表示可以定義為'\0' |
獨孤九筒 回復于:2004-10-03 00:08:54 |
是個宏 |
xzh2002 回復于:2005-01-02 13:37:13 |
NULL就是0吧 |
ificanfly 回復于:2005-01-02 15:42:32 |
不同的硬件NULL的值不一定一樣啦。
CPU決定訪問某個或者某段地址時發生中斷或者以其他方式,通知OS。 若C標準化此值,那CPU設計者就得遵從。 你設計一個CPU不允許訪問0x40000,否則發生異常,不行嗎?沒人阻攔你. |
twen345 回復于:2005-01-04 18:04:43 |
NULL是個好東東,你沒有感覺到嗎? |
eagerly1 回復于:2005-01-04 20:01:48 |
就將它理解為數學中的無窮大符號吧,僅僅表示一個方向。 |
海狼unix 回復于:2005-04-10 12:12:30 |
[size=18:3157146dbd]我是C和C++的初學者,請教個師兄,
代碼: #undef NULL #if defined(__cplusplus) #define NULL 0 #else #define NULL ((void *)0) #endif 的undef 是用來定義什么的,及 ifndef又是用來定義什么含義。[/size:3157146dbd] |
Alligator27 回復于:2005-04-10 22:44:29 |
[quote:da20bde0bc="dingdangbear"](void*) 0 是什么意思?
和0有什么區別?[/quote:da20bde0bc] (void*) 是告訴compiler, 這里的0是指針, 而不是char, int, float等其它類型. 不同的類型會有不同的機器代表方式. |