Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 为什么会这样';sizeof()和#x27;返回值是0字节,用C?_Arrays_C_Declaration_Undefined Behavior_Sizeof - Fatal编程技术网

Arrays 为什么会这样';sizeof()和#x27;返回值是0字节,用C?

Arrays 为什么会这样';sizeof()和#x27;返回值是0字节,用C?,arrays,c,declaration,undefined-behavior,sizeof,Arrays,C,Declaration,Undefined Behavior,Sizeof,我的问题是关于sizeof和内存分配。当我学习C和测试类型值时,我尝试了以下代码: #include <stdio.h> int main(void) { char vec[0]; vec[0] = 1; printf("\n SIZEOF: %li", sizeof(vec)); printf("\n VEC[0]: %li", vec[0]); } 为什么即使我加上值“vec[0]=1,“vec[0]”的大小也是“0字节”?(如果不添加

我的问题是关于
sizeof
和内存分配。当我学习C和测试类型值时,我尝试了以下代码:

#include <stdio.h>

int main(void) {
char vec[0];
vec[0] = 1;
printf("\n SIZEOF: %li", sizeof(vec));
printf("\n VEC[0]: %li", vec[0]);
}
为什么即使我加上值“vec[0]=1,“vec[0]”的大小也是“0字节”?(如果不添加此值,只需声明向量“char-vec[0]或int-vec[0]”,输出相同)


里奇克。表示您的时间。

vec
被定义为一个大小为零个元素的数组。零元素的大小是零,这似乎是合理的。为
vec[0]
赋值会覆盖某个地方的内存。

数组必须定义为正大小

您创建了一个大小为0的约束冲突,因此您的代码将显示。

此代码片段

char vec[0];
vec[0] = 1;
调用未定义的行为

不能声明包含零元素的数组

来自C标准(6.7.6.2数组声明器)

1除了可选的类型限定符和关键字static之外 [和]可以限定表达式或*。如果它们限定了一个表达式 (指定数组的大小),表达式应具有 整数类型如果表达式是常量表达式,则应 具有大于零的值。元素类型不得为 不完整或函数类型。可选类型限定符和 关键字static只能出现在函数声明中 参数的数组类型,然后仅在最外层的数组中 类型派生

请注意,在这些printf调用中使用了不正确的转换说明符

printf("\n SIZEOF: %li", sizeof(vec));
printf("\n VEC[0]: %li", vec[0]);
对于类型为
size\t
的运算符
sizeof
返回的值,应使用转换说明符
%zu
,对于类型为
char
的对象,应使用转换说明符
%c

至于你的问题

为什么“vec[0]”的大小为“0字节”,即使我加上值“vec[0]=1” ? (如果不添加此值,只需声明向量“char vec[0]或 int vec[0]“输出相同)

然后编译器应该发出一条与数组的无效声明相关的消息


对于输出,由于数组不是可变长度数组,则在编译时计算表达式
sizeof(vec)
的值。编译器看到元素的数量等于
0
,并将表达式
sizeof(vec)
计算为
0*sizeof(char)
。因此,此表达式始终产生
0
,与数组元素类型无关。

当您写入
vec[0]=1时,实际上并不是在“数组”中填充长度为0
vec
的位置

请记住,当您声明长度为
N
的数组时,其有效索引是
0,1,2。。。N-1
。如果数组的大小
0
,有效索引是什么?没有

这与以下类型的未定义行为相同:

int data[3] = { 1, 2, 3 };
data[10000] = 10;

写入
vec[0]
可能在您的系统上起作用,但它仍然不是属于您声明的
vec

字符vec[0]的内存。。。为什么它会有一个
sizeof()
除了零以外的任何东西<代码>向量[0]=1是未定义的行为,因为您在数组外编写。编译器应该在
char-vec[0]上对您大喊大叫-数组不能声明为0大小。在启用所有警告的情况下编译可能是一个好主意。假设您使用的是gcc,请参阅您必须使用打印
sizeof
gcc的结果实际上允许0长度数组作为扩展(早于C99灵活数组成员,用于解决相同的问题)。不过,像这样的解引用仍然没有定义。请看@Shawn:你仍然不应该在结构之外使用它们。@Joshua,但你可以。文档中警告不要这样做,但这是允许的。@Shawn:C标记表示,除非另有规定,否则它是针对ISO 9899标准中定义的有关C的问题。当GCC在任何模式下接受无诊断消息的零长度数组时,它没有实现ISO 9899标准中定义的C,并且它的行为与问题的相关性不亚于FORTRAN编译器的行为,因为两者都没有实现标准中定义的C。实际编译器的实际行为与我们这些不住在象牙塔中的人非常相关。我在90年代得到了comp.lang.c的闪回。如果您想将字符打印为字符,您只能使用
%c
。如果要将字符打印为(十进制)整数,请使用
%i
%d
。在许多编译器中,声明包含0个元素的数组是合法的。当构造具有灵活大小的结构时,它特别有用,其中结构的最后一个字段是零长度数组。@作为结构成员的abelenky灵活数组和问题中的声明是两件不同的事情。此外,灵活数组成员被声明为具有不完整类型。所以你的评论没有意义。“你不能声明一个零元素的数组。”-是的,在某些情况下你可以。你的笼统陈述充其量是误导性的,更可能是错误的。@Vladfrommoskow:C标准禁止“严格一致的C程序”中的某些构造。另一方面,它允许“一致的C程序”使用至少一个“一致的C实现”接受的任何扩展根据标准的术语,存在有效处理大小为零的数组声明的C实现这一事实足以允许在“一致性C程序”中使用这种构造。
int data[3] = { 1, 2, 3 };
data[10000] = 10;