C:恒定长度不允许我声明数组

发布于 2025-01-18 14:09:23 字数 881 浏览 1 评论 0原文

当我尝试编译一个简单的代码来理解指针时,我遇到了这个恼人的问题。 基本上,错误发生在数组的声明中:

// Use of pointers

#include <stdio.h>

int main(void) {
    const int SIZE = 5;

    int grades[SIZE]={78, 80, 75, 82, 83};
    //memset( grades, 0, SIZE*sizeof(int) );
    double sum = 0.0;
    double *ptr_sum = &sum;
    int i;

    printf("My grades are: \n");
    for (i=0; i<SIZE; i++) {
        printf("%d\n",grades[i]);
        sum = sum + grades[i];
    }
    printf("\n\n");
    printf("My average is %.2f\n\n", sum/SIZE);

    printf("sum is at %p, or %lu and is %lf\n",
        ptr_sum, ptr_sum, *ptr_sum);
    printf("Grades are at %lu to %lu\n", grades, grades+5);
    return 0;
}

尝试编译后,错误如下:

pointers.c:8:5:错误:可变大小的对象可能无法初始化 intgrades[SIZE]= {78, 80, 75, 82, 83};

如果我使用常量作为数组的长度,为什么会发生这种情况?

如果我删除数组内容(包括括号),程序将编译。如果我将数组留空,它会再次失败。

I'm experiencing this annoying issue when I try to compile a simple code to understand pointers.
Basically, the error happens in the declaration of the array:

// Use of pointers

#include <stdio.h>

int main(void) {
    const int SIZE = 5;

    int grades[SIZE]={78, 80, 75, 82, 83};
    //memset( grades, 0, SIZE*sizeof(int) );
    double sum = 0.0;
    double *ptr_sum = ∑
    int i;

    printf("My grades are: \n");
    for (i=0; i<SIZE; i++) {
        printf("%d\n",grades[i]);
        sum = sum + grades[i];
    }
    printf("\n\n");
    printf("My average is %.2f\n\n", sum/SIZE);

    printf("sum is at %p, or %lu and is %lf\n",
        ptr_sum, ptr_sum, *ptr_sum);
    printf("Grades are at %lu to %lu\n", grades, grades+5);
    return 0;
}

After trying to compile, the error is the following:

pointers.c:8:5: error: variable-sized object may not be initialized int grades[SIZE]={78, 80, 75, 82, 83};

If I'm using a constant for the length of my array, why is this happening?

If I remove the array content (including the brackets), the program compiles. If I leave the array empty it fails again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰つ倒转 2025-01-25 14:09:24

在 C 中,与 C++ 相反,在数组声明中使用常量对象,如下所示。

const int SIZE = 5;

int grades[SIZE]={78, 80, 75, 82, 83};

声明一个可变长度数组,该数组可能未在其声明中初始化。

相反,您需要使用整型常量表达式。

来自 C 标准(6.6 常量表达式)。

6 整数常量表达式117) 应具有整数类型并且应
仅具有整数常量、枚举常量的操作数,
字符常量、结果为整数的 sizeof 表达式
常量和作为立即操作数的浮点常量
演员表。整数常量表达式中的强制转换运算符只能
将算术类型转换为整数类型,除非作为
sizeof 运算符的操作数。

在此引用中,术语“整数常量”表示整数文字,而不是使用限定符 const 声明的对象。

例如,您可以通过以下方式声明数组。

enum { SIZE = 5 };

int grades[SIZE]={78, 80, 75, 82, 83};

//...

或者你也可以引入一个类似的宏。

#define SIZE 5

//...

int grades[SIZE]={78, 80, 75, 82, 83};

//...

或者,您可以首先声明数组而不指定其大小,然后引入指定其大小的常量,例如

int grades[]={78, 80, 75, 82, 83};
const size_t SIZE = sizeof( grades ) / sizeof( *grades );

还有这些 printf 调用。

printf("sum is at %p, or %lu and is %lf\n",
    ptr_sum, ptr_sum, *ptr_sum);

printf("Grades are at %lu to %lu\n", grades, grades+5);

均不正确。您正在尝试使用转换说明符 lu 输出指针。您需要使用转换说明符p
例如

printf("Grades are at %p to %p\n", ( void * )grades, ( void * )( grades+SIZE ));

In C opposite to C++ using a constant object in a declaration of an array like this.

const int SIZE = 5;

int grades[SIZE]={78, 80, 75, 82, 83};

declares a variable length array that may not be initialized in its declaration.

Instead you need to use an integral constant expression.

From the C Standard (6.6 Constant expressions).

