什么是空指针用于

时间:2018-03-14 16:12:16

标签: c++ pointers null-pointer

我刚刚开始使用c ++,并发现它们是指针的空值。我很好奇这是用来做什么的。似乎添加一个指向什么都没有的指针是没有意义的。

5 个答案:

答案 0 :(得分:2)

好吧,空指针值具有非凡的属性,尽管它是一个定义良好且唯一的常量值,但确切的值取决于机器架构和ABI(在大多数现代的全位 - 零,不是那个它很重要,它从不指向(或仅仅在后面)一个对象。

这允许它在预期有效指针(函数可能抛出异常或终止执行)时使用它作为可靠的错误指示符,以及标记值,或标记缺少可选的东西。 / p>

在许多实现中,通过nullpointer访问内存将可靠地导致硬件异常(有些甚至是算术陷阱),但在许多其他实现上,尤其是那些没有分页和/或分段的情况下,它不会。

答案 1 :(得分:0)

通常它是一个占位符。如果您只是声明一个指针int *a;,则无法保证在您想要访问它时指针中的内容。因此,如果您的代码稍后可能会或可能不会设置指针,则无法判断指针是有效还是仅指向垃圾内存。但是,如果您将其声明为NULL,例如int *a = NULL;,则可以稍后检查指针是否已设置,例如if(a == NULL)

在初始化期间的大部分时间我们都会为指针分配空值,以便我们可以检查它是否仍为空或者是否已为其分配地址。

答案 2 :(得分:0)

  

添加指向指向的指针似乎毫无意义   什么都没有。

不,不是。假设您有一个返回可选动态分配值的函数。当你想要回归"什么都没有"你返回null。调用者可以检查空值并区分两种不同的情况:当返回值是"没有"当返回值是某个有效的可用对象时。

答案 3 :(得分:-1)

C和C ++中的null值等于0.但C ++中的nullptr与它不同,nullptr始终是C ++中的指针类型。我们出于各种原因为指针变量赋值空值。

  
      
  1. 检查是否已将内存分配给指针
  2.   
  3. 中和悬空指针,使其不会产生任何副作用
  4.   
  5. 检查退货地址是否为有效地址等。
  6.   

在初始化期间的大部分时间我们都会为指针分配空值,以便我们可以检查它是否仍为空或者是否已为其分配地址。

答案 4 :(得分:-2)

基本上,指针只是整数。空指针是一个值为0的指针。它没有严格指向任何内容,它指向绝对地址0,这通常是程序无法访问的;取消引用它会导致错误。

它通常用作标志值,因此您可以使用它来结束循环。

<强>更新

似乎有很多人对这个答案感到困惑,严格来说,这是完全正确的。见C11(ISO / IEC 9899:201x)§6.3.2.3指针第3节:

  

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

那么,地址是什么?它是一个数字 n ,其中0≤ n max_address。我们如何代表这样的数字?为什么,它是一个整数,就像标准所说的那样。

C11标准清楚地表明在地址0处从来没有任何东西要引用,因为在BSD 4.2中的一些旧的病态非可移植代码中,你经常看到这样的代码:

/* DON'T TRY THIS AT HOME */

int
main(){
    char target[100] ;
    char * tp = &target ;
    char * src = "This won't do what you think." ;
    void exit(int);

    while((*tp++ = *src++))
        ;

    exit(0);
}

这仍然有效C:

$ gcc -o dumb dumb.c
dumb.c:6:12: warning: incompatible pointer types initializing 'char *' with an
      expression of type 'char (*)[100]' [-Wincompatible-pointer-types]
    char * tp = &target ;
           ^    ~~~~~~~
1 warning generated.
$ 

在VAX上的4.2BSD中,你可以逃避这种废话,因为地址0可靠地包含了 0,因此赋值被评估为0,当然是假的。

现在,来证明:

/* Very simple program dereferencing a NULL pointer. */

int
main() {
    int * a_pointer ;
    int a_value ;
    void exit(int);             /* To avoid any #includes */

    a_pointer = ((void*)0);
    a_value = *a_pointer ;

    exit(0);
}

结果如下:

$ gcc -o null null.c
$ ./null
Segmentation fault: 11
$