关于在C中初始化int指针的一个非常简单的问题。我 just informed :
int *varname = {0};
无效。
我还没有找到明确的引用指出这一点,但有信心(基于评论者代表)它可能无效,即使它编译,构建并接受来自calloc / malloc语句的内存好吗。
有人可以指出上述表达无效的具体原因吗?
答案 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 指向任何对象或函数的指针。
#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
。