在C语言中,指针的地址可以是0吗?

在C语言中,指针的地址可以是0吗?,c,pointers,C,Pointers,我正在读书中一个问题的解决方案(问题1.2)。这里的目标是在C中实现一个函数void reverse(char*str),该函数可以反转空终止字符串 解决方案代码如下所示: void reverse(char *str) { char* end=str; char tmp; if(str) { while(*end) { end++; } end--; //code to rever

我正在读书中一个问题的解决方案(问题1.2)。这里的目标是在C中实现一个函数
void reverse(char*str)
,该函数可以反转空终止字符串

解决方案代码如下所示:

void reverse(char *str)
{
   char* end=str;
   char tmp;
   if(str)
   {
       while(*end)
       {
          end++;
       }
       end--;
       //code to reverse
   }
}
这里,
str
包含一个地址,对吗?而
if(str)
将只计算为
false
if
str
0
,对吗


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

没有这种可能性,除非将
NULL
指针传递给函数


在C语言中,直到在C99中引入布尔类型,才出现布尔类型。任何逻辑操作(包括条件)都会根据零检查一个值,而不管它的实际类型如何。

如果你问我是否应该测试函数中是否有人通过空指针,那么答案是肯定的

if(str)
相当于

if(str != NULL)

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

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

C11 6.3.2.3指针

值为0的整型常量表达式,或转换为类型的此类表达式 void*,称为空指针常量。66)如果将空指针常量转换为 指针类型,结果指针称为空指针,保证与指向任何对象或函数的指针进行不相等的比较


是的,如果
str
是任何体系结构上的空指针,并且该体系结构为
空指针
保留了地址
0x000
如果添加了(str)
,则可以检查str是否分配了内存。最佳实践是在声明时初始化指向
NULL
的指针

以上等于

if(str != NULL)
{

} 
所以我想说的是,str是否不可能包含地址0x0000,从而评估(str)是否为false

是的,有:如果您使用空指针调用
reverse()
,它将计算为false


这是一个安全网,以防使用空指针调用
reverse()
,这样代码在实际反转字符串时不会访问无效内存。

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

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


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

str
确实包含一个地址(它是指向
char
的指针),如果
if(str)
将在
str
等于NULL指针时计算为false

请注意,本标准不要求空指针引用地址
0
;但是,本标准要求编译器必须将
0
的文本值解释为空指针的地址,不管是什么

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

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

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

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

如果str为0,if(str)将只计算为false,对吗

str不可能包含地址0x0000,因此 评估(str)是否为false

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

char * myCharPointer = 0;
reverse(myCharPointer);
不过,我从来没有使用过这种样式。我更喜欢使用NULL,这是C标准保证的等价形式。我更喜欢NULL,因为它更具表现力,并且有助于将普通整数值与地址分开

char * myCharPointer = NULL;
reverse(myCharPointer);
另见这些相关问题:

    • 声明

      if (str)
      
      相当于

      if (str != 0)
      
      编译器又将其解释为

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

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

      我能为您提供一个关于simil的答案吗ar问题?除非您自己将
      str
      作为零传递给函数。@ludesign啊,未定义行为的乐趣……为什么不:
      reverse(0)
      @ludesign即使在某些情况下由一个编译器执行,未指定的行为根据定义是未指定的,不应该被信任。您如何知道
      reverse()
      不是用0指针调用的?当然,我的意思是如果你传递了一个有效的指针。我会修正一个答案来澄清。哦,看来我误解了这个问题。抱歉。在C99中引入了布尔类型。我不同意。函数没有责任检查它是否得到有效的参数。如果有人做出了“错误的调用”通过传递
      NULL
      指针,好吧,让程序崩溃。当然,这在很大程度上取决于上下文,因此它可能不适用于海报的情况。@Xaqq它将取决于
      if (str != null-pointer-value-for-char-pointer-type)