空指针究竟指向了内存的哪个地方?
大家都知道:
[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
你的说法并不正确.
请见翻译:
http://c-faq-chn.sourceforge.net/ccfaq/node59.html
特别是http://c-faq-chn.sourceforge.net/ccfaq/node69.html
[quote:7730b2a634="FH"]NULL不一定是0!这句话是俺今天第二次说。
NULL只是一个概念,叫作空值,其值本身没有任何含义,可以用0代替,也可以用1,...代替,只要这些值不会与系统实际的有效地址冲突即可。
因此,本人在此再次强调,不要自?..........[/quote:7730b2a634]
FH 回复于:2005-05-14 01:55:04
没觉得楼上引用的文字与俺的见解有什么冲突,相反,说得比俺更过火。比如:“每种指针类型都有一个空指针, 而不同类型的空指针的内部表示可能不尽相同。”再如:“空指针的内部 (或运行期) 表达形式, 这可能并不是全零, 而且对不用的指针类型可能不一样。”
qunying 回复于:2005-05-14 02:01:03
也许这一段可能更适合 对 if (!ptr) 的讨论http://c-faq-chn.sourceforge.net/ccfaq/node62.html
qunying 回复于:2005-05-14 02:13:45
[quote:450a3da0e5="FH"]没觉得楼上引用的文字与俺的见解有什么冲突,相反,说得比俺更过火。比如:“每种指针类型都有一个空指针, 而不同类型的空指针的内部表示可能不尽相同。”再如:“空指针的内部 (或运行期) 表达形式, 这可能并不是全..........[/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。
gvim 回复于:2005-05-16 21:56:01
no,no,no
NULL只是一个表示“空”“无”的概念,可是计算机不能用一个"实物"来表示“空”“无”等概念,所以只有借助辅助的手段。最常用的,而且数学中表示这个概念的,也就是0了。可是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 这种类型修饰符。
|