以多维数组作为参数的函数原型

问题描述 投票:0回答:2

我是 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 不感兴趣。

c function multidimensional-array declaration variable-length-array
2个回答
5
投票

如果编译器支持变长数组,那么你可以通过以下方式声明函数

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
投票

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
是一个可变修改的参数。

© www.soinside.com 2019 - 2024. All rights reserved.