【问题标题】:Passing 2D Arrays with Pointers (C)使用指针传递二维数组 (C)
【发布时间】:2016-03-14 16:52:44
【问题描述】:

下面是我正在使用的代码。当我运行它并注释掉处理addArrays 函数的代码时,它工作得非常好。

我相信我没有在 addArrays 函数中正确使用指针。任何帮助将不胜感激。

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

void addArrays(int rowSize, int columnSize, int Array1[rowSize][columnSize],
               int Array2[rowSize][columnSize],
               int *sumloc[rowSize][columnSize]);
void printArray(int rowSize, int columnSize, int arrayValue[rowSize][columnSize]);

/*
This program will make 2 2D matrices out of a random number of rows, 3 columns, and a random set of values.
Then, the two matrices will be added and all three printed.
*/

int main() {
    //To get a true random number
    srand(time(NULL));

    int rowSize = rand() % 4 + 1;
    int columnSize = 2;
    int Array1[rowSize][columnSize];
    int Array2[rowSize][columnSize];
    int Arraysum[rowSize][columnSize];

    //For loop counter
    int col;
    int row;

    //Makes a unique number for each part of both arrays from 0-50
    for (row = 0; row <= rowSize; row++)
        for (col = 0; col <= columnSize; col++)
            Array1[row][col] = rand() % 50;

    for (row = 0; row <= rowSize; row++)
        for (col = 0; col <= columnSize; col++)
            Array2[row][col] = rand() % 50;


    //Add arrays
    addArrays(rowSize, columnSize, Array1[rowSize][columnSize],
              Array2[rowSize][columnSize],v&Arraysum[rowSize][columnSize]);

    //Utilizes the print function
    printArray(rowSize, columnSize, Array1);
    printArray(rowSize, columnSize, Array2);
    printArray(rowSize, columnSize, &Arraysum);

    return 0;
}

void addArrays(int rowSize, int columnSize, int a1[rowSize][columnSize],
               int a2[rowSize][columnSize],
               int *sumloc[rowSize][columnSize]) {
    int row;
    int col;
    sumloc[rowSize][columnSize] = malloc(rowSize * columnSize * sizeof(int));

    for (row = 0; row <= rowSize; row++)
        for (col = 0; col <= columnSize; col++)
            *sumloc[row][col] = a1[row][col] + a2[row][col];

    return;
}

void printArray(int rowSize, int columnSize, int arrayValue[rowSize][columnSize]) {
    int row;
    int col;

    for (row = 0; row <= rowSize; row++) {
        printf("\n");
        printf("[");
        for (col = 0; col <= columnSize; col++) {
            printf(" %d ", arrayValue[row][col]);
        }
        printf("]");
    }
    printf("\n\n");

    return;
}

【问题讨论】:

  • 你没有说你得到了什么错误(编译?运行时?什么消息?)你调用的函数是错误的。您正在使用声明来调用它。类型已经是int[][],所以只需传递名称:addArrays(rowSize, columnSize, Array1, Array2, &amp;Arraysum);。您可能还想为您的数组考虑更合理的名称。
  • 所有这些&lt;= 运算符似乎都不正确。

标签: c arrays pointers 2d


【解决方案1】:

您的代码有几个问题:

  • 您不应在 for 循环中使用 &lt;=,您可以访问数组末尾之外的元素。
  • 行数和列数加一。
  • 您应该直接传递数组,而不是传递数组元素或暂时传递目标数组的地址。

这是一个更正的版本:

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

void addArrays(int rowSize, int columnSize, int Array1[rowSize][columnSize],
               int Array2[rowSize][columnSize],
               int Result[rowSize][columnSize]);
void printArray(int rowSize, int columnSize, int arrayValue[rowSize][columnSize]);

/*
This program will make 2 2D matrices out of a random number of rows
and 3 columns, and a random set of values.
Then, the two matrices will be added and all three printed.
*/

int main() {
    //To get a pseudo random number
    srand(time(NULL));

    int rowSize = rand() % 4 + 1;  // number between 1 and 4
    int columnSize = 3;
    int Array1[rowSize][columnSize];
    int Array2[rowSize][columnSize];
    int Arraysum[rowSize][columnSize];

    //Makes a unique number for each part of both arrays from 0-50
    for (int row = 0; row < rowSize; row++) {
        for (int col = 0; col < columnSize; col++) {
            Array1[row][col] = rand() % 50;
            Array2[row][col] = rand() % 50;
        }
    }

    //Add matrices
    addArrays(rowSize, columnSize, Array1, Array2, Arraysum);

    //Utilizes the print function
    printArray(rowSize, columnSize, Array1);
    printArray(rowSize, columnSize, Array2);
    printArray(rowSize, columnSize, Arraysum);
    return 0;
}

void addArrays(int rowSize, int columnSize, int a1[rowSize][columnSize],
               int a2[rowSize][columnSize], int result[rowSize][columnSize]) {
    for (int row = 0; row < rowSize; row++) {
        for (int col = 0; col < columnSize; col++)
            result[row][col] = a1[row][col] + a2[row][col];
    }
}

