为什么 "storage size of 'array' isn't constant"
why "storage size of 'array' isn't constant"
我刚上C.Last周,学习用数组来解决问题。我发现当数组的个数太大时,比如1024*1024,会报错。有人建议我使用 static 来解决它,但是这个错误(标题)让我更加困惑。我想我已经定义了参数,它应该是不变的。但事实并非如此。看不懂。
总结:
- 为什么会出现这个错误?
- 为什么常量在 C 中不是常量?
- 如果不使用一个常量,比如 5000,我怎么能解决这个问题?
- 有什么功能可以代替静态存储大数组?
这是文本代码,显示相同的错误
# include <stdio.h>
int main()
{
int num = 500;
static int arr[num] = {0};
printf("%d",arr[0]);
return 0;
}
具有静态存储持续时间的数组,即在文件范围或使用static
关键字定义的数组,必须有一个编译时间常数的大小。变量的值不是编译时常量,这就是您收到错误的原因。
将有问题的变量声明为 const
也不符合条件,因为它只是意味着变量不能被修改,而不是它是一个编译时间常量。
你可以做的是对常量使用预处理器符号。这将在编译器运行之前被替换。
#define NUM 500
static int arr[NUM] = {0};
静态存储持续时间数组大小必须是常量表达式 C17 6.7.6.2/2).
来自 C 标准:
An integer constant expression 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.
如您所见,const 整型变量未在此处列出,它们不能被视为常量表达式。
示例:
#define SIZE 300
int x = 500;
int a[SIZE];
int b[SIZE+ 'a'];
int c[SIZE + sizeof(x)];
/* and even most modern compilers will accept it*/
int d[SIZE + sizeof(x) + (size_t)sqrt(sizeof(c))];
why this error happens?
具有静态存储持续时间的对象在程序开始执行之前被实例化(为它们预留内存);这意味着必须在编译时知道 arr
的大小。尽管我们有 num
的初始化器,但它与编译时已知的值 num
不同; num
在程序开始执行之前 不存在 。
在文件范围内(在任何函数之外)或使用 static
关键字声明的数组必须使用 常量表达式 的大小声明 - 要么是整数像 1024
这样的常量,像 sizeof (<em>some-type</em>)
或 sizeof [这样的 <code>sizeof
表达式 some-expression,一个算术表达式,涉及前一个(例如1024*1024
或5000 * sizeof (int)
),或者一个扩展为任何一个的宏以上。或者它们可以在没有大小的情况下声明,并且大小取自初始化程序中的元素数量。
why a constant is not a constant in C?
500
是一个常量 - num
不是。同样,num
直到 运行 时间才存在,但是必须在 运行 时间之前知道 arr
的大小。添加 const
关键字,例如
const int num = 500;
没有帮助 - const
所做的只是告诉编译器在您尝试为 num
分配新值时对您大喊大叫。它不会使 num
成为 常量表达式 (无论如何在 C 中 - 在 C++ 中它确实如此)。
how could i solve it without using a ture constant,like 5000?
此时,您几乎只能使用动态内存。
what function can take the place of static to storage large array?
使用 malloc
或 calloc
在 运行 时间为数组分配 space:
#include <stdio.h>
<strong>#include <stdlib.h></strong>
int main( void )
{
size_t num = 500; // or whatever value you ultimately need
/**
* Dynamically allocate enough space for "num" objects of type "int".
*
* calloc will zero out the allocated memory (malloc does not).
*
* calloc will return NULL if it cannot satisfy the request, so we
* want to make sure "arr" isn't NULL before trying to use it.
*
* The type of the *expression* "*arr" is "int", so "sizeof *arr" == "sizeof (int)"
*/
<strong>int *arr = calloc( num, sizeof *arr ); </strong>
if ( arr )
{
printf( "%d\n", arr[0] );
/**
* Deallocate "arr" when you're done with it
*/
<strong>free( arr );</strong>
}
return 0;
}
像这样使用动态内存的一大优势是您可以根据需要使用 realloc
调整数组的大小 - 不能使用固定大小的数组(static
或不)。
从 C99 开始,您可以使用 运行时间变量声明数组作为大小:
int num = 500;
int arr[num];
这些被称为 可变长度数组 并且工作得很好(在大多数 C99 和更高版本的实现中),但是因为它们的大小直到 运行 时间才知道不能在 static
或文件范围内声明,也不能用任何初始值设定项声明。与其他 auto
数组一样,它们不能任意大。尽管有它们的名字,但它们一旦定义就不能调整大小——“可变长度”中的“变量”只是意味着它们的大小在每次实例化时都可以不同。
我刚上C.Last周,学习用数组来解决问题。我发现当数组的个数太大时,比如1024*1024,会报错。有人建议我使用 static 来解决它,但是这个错误(标题)让我更加困惑。我想我已经定义了参数,它应该是不变的。但事实并非如此。看不懂。
总结:
- 为什么会出现这个错误?
- 为什么常量在 C 中不是常量?
- 如果不使用一个常量,比如 5000,我怎么能解决这个问题?
- 有什么功能可以代替静态存储大数组?
这是文本代码,显示相同的错误
# include <stdio.h>
int main()
{
int num = 500;
static int arr[num] = {0};
printf("%d",arr[0]);
return 0;
}
具有静态存储持续时间的数组,即在文件范围或使用static
关键字定义的数组,必须有一个编译时间常数的大小。变量的值不是编译时常量,这就是您收到错误的原因。
将有问题的变量声明为 const
也不符合条件,因为它只是意味着变量不能被修改,而不是它是一个编译时间常量。
你可以做的是对常量使用预处理器符号。这将在编译器运行之前被替换。
#define NUM 500
static int arr[NUM] = {0};
静态存储持续时间数组大小必须是常量表达式 C17 6.7.6.2/2).
来自 C 标准:
An integer constant expression 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.
如您所见,const 整型变量未在此处列出,它们不能被视为常量表达式。
示例:
#define SIZE 300
int x = 500;
int a[SIZE];
int b[SIZE+ 'a'];
int c[SIZE + sizeof(x)];
/* and even most modern compilers will accept it*/
int d[SIZE + sizeof(x) + (size_t)sqrt(sizeof(c))];
why this error happens?
具有静态存储持续时间的对象在程序开始执行之前被实例化(为它们预留内存);这意味着必须在编译时知道 arr
的大小。尽管我们有 num
的初始化器,但它与编译时已知的值 num
不同; num
在程序开始执行之前 不存在 。
在文件范围内(在任何函数之外)或使用 static
关键字声明的数组必须使用 常量表达式 的大小声明 - 要么是整数像 1024
这样的常量,像 sizeof (<em>some-type</em>)
或 sizeof [这样的 <code>sizeof
表达式 some-expression,一个算术表达式,涉及前一个(例如1024*1024
或5000 * sizeof (int)
),或者一个扩展为任何一个的宏以上。或者它们可以在没有大小的情况下声明,并且大小取自初始化程序中的元素数量。
why a constant is not a constant in C?
500
是一个常量 - num
不是。同样,num
直到 运行 时间才存在,但是必须在 运行 时间之前知道 arr
的大小。添加 const
关键字,例如
const int num = 500;
没有帮助 - const
所做的只是告诉编译器在您尝试为 num
分配新值时对您大喊大叫。它不会使 num
成为 常量表达式 (无论如何在 C 中 - 在 C++ 中它确实如此)。
how could i solve it without using a ture constant,like 5000?
此时,您几乎只能使用动态内存。
what function can take the place of static to storage large array?
使用 malloc
或 calloc
在 运行 时间为数组分配 space:
#include <stdio.h>
<strong>#include <stdlib.h></strong>
int main( void )
{
size_t num = 500; // or whatever value you ultimately need
/**
* Dynamically allocate enough space for "num" objects of type "int".
*
* calloc will zero out the allocated memory (malloc does not).
*
* calloc will return NULL if it cannot satisfy the request, so we
* want to make sure "arr" isn't NULL before trying to use it.
*
* The type of the *expression* "*arr" is "int", so "sizeof *arr" == "sizeof (int)"
*/
<strong>int *arr = calloc( num, sizeof *arr ); </strong>
if ( arr )
{
printf( "%d\n", arr[0] );
/**
* Deallocate "arr" when you're done with it
*/
<strong>free( arr );</strong>
}
return 0;
}
像这样使用动态内存的一大优势是您可以根据需要使用 realloc
调整数组的大小 - 不能使用固定大小的数组(static
或不)。
从 C99 开始,您可以使用 运行时间变量声明数组作为大小:
int num = 500;
int arr[num];
这些被称为 可变长度数组 并且工作得很好(在大多数 C99 和更高版本的实现中),但是因为它们的大小直到 运行 时间才知道不能在 static
或文件范围内声明,也不能用任何初始值设定项声明。与其他 auto
数组一样,它们不能任意大。尽管有它们的名字,但它们一旦定义就不能调整大小——“可变长度”中的“变量”只是意味着它们的大小在每次实例化时都可以不同。