【问题标题】:Using scanf to fill out a multidimensional array (C language)使用scanf填充多维数组(C语言)
【发布时间】:2016-04-23 01:04:34
【问题描述】:

我想知道如何正确使用 scanf 来填充多维数组。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[]) {

int n; //number of rounds
int* sArray; //multidimensional array that holds the scores of both players
int i;

scanf("%d", &n);

sArray = (int*) calloc (n * 2, sizeof(int));


for(i=0; i<n; i++) {
    scanf("%d %d", &sArray[i][1], &sArray[i][2]); 

}

return 0;
}

它给了我一个错误,“下标值不是数组、指针或向量。”任何帮助将不胜感激!

【问题讨论】:

  • 要取消引用二维数组,您需要一个双指针:int** sArray;
  • 仅供参考,您的#include 语句应该在您的主要方法之前。
  • 始终检查来自scanf的函数返回值(成功扫描的项目数)。
  • 要填充二维数组,您需要两个嵌套的 for 循环
  • 应该是int (*sArray)[2] = calloc (n , sizeof **sArray * 2);

标签: c arrays multidimensional-array scanf dynamic-arrays


【解决方案1】:

这里已经有很多关于如何定义动态二维数组的好答案。但是这个变种还没有提到,所以我把它记录下来。

由于数组的最后一维是固定的,您可以按如下方式定义二维数组:

int (*sArray)[2]; //multidimensional array that holds the scores of both players
...
sArray = (int(*)[2]) calloc (n, sizeof(int)*2);  // self explaining

这样,所有的元素都会被连续存储(分配数组的每个n个元素,都是2个连续的整数),而不需要一个数组对数组。

其余代码保持不变。除了你应该地址sArray[i][0]..[1]而不是[1][2]并在最后释放内存。在 C 中,数组索引总是从 0 开始,一直到 size-1。

当然,这种方法严格限于最后一维是固定的二维数组。

Live demo with addressing

【讨论】:

    【解决方案2】:

    你也可以这样做:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, const char * argv[]) {
    
    
        int n; //number of rounds
        int** sArray = malloc(2 * sizeof(int*)); //multidimensional array that holds the scores of both players
        scanf("%d", &n);
        sArray[0] = (int*)calloc(n , sizeof(int));
        sArray[1] = (int*)calloc(n , sizeof(int));
    
        int i;
        for (i = 0; i < n; i++) {
            scanf("%d %d", &sArray[0][i], &sArray[1][i]);
        }
    
        free(sArray[0]);
        free(sArray[1]);
        free(sArray);
    
        return 0;
    }
    

    【讨论】:

    • 这是一种有点痛苦的分配方式,并不能完全完成你的计划。仔细查看有关如何分配 pointer-to-array 2 of type int 的注释或分配 pointer-to-pointer-to 类型的其他答案 int.
    • @DavidC.Rankin:明白了!
    • 呃,这是 UB。您想在将n 传递给calloc 之前阅读它。
    【解决方案3】:

    二维数组定义如下:int sArray[N][M],但由于您想使用动态内存,我建议您查看指向 int 的指针:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int n;
        scanf("%d", &n);
        int **sArray;
        sArray = (int **)malloc(n * sizeof(int *));
    
        int i;
        for(i = 0; i < n; i++)
        {
            sArray[i] = (int *)malloc(2 * sizeof(int));
            scanf("%d %d", &sArray[i][1], &sArray[i][2]);
        } 
        return 0;
    }
    

    完成数组后不要忘记清理。

    如评论中所述,如果您使用pure c,则无需转换malloc 的结果。我这样做是因为我的 c++ 编译器拒绝在没有这种转换的情况下编译它。

    您可能需要在数组的动态分配期间检查错误。阅读更多here

    【讨论】:

    • 可以,但请不要投malloc的结果。
    • 这不是一个真正的二维数组,而是指向一维数组的指针的一维数组(在这种情况下具有大量内存开销)。也可以有实际的二维值数组。
    • @hyde 如果您使用的 C 实现没有 VLA,则不会,这在 C11 中是可能的。
    • @szczurcio 如果其他维度在编译时固定,则不需要VLA,这里是2。所以C89就足够了。另外,C99 已经有 VLA。
    • 二维数组定义如下: int **sArray... C 中的二维数组如下所示:int array[x][y]; 你所拥有的是一个指向指向 int 的指针:int **array;,将用于模拟 2D 数组。
    【解决方案4】:

    通常要填充二维数组,您将使用两个嵌套的 for 循环。 例如:

    int array[2][3] = {0};
    
    for (i = 0; i < 2; i++)
       for (k = 0; k < 3; k++)
          scanf("%d", &array [i][k]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-07
      • 2014-11-20
      • 2023-02-11
      • 2014-09-02
      • 2011-01-11
      • 1970-01-01
      相关资源
      最近更新 更多