在C中,指针的地址可以为0吗?

时间:2013-07-22 08:33:35

标签: c pointers

我正在阅读书Cracking the Coding interview(问题1)中的问题解决方案。目标是在C中实现一个反转空终止字符串的函数void revers(char* str)

解决方案代码如下所示:

void reverse(char *str)
{
   char* end=str;
   char tmp;
   if(str)
   {
       while(*end)
       {
          end++;
       }
       end--;
       //code to reverse
   }
}

在这里,str包含一个地址吗?如果if(str)falsestr只评估为0,对吗?

所以我要说的是,str是否有可能包含地址0x0000,从而评估if(str)false

10 个答案:

答案 0 :(得分:13)

str确实包含一个地址(它是指向char的指针),如果if(str)等于null,str将评估为false 指针

请注意,标准不要求空指针引用地址0;但是,标准要求在指针上下文中使用的{em>文字值时,必须由编译器将其解释为空指针的地址 - 无论可能是什么。

这意味着保证测试0始终与if(p == 0)相同。此外,条件if(p == NULL)保证始终与if(p)相同。

结论:你的代码总是会检测到一个空指针,但是在技术上与指向零地址的指针不同(即使在实践中你会发现它通常是)

答案 1 :(得分:5)

if(str)

等同于

if(str != NULL)

if(str != 0)

此测试不是测试str是否具有0的地址,而是测试str是否为空指针。

请注意,空指针不必具有地址0,标准只能确保空指针不等于任何其他非空指针。

C11 6.3.2.3 指针

  

一个整数常量表达式,其值为0,或者这样的表达式强制转换为类型   void *,被称为空指针常量.66)如果将空指针常量转换为a   指针类型,结果指针,称为空指针,保证比较不等于指向任何对象或函数的指针。

答案 2 :(得分:3)

理论上0x0指针是有效的,但是现在所有编译器都不会给你虚拟地址0,因为它被保留来表示空指针(指向什么都没有)。

某些内核可能仍在使用它,但除非你在非常罕见的内核中编写非常低级别的内容,否则可以假设0x0没有指向任何内存。

为指针未指向任何内容的值创建了NULL常量。现在NULL始终为0。

答案 3 :(得分:2)

除非你将NULL指针传递给函数,否则没有这样的机会

在C中,除非在C99中引入,否则没有布尔类型。无论其实际类型如何,任何逻辑运算(包括条件)都会将值检查为零。

答案 4 :(得分:2)

  

所以我所说的是,str是否有可能包含地址0x0000,从而评估if(str)是否为假?

是的,如果您使用空指针调用reverse(),它将评估为false。

如果发生使用空指针调用reverse(),则将其用作安全网,以便在实际反转字符串时代码不会访问无效内存。

答案 5 :(得分:1)

如果你问我应该测试在我的函数中传递NULL指针的人,那么答案是肯定的。

答案 6 :(得分:1)

是的,如果str是任何为0x000保留地址null pointer的架构上的NULL指针,则可能。

答案 7 :(得分:1)

添加

if(str)以检查str是否已分配内存。最佳做法是在声明时初始化指向NULL的指针。

以上等于

if(str != NULL)
{

} 

答案 8 :(得分:1)

  

这里,str包含一个地址吧?

是。这是char *。其值表示char的地址。

  

如果str为0,那么(str)只会评估为false,对吗?

  

因此str不可能包含地址0x0000   评估if(str)为false?

这是完全可能的。只需使用此值调用该函数。

char * myCharPointer = 0;
reverse(myCharPointer);

但我从不使用这种风格。我更喜欢使用NULL,这是C标准保证的等价物。我更喜欢NULL,因为它更具表现力,它有助于将普通整数值与地址分开。

char * myCharPointer = NULL;
reverse(myCharPointer);

另见这些相关问题:

答案 9 :(得分:1)

声明

if (str)

相当于

if (str != 0)

又由编译器解释为

if (str != null-pointer-value-for-char-pointer-type)

即。它与“地址零”无关。编译器需要识别指针上下文,并与类型char *的依赖于实现的空指针值进行比较。后者将通过依赖于实现的地址值进行物理表示,不一定是零地址。