首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >可以将C指针初始化为NULL吗?

可以将C指针初始化为NULL吗?
EN

Stack Overflow用户
提问于 2017-04-11 14:15:27
回答 8查看 43.4K关注 0票数 92

我一直在写这样的东西

char *x=NULL;

假设

 char *x=2;

将创建指向地址2的char指针。

但是,在The GNU C Programming Tutorial中,它说int *my_int_ptr = 2;在分配时将整数值2存储到my_int_ptr中的任何随机地址。

这似乎意味着我自己的char *x=NULLNULL强制转换为char的值分配给内存中的某个随机地址。

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

实际上,打印

为空

当我编译和运行它时,我担心我依赖于未定义的行为,或者至少是未指定的行为,并且我应该编写

char *x;
x=NULL;

而不是。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2017-04-11 14:18:55

是否可以将C指针初始化为NULL?

TL;Dr.是的,非常喜欢。

The reads like

另一方面,如果您只使用单个初始赋值int *my_int_ptr = 2;__,程序将尝试用值2填充my_int_ptr指向的内存位置的内容。因为my_int_ptr充满了垃圾,所以它可以是任何地址。..。

好吧,他们是错的,你是对的。they wrong,你是对的。

对于语句,(目前,忽略指向整数转换的指针是实现定义的行为)

int * my_int_ptr = 2;

my_int_ptr是一个变量(指向int的指针类型),它有自己的地址(类型:指向整数的指针的地址),您正在将2的值存储到该地址中。

现在,my_int_ptr,作为一个指针类型,我们可以说,它指向my_int_ptr中保存的值所指向的内存位置上的“Type值”。因此,您实际上是在分配指针变量的值,而不是指针所指向的内存位置的值。

所以,作为结论

 char *x=NULL;

将指针变量x初始化为NULL,而不是指针指向的内存地址处的值。

这是与相同的

 char *x;
 x = NULL;    

扩展:

现在,为了严格遵守,像这样的语句

 int * my_int_ptr = 2;

是非法的,因为它涉及到违反约束。先说清楚,

根据定义,

  • my_int_ptr是一个指针变量,类型为int *
  • an整数常量,2的类型为int

而且它们不是“兼容”类型,所以这个初始化是无效的,因为它违反了Lundin's answer中描述的§6.5.16.1/P1章中提到的简单赋值规则。

如果任何人对初始化如何链接到简单的赋值约束感兴趣,请引用C11,第6.7.9章,P11

标量的初始值设定项应该是单个表达式,可以选择将其括在大括号中。对象的初始值是表达式的初始值(转换后);应用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本。

票数 114
EN

Stack Overflow用户

发布于 2017-04-11 14:26:50

教程是错误的。在ISO中,int *my_int_ptr = 2;是一个错误。在GNU中,它的意思与int *my_int_ptr = (int *)2;相同。这将以编译器确定的某种方式将整数2转换为内存地址。

它不会尝试在由该地址寻址的位置(如果有的话)中存储任何内容。如果您继续编写*my_int_ptr = 5;,那么它将尝试将数字5存储在该地址所寻址的位置。

票数 53
EN

Stack Overflow用户

发布于 2017-04-11 15:13:09

为了澄清为什么教程是错误的,int *my_int_ptr = 2;是一个“约束冲突”,它是不允许编译的代码,编译器必须在遇到它时给你一个诊断。

根据6.5.16.1的简单分配:

约束应满足以下条件之一:

  • 左操作数具有原子、限定或非限定算术类型,右操作数具有算术类型;
  • 左操作数具有与右操作数类型兼容的结构或联合类型的原子、限定或非限定版本;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且左操作数指向的类型具有右指向的类型的所有限定符;
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个操作数是指向空的限定或非限定版本的指针,左侧指向的类型具有右指向的类型的所有限定符;
  • 左操作数是原子、限定或非限定指针,而右操作数是空指针常量;or
  • 左操作数具有原子、限定或非限定_Bool类型,而右操作数是指针。

在这种情况下,左操作数是一个非限定指针。它没有提到右操作数可以是整数(算术类型)。因此,该代码违反了C标准。

众所周知,GCC的行为很糟糕,除非你显式地告诉它是一个标准的C编译器。如果您将代码编译为-std=c11 -pedantic-errors,它将像它必须做的那样正确地给出诊断。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43338084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档