void printArray(int rowSize, int columnSize, int array[rowSize][columnSize]) {
    for (int row = 0; row < rowSize; row++) {
        printf("\n");
        printf("[");
        for (int col = 0; col < columnSize; col++) {
            printf(" %d ", array[row][col]);
        }
        printf("]");
    }
    printf("\n\n");
}

【讨论】:

  • 是的,谢谢你找到这个。这实际上是我的一半问题。我还是编程新手。
【解决方案2】:

替换你的 addArrays(..) 函数:

void addArrays(int rowSize, int columnSize, int a1[rowSize][columnSize], int a2[rowSize][columnSize], int sumloc[rowSize][columnSize]) {

int row;
int col;

for(row = 0; row <= rowSize; row++)
    for(col = 0; col <= columnSize; col++)
        sumloc[row][col] = a1[row][col] + a2[row][col];

return;
}

您的函数原型中不需要sumloc 处的*,也不必为它分配更多内存。

【讨论】:

    【解决方案3】:

    TL/DR 版本

    您根本不需要(直接)在此代码中使用指针;只需将addArrays 函数称为

    addArrays(rowSize, columnSize, Array1, Array2 ,Arraysum);
    

    并将声明/定义更改为

    void addArrays(int rowSize, int columnSize, int Array1[rowSize][columnSize],
               int Array2[rowSize][columnSize],
               int sumloc[rowSize][columnSize])
    

    完全失去对malloc 的调用,并从对sumloc 的任何引用中失去* 运算符:

    sumloc[row][col] = a1[row][col] + a2[row][col];
    

    同样,将printArray的调用改为

    printArray(rowSize, columnSize, Arraysum);
    

    略长的版本

    除非它是 sizeof 或一元 &amp; 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,否则 表达式 类型为 "N-element T" 的数组将被转换 ("decay") 为类型为 "pointer to T" 的表达式,表达式的值将是数组第一个元素的地址。

    您的第一组问题在函数调用中:

    addArrays(rowSize, columnSize, Array1[rowSize][columnSize],
              Array2[rowSize][columnSize],&Arraysum[rowSize][columnSize]);
    

    首先,您没有在此调用中将 arrays 作为参数传递;您正在传递Array1Array2单个元素 以及指向Arraysum 的单个元素的指针,并且所有这些元素都超出了各自数组的末尾(请记住N-element 数组的索引从0N-1,因此每个数组的最后一个元素将位于索引[rowSize-1][columnSize-1])。

    您要传递的是 数组表达式,而不是单个元素,如下所示:

    addArrays( rowSize, columnSize, Array1, Array2, Arraysum );
    

    由于三个数组表达式不是sizeof或一元&amp;运算符的操作数,它们的类型将从“N-T的元素数组”转换为“指向T 的指针”。在这种情况下,NrowSizeT 是“columnSize-int 的元素数组”。因此,函数实际接收的是int (*)[columnSize]类型的三个参数。

    另外,在函数参数声明的上下文中,T a[N]T a[] 等价于T *a1;这三个都将a 声明为指向T 的指针,而不是T2 的数组。

    意思是

    void addArrays( int rowSize, int columnSize, int Array1[rowSize][columnSize],
      int Array2[rowSize][columnSize], int sumloc[rowSize][columnSize])
    

    可以写成

    void addArrays( int rowSize, int columnSize, int Array1[][columnSize],
      int Array2[][columnSize], int sumloc[][columnSize])
    

    void addArrays( int rowSize, int columnSize, int (*Array1)[columnSize],
      int (*Array2)[columnSize], int (*sumloc)[columnSize] )
    

    无论声明的形式如何,您仍然可以将每个数组表达式作为常规二维数组 (sumloc[i][j] = Array1[i][j] + Array2[i][j];) 访问。

    请注意,由于您实际上是在传递 指针,因此对 addArray 函数中的数组所做的任何更改都会反映在调用方 (main) 中。这就是为什么您不需要对Arraysum 参数使用&amp; 运算符(并注意表达式&amp;Arraysum 的类型是int (*)[rowSize][columnSize] - 即@ 指向rowSize 的指针987654371@数组int). While the expressionsArraysumand&Arraysum`产生相同的(数组的地址与数组的第一个元素的地址相同),类型 两种表达方式不同,类型很重要。


    1。函数参数声明中 T a[]T *a 的等价是从 B 编程语言中继承而来的,C 是从 B 语言派生的。在 B 中,使用空方括号(如 auto p[])声明了一个指针变量。就个人而言,我认为保留仅在一种上下文中有效的另一种指针声明形式是错误的,但我不是语言设计者。
    2. 适用于函数参数声明,而不是常规声明。

    【讨论】:

      猜你喜欢
      • 2021-10-09
      • 1970-01-01
      • 2016-04-27
      • 1970-01-01
      • 2014-12-31
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多