我是 C 语言新手,有 Java 背景。
我遇到一个无法编译的问题,因为编译器想在编译时知道数组的大小。例如,我想将我的数组打印到控制台。它不允许我这样声明函数原型:
void printRoom(char[][], int, int); //not allowed
我该怎么办?难道就没有办法解决这个问题吗?我发现的在线资源似乎表明,如果我想使用函数原型,我必须知道尺寸。看来它还要求函数头也具有数组的大小。
void printRoom(char room[][], int height, int width){ // not allowed, missing array bounds
这个问题的有效解决方案只是说数组的大小为 1000*1000 (我可以预期的最大数组大小)吗?这对我来说似乎很草率,但我很确定只要我保持在数组实际大小的范围内,它就会起作用。
我目前对指针和 malloc 不感兴趣。
如果编译器支持变长数组,那么你可以通过以下方式声明函数
void printRoom( int, int, char[*][*]);
或者只是
void printRoom( int, int, char[][*]);
这是一个演示程序
#include <stdio.h>
#include <string.h>
void printRoom( int, int, char[*][*]);
void printRoom( int m, int n, char a[m][n] )
{
for ( int i = 0; i < m; i++ )
{
printf( "%3s ", a[i] );
putchar( ' ');
}
printf( "\n" );
}
int main(void)
{
const int M = 2;
const int N = 10;
char a[M][N];
strcpy( a[0], "Hello" ),
strcpy( a[1], "World" );
printRoom( M, N, a );
return 0;
}
它的输出是
Hello World
如果编译器不支持 VLA,则列数必须是常量。例如
#define N 100
//...
void printRoom(char[][N], int, int);
C 标准在 §6.7.6.3 中表示函数声明符(包括原型):
¶12 如果函数声明符不是该函数定义的一部分,则参数可能具有 不完整类型,可以在声明符说明符序列中使用
表示法 指定可变长度数组类型。[*]
这是标准说法: 您可以使用如下表示法编写函数声明,但不能编写函数定义:
void printRoom(int, int, char [*][*]);
其中参数在声明中重新排序,因为在函数定义中,您必须在指定数组之前指定大小:
void printRoom(int height, int width, char room[height][width])
{
…
}
您可以颠倒函数中
height
和 width
的顺序,但通常在 C 中,您会按照使用的顺序命名维度。
您不必指定主尺寸的大小;所有其他的都必须有与其相关的大小。 这意味着你可以写:
void printRoom(int, int, char [][*]);
和:
void printRoom(int height, int width, char room[][width])
{
…
}
该函数仍然需要知道高度,以便它可以准确地处理数组,但它不必是数组定义的一部分。
§6.9.1 函数定义
¶10 进入函数时,每个可变修改参数的大小表达式为 求值并将每个参数表达式的值转换为 就像通过赋值一样的相应参数。 (数组表达式和函数 作为参数的指示符在调用之前被转换为指针。)
您的
room
是一个可变修改的参数。