6 An integer constant expression117) shall have integer type and shall
only have operands that are integer constants, enumeration constants,
character constants, sizeof expressions whose results are integer
constants, and floating constants that are the immediate operands of
casts. Cast operators in an integer constant expression shall only
convert arithmetic types to integer types, except as part of an
operand to the sizeof operator.

In this quote the term "integer constants" means integer literals not objects declared with the qualifier const.

You can declare the array for example the following way.

enum { SIZE = 5 };

int grades[SIZE]={78, 80, 75, 82, 83};

//...

Or alternatively you can introduce a macro like.

#define SIZE 5

//...

int grades[SIZE]={78, 80, 75, 82, 83};

//...

Or you could at first declare the array without specifying its size and then introduce the constant that specifiers its size as for example

int grades[]={78, 80, 75, 82, 83};
const size_t SIZE = sizeof( grades ) / sizeof( *grades );

Also these call of printf.

printf("sum is at %p, or %lu and is %lf\n",
    ptr_sum, ptr_sum, *ptr_sum);

printf("Grades are at %lu to %lu\n", grades, grades+5);

Are incorrect. You are trying to output a pointer using the conversion specifier lu. You need to use the conversion specifier p.
For example

printf("Grades are at %p to %p\n", ( void * )grades, ( void * )( grades+SIZE ));
﹏雨一样淡蓝的深情 2025-01-25 14:09:24

const 并不意味着“常量”。诚然,这有点令人困惑,因为关键字 const 显然源自英语单词“constant”,但它们意味着两个不同的东西。

在 C 中,const 表示只读。如果一个对象(变量)是使用 const 关键字定义的,则意味着其值在初始化后无法合法更改。如果您使用 SIZE 作为表达式,它就不是一个常量表达式。 如此

int grades[SIZE];

变长数组也是 。典型的编译器可能会生成与固定长度数组等效的代码,但语言规则仍然适用,包括无法初始化可变长度数组的规则。

常量表达式是必须在编译时求值的表达式,例如 422+2

请注意,例如,此声明是完全合法的:

const int r = rand();

即使在程序执行之前无法确定 rand() 的值(假设 PRNG 已使用某些运行时值进行播种) )。将初始值设定项设置为常量表达式不会改变行为。

(C++ 有一个特殊情况规则,即 const int SIZE = 5; 确实使 SIZE 成为常量表达式。这很方便,但在我看来有点不幸。C++ 较新constexpr 是做同样事情的更好方法,但当然 C 不是 C++。)

不幸的是,C 没有很好的方法来定义任意类型的命名常量。最常见的方法是使用预处理器宏:

#define SIZE 5

但宏名称的作用域与普通标识符不同。仅适用于 int 类型的解决方案是:

enum { SIZE = 5 };

其中任何一个都可以让您声明:

int grades[SIZE]={78, 80, 75, 82, 83};

const does not mean "constant". This is admittedly a bit confusing, since the keyword const is obviously derived from the English word "constant", but they mean two different things.

In C, const means read-only. If an object (variable) is defined with the const keyword, that means that its value can't legally be changed after it's been initialized. If you use SIZE as an expression, it's not a constant expression. So

int grades[SIZE];

is a variable-length array. A typical compiler will probably generate code equivalent to that for a fixed-length array, but the language rules still apply, including the one that says a variable-length array cannot be initialized.

A constant expression is one that must be evaluated at compile time, such as 42 or 2+2.

Note that, for example, this declaration is perfectly legal:

const int r = rand();

even though the value of rand() can't be determined until the program is executed (assuming the PRNG has been seeded using some run-time value). Making the initializer a constant expression doesn't change the behavior.

(C++ has a special-case rule that const int SIZE = 5; does make SIZE a constant expression. This is convenient, but in my opinion it's slightly unfortunate. C++'s newer constexpr is a better way to do the same thing. But of course C is not C++.)

C unfortunately does not have very good ways to define named constants of arbitrary types. The most common method is to use a preprocessor macro:

#define SIZE 5

but macro names are not scoped the way ordinary identifiers are. A solution that works only for type int is:

enum { SIZE = 5 };

Either of those will let you declare:

int grades[SIZE]={78, 80, 75, 82, 83};
迷迭香的记忆 2025-01-25 14:09:23

该数组被认为是变量长度数组,因为它的大小不是编译时间常数,并且A const变量不符合条件。而且由于它是一个可变长度数组,因此无法初始化。

您需要制作size宏,以便完成直接令牌替换。

#define SIZE 5

The array is considered a variable length array because its size is not a compile time constant, and a const variable doesn't qualify as such. And because it is a variable length array, it cannot be initialized.

You would need to make SIZE a macro so that a direct token substitution is done.

#define SIZE 5
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文