7

我正在阅读《Cracking the Coding interview (Q 1.2)》一书中问题的解决方案。目标是在 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)只会评估falseif stris 0,对吗?

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

4

10 回答 10

15

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

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

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

结论:您的代码将始终检测到空指针,但这在技术上与指向地址零的指针不同(即使在实践中您会发现它通常是)。

于 2013-07-22T08:46:14.887 回答
5
if(str)

相当于

if(str != NULL)

或者

if(str != 0)

该测试不是测试str地址是否为0,而是测试是否str为空指针。

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

C11 6.3.2.3指针

值为 0 的整型常量表达式或转换为 void * 类型的表达式称为空指针常量。66) 如果将空指针常量转换为指针类型,则生成的指针(称为空指针)为保证比较不等于指向任何对象或函数的指针。

于 2013-07-22T08:38:33.037 回答
3

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

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

为不指向任何东西的指针的值创建了 NULL 常量。现在 NULL 的值始终为 0。

于 2013-07-22T08:44:35.010 回答
2

所以我要说的是,str 是否没有机会包含地址 0x0000,从而将 if(str) 评估为 false?

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

这用作安全网,以防发生reverse()使用空指针调用的情况,以便代码在实际反转字符串时不会访问无效内存。

于 2013-07-22T08:39:27.880 回答
2

没有这样的机会,除非你传递一个NULL指向函数的指针。

在 C99 中引入布尔类型之前,C 中没有布尔类型。任何逻辑运算(包括条件)都会检查一个值是否为零,而不管它的真实类型。

于 2013-07-22T08:35:24.090 回答
1

在这里, str 包含一个地址,对吗?

是的。它是一个char *. 它的值表示 a 的地址char

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

是的。

str 是否没有机会包含地址 0x0000,从而将 if(str) 评估为 false?

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

char * myCharPointer = 0;
reverse(myCharPointer);

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

char * myCharPointer = NULL;
reverse(myCharPointer);

另请参阅这些相关问题:

于 2013-07-22T08:50:01.670 回答
1

是的,如果str任何架构上的 NULL 指针都0x000null pointer.

于 2013-07-22T08:38:35.717 回答
1

if(str)添加用于检查 str 是否已分配内存。最佳实践是在声明时初始化一个指针NULL

以上等于

if(str != NULL)
{

} 
于 2013-07-22T08:38:51.337 回答
1

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

于 2013-07-22T08:38:13.460 回答
1

该声明

if (str)

相当于

if (str != 0)

编译器又将其解释为

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

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

于 2013-07-23T02:58:34.290 回答