C - 空指针如何成为常量?

C - How is the Null Pointer a constant?

常量被定义为不能被程序改变的固定值。例如像 1, 2, 3, 'a' 这样的直接值,也像 #define CONSTANT 100

这样定义的常量

所以我在读空指针,

The NULL pointer is a constant with a value of zero defined in several standard libraries.

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

#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;
}

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

而且在那之前我读过。

It is always a good practice to assign a NULL value to a pointer variable in case you do not have exact address to be assigned

所以如果空指针是常量,那么当我们可以抓到我们想要的地址时,你怎么分配它,常量不能改变。

int *a = NULL; /* Declaration\Definition of pointer and initialization of NULL */

您的评论必须更改如下,这样会更清楚

Declaration\Definition of pointer and initialization with NULL

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

NULL 是一个常量。真实而真实。 a 指向的位置 不是 常量,这就是你在这里更改的位置:

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

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

int x = 1;
x = 2;

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

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

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

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

The NULL pointer is a constant

这个措辞可能会产生误导(而且也有很大的缺陷):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

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

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

一个指针变量 OTOH可以被修改。它可以设置为空指针值,使其成为空指针,但是没有将 指针 设置为另一个值时出现问题。改完之后就不是a空指针

这被标记为 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不是一个常量变量而是一个常量表达式。它是一个宏。宏是在编译时处理的常量表达式。

A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.

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

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

那样更改该变量