为什么 int x[n] 是错误的,其中 n 是一个常量值? [英] Why is int x[n] wrong where n is a const value?

查看:62
本文介绍了为什么 int x[n] 是错误的,其中 n 是一个常量值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么这样做是错误的:

I cannot understand why doing this is wrong:

const int n = 5; 
int x[n] = { 1,1,3,4,5 };

即使 n 已经是一个常量值.

even though n is already a const value.

虽然这样做似乎适合 GNU 编译器:

While doing this seems to be right for the GNU compiler:

const int n = 5;
int x[n]; /*without initialization*/

我知道 C99 的 VLA 功能,我认为这与正在发生的事情有关,但是我只需要澄清一下背景中发生的事情.

I'm aware of VLA feature of C99 and I think it's related to what's going on but I just need some clarification of what's happening in the background.

推荐答案

要记住的关键是const 和constant"是两个完全不同的东西.

The key thing to remember is that const and "constant" mean two quite different things.

const 关键字的真正意思是只读".constant 是数字文字,例如 421.5(或枚举或字符常量).常量表达式是一种可以在编译时求值的特殊表达式,例如2 + 2.

The const keyword really means "read-only". A constant is a numeric literal, such as 42 or 1.5 (or an enumeration or character constant). A constant expression is a particular kind of expression that can be evaluated at compile time, such as 2 + 2.

所以给出一个声明:

const int n = 5;

表达式 n 指的是 object 的值,它不被视为常量表达式.典型的编译器会优化对 n 的引用,用用于文字 5 的相同代码替换它,但这不是必需的——以及表达式常量是由语言决定的,而不是由当前编译器的聪明程度决定的.

the expression n refers to the value of the object, and it's not treated as a constant expression. A typical compiler will optimize a reference to n, replacing it by the same code it would use for a literal 5, but that's not required -- and the rules for whether an expression is constant are determined by the language, not by the cleverness of the current compiler.

const(只读)和 constant(在编译时计算)之间的区别的一个例子是:

An example of the difference between const (read-only) and constant (evaluated at compile time) is:

const size_t now = time(NULL);

const 关键字表示now 的值在初始化后不允许修改,但是time(NULL) 的值> 显然直到运行时才能计算.

The const keyword means you're not allowed to modify the value of now after its initialization, but the value of time(NULL) clearly cannot be computed until run time.

所以:

const int n = 5;
int x[n];

在 C 中并不比没有 const 关键字时更有效.

is no more valid in C than it would be without the const keyword.

语言可以(恕我直言可能应该)将 n 评估为常量表达式;它只是没有那样定义.(C++ 确实有这样的规则;有关血腥细节,请参阅 C++ 标准或体面的参考.)

The language could (and IMHO probably should) evaluate n as a constant expression; it just isn't defined that way. (C++ does have such a rule; see the C++ standard or a decent reference for the gory details.)

如果你想要一个值为 5 的命名常量,最常见的方法是定义一个宏:

If you want a named constant with the value 5, the most common way is to define a macro:

#define N 5
int x[N];

另一种方法是定义一个枚举常量:

Another approach is to define an enumeration constant:

enum { n = 5 };
int x[n];

枚举常量是常量表达式,并且总是int 类型(这意味着此方法不适用于int 以外的类型).这可以说是对 enum 机制的滥用.

Enumeration constants are constant expressions, and are always of type int (which means this method won't work for types other than int). And it's arguably an abuse of the enum mechanism.

从 1999 标准开始,数组可以定义为非常量大小;这是一个 VLA,或可变长度数组.此类数组只允许在块范围内使用,并且可能没有初始化器(因为编译器无法检查初始化器是否具有正确数量的元素).

Starting with the 1999 standard, an array can be defined with a non-constant size; this is a VLA, or variable-length array. Such arrays are permitted only at block scope, and may not have initializers (since the compiler is unable to check that the initializer has the correct number of elements).

但鉴于您的原始代码:

const int n = 5; 
int x[n] = { 1,1,3,4,5 };

你可以让编译器从初始化器推断长度:

you can let the compiler infer the length from the initializer:

int x[] = { 1,1,3,4,5 };

然后你可以从数组的大小计算长度:

And you can then compute the length from the array's size:

const int x_len = sizeof x / sizeof x[0];

这篇关于为什么 int x[n] 是错误的,其中 n 是一个常量值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