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不感兴趣。
答案 0 :(得分:3)
如果编译器支持可变长度数组,那么可以按以下方式声明函数
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);
答案 1 :(得分:1)
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
是一个可变修改的参数。