在C中初始化int指针

时间:2014-11-12 20:41:56

标签: c pointers initialization

关于在C中初始化int指针的一个非常简单的问题。我 just informed

int *varname = {0};  

无效。

我还没有找到明确的引用指出这一点,但有信心(基于评论者代表)它可能无效,即使它编译,构建并接受来自calloc / malloc语句的内存好吗。

有人可以指出上述表达无效的具体原因吗?

3 个答案:

答案 0 :(得分:4)

这是有效的,我们可以通过转到C99 draft standard部分6.7.8 初始化11来看到这一点,其中说明:

  

标量的初始值设定项应为单个表达式,可选择用大括号括起来。 [...]

所以:

int *varname = {0}; 

会将varname初始化为空指针,因为0空指针常量,符合6.3.2.3 指针

  

值为0的整型常量表达式,或此类表达式   强制转换为void *,称为空指针常量.55)如果为null   指针常量被转换为指针类型,由此产生   指针,称为空指针[...]

为了完整起见,我们知道指针是基于6.2.5 类型部分的标量类型:

  

算术类型和指针类型统称为标量类型[...]

答案 1 :(得分:2)

在:

int *varname = {0};

等同于:

int *varname = 0;

它是NULL类似对象宏的有效替换之一(作为0整数常量或此类常量转换为void *类型)。

N1570(C11草案),6.3.2.3 / 3:

  

值为0的整型常量表达式,或此类表达式   强制转换为类型void *,称为空指针常量如果为null   指针常量被转换为指针类型,由此产生   指针,称为空指针,保证比较不等于a   指向任何对象或函数的指针。

示例(http://ideone.com/9917zk):

#include <stdio.h>

int main(void)
{
    int *varname = {0};

    printf("%p\n", (void *) varname);

    return 0;
}

它的输出只是:

(nil)

(作为奖励部分说明nil术语由Alfred Tarski发明

答案 2 :(得分:2)

正如Grzegorz Szpetkowski的回答所说,语法:

int *varname = {0};

有效。它只是没有做我怀疑你认为它应该做的事情。它相当于

int *varname = 0;

相当于

int *varname = NULL

(假设NULL可见)。

如果我对您尝试做的事情的猜测是错误的,则此答案的其余部分不适用。


根据评论,看起来这不是OP试图做的事情。不确定是否删除此答案;对于其他一些问题,这可能是一个很好的答案。


您可以初始化char*指针以指向字符串文字:

char *cptr = "hello";

字符串文字"hello"隐式创建一个具有静态存储持续时间的匿名数组对象;初始化导致cptr指向该数组的初始元素。

在C99之前,没有相同的语法来定义非字符指针并同时创建指向它的东西。

C99添加了复合文字。例如,这个:

(int){42}

创建一个值int的{​​{1}}对象。与文字42不同,这实际上创建了一个对象,而不仅仅是一个值 - 这意味着它有一个地址。所以这个:

42

创建一个初始值为int *iptr = &((int){42}); 的匿名int对象,并初始化42以指向它。 (如果您的编译器支持复合文字。)

复合文字通常用于数组和结构类型,但它们对标量类型也有效。

需要注意的一件事:由字符串文字创建的数组始终具有静态存储持续时间,这意味着它在整个程序执行期间存在。复合文字创建的匿名对象的存储持续时间取决于它出现的位置。如果它在函数内部,则该对象具有自动存储持续时间,这意味着一旦执行离开最近的封闭块,它就不再存在。

所以给出:

iptr

您可以安全地从函数返回char *cptr = "hello"; 的值,它将继续有效。但鉴于:

cptr

从函数返回int *iptr = &((int){42}); 的值将是危险的,因为它指向的对象将在调用者获得指针值之前停止存在。

执行此类操作的更简单方法是自己定义对象:

iptr

如有必要,您可以将int obj = 42; int *iptr = &obj; 定义为obj