对于 C89 及更早版本,数组声明中的数组维度必须是常量表达式,这意味着它们必须在编译时可计算(数字常量、sizeof 表达式、涉及数字常量的表达式和/或 sizeof 表达式,或扩展为之前任何一个的宏)。
C99 引入了“可变长度数组”,其中数组尺寸使用运行时表达式确定(这对 VLA 的使用位置设置了一些限制):
int blocks = some_value();
int seg = some_other_value();
int memory[blocks][segs];
不幸的是,Microsoft 的 Visual Studio 实现不支持可变长度数组(或 C89 之外的许多其他数组)。
因此,您可以选择 - 您可以使用支持 C99 或更高版本的不同编译器(例如 MinGW),或者您需要使用动态内存分配。如果你想保持 BLOCKS 不变但 SEG 变量,你需要做这样的事情:
int *memory[BLOCKS];
int seg;
...
scanf( "%d", &seg );
...
for ( int i = 0; i < BLOCKS; i++ )
{
memory[i] = malloc( sizeof *memory[i] * seg );
if ( !memory[i] )
// handle memory allocation failure
}
完成后,您需要free 那个内存:
for ( int i = 0; i < BLOCKS; i++ )
free( memory[i] );
这种方法的主要缺点是数组的行在内存中不会连续——memory[i][seg-1] 和memory[i+1][0] 之间会有一个间隙。如果这很重要,您可能必须将内存分配为单个块,然后伪造 2D 索引:
int *memory = malloc( sizeof *memory * BLOCKS * seg );
if ( !memory )
// handle memory allocation failure
...
memory[i * BLOCKS + j] = some_value();
编辑
这是一个基于您问题中的 sn-p 的(未经测试!)示例 - 您正在尝试读取具有固定行数 (BLOCKS) 和可变列数 (@987654333) 的 .csv 文件@):
#include <stdio.h>
#include <stdlib.h>
#define BLOCKS 20
int *memory[BLOCKS];
int main( void )
{
int seg;
FILE *stream = fopen( “file.csv”, “r” );
if ( !stream )
// print error and exit
printf( “Please enter a number: “);
if ( scanf( “%d”, &seg ) != 1 )
// print error and exit
for ( size_t b = 0; b < BLOCKS; b++ )
{
/**
* Allocate memory for a block (row)
*/
memory[b] = malloc( sizeof *b * seg );
if ( !memory[b] )
// print error and exit
/**
* Read that row from the file - since it has
* a .csv extension, I am assuming it is
* comma-delimited. Note that malloc is not
* required to initialize memory to any specific
* value - the initial value of each memory[b][s]
* is indeterminate.
*/
for ( size_t s; s < seg; s++ )
if ( fscanf( stream, “%d%*c”, &memory[b][s] )) != 1 )
// print error and exit
}
fclose( stream );
/**
* Do stuff with memory here
*/
/**
* After you’re done with memory, free it
*/
for ( size_t b = 0; b < BLOCKS; b++ )
free( memory[b] );
return EXIT_SUCCESS;
}