【问题标题】:Specific Value to a NULL Pointer指向 NULL 指针的特定值
【发布时间】:2015-10-03 17:11:35
【问题描述】:

我指的是What's the difference between a null pointer and a void pointer?中的NULL指针 根据@AnT 的帖子回复,“形式上,每个特定的指针类型(int *、char * 等)都有自己专用的空指针值”

我写了一个简单的程序。但是指针值对于整数或字符不是固定的。它有时会改变。那么我们如何才能得出指向 int 的 NULL 指针具有固定值的结论呢?指针的值也永远不会是 0。

 #include <stdio.h>

int main()
{
    int a;
    char *ptr; // Declaring a pointer without initializing it
    int *ptrToInt;

    if(ptr)
    {
        printf("Pointer is not NULL\n");
        printf("Value of pointer = %x\n",ptr);
        printf("Value of pointer = %x\n",ptrToInt);
    }
    else
    {
        printf("Pointer is NULL\n"); 
        printf("Value of pointer = %x",ptr);
        printf("Value of pointer = %x\n",ptrToInt);
    }
    return 0;
}

【问题讨论】:

  • 你的if(ptr) 是未定义的行为,因为ptr 是一个未初始化的自动变量。参见 C11 标准草案 6.2.4 Storage durations of objects, Section 6Annex J.2 Undefined behavior
  • 我没有看到任何空指针,只有两个未初始化的指针。
  • 应该是char *ptr = NULL;
  • 未初始化的指针不是空指针。
  • 并且不要打印带有整数格式字符串类型说明符的指针值,而是使用正确的"%p"!

标签: c pointers nul


【解决方案1】:

NULL 是一个值,表示任何类型的指针都无效,void* 是一个类型。在 C 或 C++ 中,常量 0 可以分配给任何类型的指针,并将其设置为该类型的空指针。常量NULL 可能被声明为0((void*)0),或者在不寻常的系统上的其他东西。

NULL 指针是任何类型的指针,已设置为无效值 NULL。您必须自己将其设置为该值;简单地留下一个没有初始化器的指针意味着它可能包含垃圾。 (从技术上讲,有一些例外,但请始终初始化您的变量。)

void* 是一种可以存储任何其他类型指针的类型(指向函数的指针除外)。它不能被取消引用,你不能像数组一样索引它或对它进行指针运算。它通常用作语法糖,让您调用诸如memset() 之类的函数,该函数仅将您提供的地址视为要填充的字节数组,或分配p = malloc(…),而无需显式转换。换句话说,当您只是将指针视为无类型的内存块,稍后将转换为某种类型的对象时,您并不关心哪个。

如果你想测试不同类型的空指针的位值,我建议转换为uintptr_t&lt;inttypes.h&gt; 中的printf() 格式说明符。在大多数但不是所有实现中,这些都将为零。

【讨论】:

  • 不幸的是,C 标准不要求空指针常量的类型为void *。没有“NULL指针”,而是一个空指针NULL 只是一个宏。 空指针常量 的实际值使用没有被标准定义。它只需要将 unequel 与任何有效的指针值进行比较。
  • 而你总是必须初始化一个auto变量;没有例外。唯一的区别是如何。您不需要 initializer,但也可以使用赋值。 void * 不是“语法糖”,而是必需的类型,因为它是唯一可以与任何其他对象指针相互转换的类型。
  • 添加 C++ 是一个非常糟糕的主意,因为 C++11 引入了真正的 nullptr,这与之前在两种语言中错误使用整数 0 明显不同。在 C++ 中使用 0 已被弃用(因此他们最终从 Pascal 等旧语言中学习)。希望 C 会跟进,但我并不乐观。
  • @Olaf:哎呀,更正了关于 NULL 类型的句子:通常但不能保证是 (void*)0
  • @nafsaka:宏NULL的定义有区别,分别。 空指针常量 标记(不幸的是整数常量0)和内部使用的实际值!这就是设计得更好的语言为这个特殊值使用保留字的原因。请注意,C++ 也引入了这样的保留字nullptr
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 2011-01-24
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多