【问题标题】:C - How is the Null Pointer a constant?C - 空指针如何成为常数?
【发布时间】:2015-07-04 14:27:13
【问题描述】:

常量定义为程序无法更改的固定值。1, 2, 3, 'a' 这样的直接值以及像#define CONSTANT 100 这样定义的常量

所以我正在阅读有关空指针的信息,

NULL 指针是一个常量,在几个标准库中定义为零值。

但是指针变量是可以改变的,证明:

#include <stdio.h>

int main()
{
    int *a = NULL; /* Declaration\Definition of pointer and initialization of NULL */
    int b; /* Regular Declaration\Definition of variable */

    a = &b; /* pointer now stores memory address of b variable */

    return 0;
}

所以如果空指针是常量,那我怎么编译它没有错误。

在那之前我也读过。

如果您没有要分配的确切地址,最好将 NULL 值分配给指针变量

所以如果Null Pointer是常量,那么当我们可以获取到我们想要的地址时,你怎么分配它,常量是不能改变的。

【问题讨论】:

  • NULL 指针是常量。 null 指针不一定是常量。该引用专门讨论了宏NULL,它是一个常量表达式。
  • 怎么样double val = MATH_PI; 然后val = 3.0; ??您已经分配了一个常量的变量 de 值,然后您已经为其分配了另一个(不同的)常量。常量是值,变量是存储该值的位置。试试这个:const double pi = 3.141592; 然后尝试给它赋值(在这种情况下 pi 不是变量,它是一个常量,编译器不允许你改变它的值。

标签: c pointers constants


【解决方案1】:

出于同样的原因,这很有效:

int x = 1;
x = 2;

你正在复制一个常量到一个可变变量中,然后改变那个变量。这不会以任何方式影响常量,因为它是一个副本。

如果你复制一本书,然后在副本中记笔记,原书是否有相同的笔记?

【讨论】:

    【解决方案2】:

    NULL 是一个常数。真实而真实。 a 指向的位置不是常量,这就是您在此处更改的内容:

    a = &b; /* pointer now stores memory address of b variable */ 
    

    【讨论】:

      【解决方案3】:

      NULL 有一个常量值,您可以将其分配给任何变量。这并不意味着变量应该是常数。

      e.g. const int a = 2;
           int b = a;    // this statement is valid
      

      【讨论】:

        【解决方案4】:

        NULL 指针是一个常量

        这个措辞可能会产生误导(也有相当大的缺陷):NULL 是一个空指针常量。 NULL 指针是指向 NULL 的指针。您可以获得NULL 指针,但不能更改NULL 扩展为的内容,即空指针常量

        int *ptr = NULL;
        ptr = &variable; // ok
        
        int *const ptr2 = NULL;
        ptr2 = &variable; // fails: ptr2 is a const pointer
        
        ++NULL; // fails: expression not assignable
        

        【讨论】:

          【解决方案5】:
          int *a = NULL; /* Declaration\Definition of pointer and initialization of NULL */
          

          您的评论必须更改如下,它会明确

          指针的声明\定义和​​用NULL初始化

          NULL指针是指在内存中没有地址的指针,或者根据NULL的定义,内存地址为0。

          【讨论】:

            【解决方案6】:

            这是标记为C,但从C++ 的角度来看,请查看以下代码。

            #include <iostream>
            
            #define NULL 0
            const int null = 0;
            
            int main(){
            
                int var1 = NULL; //can do (copy NULL into var1)
                int var2 = null; //can do (copy null into var2)
                int &var3 = NULL; //can't do, NULL is not in memory so it can't be referenced
                                  //same as doing int &var3 = 0
                const int &var4 = NULL; //can do, creates a constant reference for the value of NULL
                                  // same as const int &var4 = 0
                int &var5 = null; //can't do, null is in memory thus can be referenced
                                  //but the reference has to be a constant
                const int &var6 = null; //can do, references null with a constant reference 
            
                var1++; //can do
                var2++; // also can do
                var3++; //this is folly
                var4++; //can't do, it's a constant
                var5++; //this is also a folly
                var6++;  //can't do, it's a constant
                NULL++; //can't do NULL isn't a variable (lvalue), same as doing 0++
                null++; //can't do null is a constant
            
            }
            

            从上面的代码来看,NULL 不是一个常量变量,而是一个常量表达式。它是一个宏。宏是在编译时处理的常量表达式。

            宏是已命名的代码片段。每当 名称被使用,它被宏的内容替换。那里 是两种宏。它们的主要区别在于它们的外观 当它们被使用时。类对象宏在以下情况下类似于数据对象 使用的类似函数的宏类似于函数调用。

            我也这样做#define log std::cerr,但它不会使 log 成为变量,尽管它确实使它成为常量。可以像上面NULL 那样重新定义宏。

            另一方面,null 是一个常量变量。任何指向它的指针或引用也必须是常量以保持其不变性。但它的值可以复制到另一个变量中,并且可以像 var2 那样更改该变量。

            【讨论】:

              【解决方案7】:

              (仅)空指针值实际上是一个常量:它是一个特定的、固定的值。 IOW:只有一个值表示将指针设为空指针

              NULL 代表空指针值。预处理器将用 textual 替换来替换其名称(与其他宏一样)。然后将文本传递给 C 编译器。

              指针变量 OTOH 可以修改。它可以设置为空指针的值,使其成为空指针,但是设置指针 到另一个值。经过这次改动,它不再是a 空指针了。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2023-03-17
                • 2015-04-12
                • 1970-01-01
                • 1970-01-01
                • 2011-10-01
                • 2023-03-15
                • 1970-01-01
                • 2023-03-12
                相关资源
                最近更新 更多