C语言中动态分配数组的大小
我知道以前有人问过这个问题,但我的问题更具体, 代码如下:C语言中动态分配数组的大小,c,arrays,sizeof,ansi,c89,C,Arrays,Sizeof,Ansi,C89,我知道以前有人问过这个问题,但我的问题更具体, 代码如下: #include <stdio.h> #include <time.h> /* must be included for the time function */ main() { time_t t = time(NULL); srand((unsigned) t); int i = rand(); int a[i]; printf("%d\n", i);
#include <stdio.h>
#include <time.h> /* must be included for the time function */
main()
{
time_t t = time(NULL);
srand((unsigned) t);
int i = rand();
int a[i];
printf("%d\n", i); /* ouptut: 18659 */
printf("%d\n", sizeof a); /* output: 74636 */
}
#包括
#时间函数必须包含include/**/
main()
{
时间t=时间(空);
srand((无符号)t);
int i=rand();
int a[i];
printf(“%d\n”,i);/*输出:18659*/
printf(“%d\n”,大小为a);/*输出:74636*/
}
我使用gcc和-ansi选项编译了这段代码,以限制它只识别ansic。
我知道编译器无法在编译时知道数组的大小,因为它是在运行时随机确定的。
现在我的问题是sizeof返回的值只是一个随机值,还是有意义?
sizeof返回的值只是一个随机值,还是有意义
它确实有一个含义,即74636
/18659
=4
,这显然是机器上int
的大小
因此sizeof
(将在运行时而不是编译时计算,因为参数是VLA),将返回数组a
的大小(以字节为单位),即它包含的int
s的数量(换句话说i
或18659
)乘以int
的大小,这是您机器上的4
< > <代码> > <代码>(<代码> RAND < /代码>的结果)是随机的,可以认为<>代码> sieOS/<代码>的值在这个意义上也是随机的。 < p>由<代码> SigeOS/<代码>返回的值是一个伪随机值,其含义是:
- 该值表示VLA
的大小,以字节为单位a
- 它是随机的,只是因为数组元素的数量是通过调用
确定的rand
sizeof(int)
似乎是4,因为sizeof
返回的数字是数组中元素数的四倍
注意:在C99中允许VLA的后果之一是
sizeof
不再是纯粹的编译时表达式。当sizeof
运算符的参数为VLA时,将在运行时计算结果。对于大多数操作数,将在编译时对sizeof
运算符求值。对于VLA,将在运行时对其进行评估
根据本规范第6.5.3.4节:
2运算符的sizeof
生成其操作数的大小(以字节为单位),可以是表达式或类型的括号名称。这个
大小由操作数的类型决定。结果是一场灾难
整数如果操作数的类型是可变长度数组类型,
计算操作数;否则,将不计算操作数并
结果是一个整数常量
因此,sizeof
返回的大小是VLA的字节大小。在您的示例中,这将是
ansi选项不会导致非ISO程序被无故拒绝。为此,除-ansi外,还需要-Wpedantic
这是无效的C89代码,因为数组长度可变。它在C99+中有效,sizeof在VLAs上显式地执行运行时魔术(提示:74636/18659是什么?)让我们做一个练习-我们尝试将18659乘以4。我们得到了什么?如果您只想要ANSI C,请使用with
-pedantic
选项(with-Werror
)。(关闭GCC的扩展。)顺便说一句,为了避免UB,这应该是printf(“%zu\n”,sizeof a)代码>。sizeof返回一个size_t,而不是int。TFM说,“-ansi选项不会导致非ISO程序被无故拒绝。为此,除了-ansi外,还需要-pedantic”。这不是问题的真正答案(sizeof(a)对VLA有效),是吗?@Aconcagua实际上是,因为它意味着sizeof(a)仅在C89中(不使用-Wpedantic选项)的情况下,才在编译时对其进行评估。@MaykelJakson答案中甚至没有提到“sizeof”一词-也没有任何关于在编译/运行时对其进行评估的词语,也没有确认结构是否有效。这可能是正确答案的原因——如果有人回答了“如何仅使用GCC编译ANSI?”这一问题,OP(错误地)认为已经在这样做了。。。