【问题标题】:Function for printing 2D arrays of uknown size in C用于在 C 中打印未知大小的二维数组的函数
【发布时间】:2019-12-30 13:57:03
【问题描述】:

我是 C 编程新手,在创建 2D 数组打印函数时遇到了问题。当我尝试执行下面的代码时,我得到:

points.c:13: error: unknown array element size

正如我所检查的那样,网上有非常相似的代码,它们应该可以工作。我试图将函数初始化为

int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])

但它引发了:

points.c:3: error: 'arrayLen' undeclared

谁能告诉我这段代码有什么问题以及如何修复它?我也不明白为什么一维数组非常相似的函数工作得很好。它必须是纯 C 语言。

#include <stdio.h>
//supposed to print 2D array:
int print2DArray(int array[][], int arrayLen, int elementLen)
{
    int i;
    int j;

    for (i = 0; i < arrayLen; i++)
    {
        for (j=0; j < elementLen; j++)
        {
            printf("%5d", array[i][j]);
        }
        printf("\n");
    }
}

//prints 1D array:

int printArray( int array[], int arrayLen)
{
    int i;
    for (i = 0; i < arrayLen; i++)
    {
        printf("%d", array[i]);
    }
}

--- 编辑---

我不明白你们中的大多数人指出该函数必须这样调用:

#include <stdio.h>

int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])
{
    int i;
    int j;

    for (i = 0; i < arrayLen; i++)
    {
        for (j=0; j < elementLen; j++)
        {
            printf("%5d", array[i][j]);
        }
        printf("\n");
    }
}

这会引发错误:

points.c:3: error: 'arrayLen' undeclared

我在 windows 上使用 tcc,根据文档,它应该支持 C99 VLA。

【问题讨论】:

  • 你说你把函数写成int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])。但你没有。相反,您已经完成了int print2DArray(int array[][], int arrayLen, int elementLen),这是完全不同的(并且无效)。
  • int array[][] 不是一个有效的参数,所以忘记这一点。在此之前,您已经确定您的编译器 是否 支持 VLA(可变长度数组)?必须这样做,否则您的 int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen]) 将无法正常工作。
  • 发布导致“我已尝试将函数初始化为int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])”的代码。我怀疑您有转录错误。
  • @Peter 我知道,我的意思是我已经尝试了这两种方法。
  • ChrisM "我在 windows 上使用 tcc,根据文档,它应该支持 C99 VLA" --> 编译器似乎处于根本不接受 VLA 的模式。也许编译器选项是为 C89 之前设置的,没有 VLA 或“支持 C99”只是“支持大部分 C99”。

标签: c arrays multidimensional-array


【解决方案1】:

看来 OP 的编译器(或它使用的模式)不支持 可变长度数组 (VLA) 作为函数参数。

以下是非 VLA 方法。

void print2DArrayX(int arrayLen, int elementLen, const int *array) {
  int i;
  int j;

  for (i = 0; i < arrayLen; i++) {
    for (j = 0; j < elementLen; j++) {
      printf("%5d", array[i*elementLen + j]);
    }
    printf("\n");
  }
}

使用第一个int 的地址调用,而不是二维数组

#define ARRAY_LEN 3
#define ELEMENT_LEN 4
int array[ARRAY_LEN][ELEMENT_LEN] = { 0 };
...
print2DArrayX(ARRAY_LEN, ELEMENT_LEN, array[0]);

【讨论】:

  • 这种方法不会导致Annex J.2 中提到的类型的未定义行为:“数组下标超出范围,即使对象显然可以使用给定的下标访问(如在给定声明 int a[4][5]) (6.5.6)" 和 discussed here? 的左值表达式 a[1][7]
  • @exnihilo 有趣:我会说它不是 UB,因为 const int *array 没有 int array[ARRAY_LEN][ELEMENT_LEN] 的二维限制,只是整体索引受到 ARRAY_LEN*ELEMENT_LEN 的限制而没有 @ 987654323@print2DArrayX().
【解决方案2】:

好的,非常感谢您提供的所有答案 - 他们非常有帮助。我刚刚尝试在 linux 中使用 gcc,正如您所指出的,这种方法效果很好:

int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])

我猜 tcc (tiny c compiler, windows version 0.9.27) 毕竟不支持 VLA。有点奇怪,因为文档说确实如此。

【讨论】:

  • “有点奇怪,因为文档说确实如此。” --> 最好贴出错误的 tcc 报价和 tcc 的版本。
  • 您的意思是这个文档:bellard.org/tcc/tcc-doc.html#Clang 吗?不过,我还没有找到任何方法来指定特定的标准。
  • @Bob__ 是的,这个小文件。由于 tcc 'help' 没有显示任何指定标准的选项,我假设 VLA 默认为“on”。老实说,至少我发现 VLA 不是 ANSI C 标准的一部分。我必须使用 ANSI C,所以这对我来说不是一个真正的问题。
  • 不要打开那罐蠕虫,但即使通常将 C89 称为 ANSI C,current ANSI C standard 也是 C18。
【解决方案3】:

你试试这个解决方案怎么样。

#include <stdio.h>


int print2DArray(int* array, int arrayLen, int elementLen)
{
    int i;
    int j;

    for (i = 0; i < arrayLen; i++)
    {
        for (j=0; j < elementLen; j++)
        {
            printf("%5d ", *(array+j+elementLen*i));
        }
        printf("\n");
    }

}

int main(){
    int arr[2][6] = {   {9,258,9,96,-8,5},
                        {1,1212,-3,45,27,-6}
                      };
    print2DArray(*arr,2,6);
    return 0;
}

【讨论】:

    【解决方案4】:

    除非您使用的是 C99 编译器,否则

    int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen])
    

    不可能。

    即使您使用的是 C99 编译器,您的代码也有问题。您需要先通过其中一个维度。

    int print2DArray(int arrayLen, int elementLen, int arr[][elementLen]);
    

    所以,

    int print2DArray(int arrayLen, int elementLen, int arr[][elementLen]) 
    {
        // Your code
        int i;
        int j;
    
        for (i = 0; i < arrayLen; i++)
        {
            for (j=0; j < elementLen; j++)
            {
                printf("%5d", array[i][j]);
            }
            printf("\n");
        }
    
        return 0;
    }
    

    这可以用作

    int main(void) 
    { 
        int i32Array[3][3] = {{-15, 4, 36}, {45, 55, 12}, {-89, 568, -44568}}; 
        int m = 3, n = 3; 
        // I am not sure why 'print2DArray' would return an int 
        // (or anything at all for that matter). 
        // If you can establish a case for it, 
        // modify the function and the value it is supposed to return,
        // And catch it below.
    
        print2DArray(m, n, i32Array); 
    
        return 0; 
    }
    

    我不确定你是如何调用print2DArray 函数的。除非您发布那段代码,否则很难解决您的问题。如上所示,确认您正在正确调用该函数。

    【讨论】:

    • 第一步很好,但是如果int print2DArray(int arrayLen, int elementLen, int arr[][elementLen]); 有效,那么OP 的int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen]) 也应该报告错误。
    • @chux-ReinstateMonica:它应该适用于 C99,对吧?
    • 是的,int print2DArray( int arrayLen, int elementLen, int array[arrayLen][elementLen]) 可以在 C99 中工作 - 也可以在 C11、C17 中工作。
    • 我想问题在于 OP 如何调用此函数。需要看看那个。
    • Answer 有弱点,但不是 DV。
    猜你喜欢
    • 2022-12-04
    • 2018-03-10
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    相关资源
    最近更新 更多