使用指针传递二维数组 (C)

Passing 2D Arrays with Pointers (C)

下面是我正在使用的代码。当我 运行 它并注释掉处理 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;
}

替换您的 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 处不需要 *,也不必为其分配更多内存。

您的代码有几个问题:

  • 您不应在 for 循环中使用 <=,因为您访问的元素超出了数组的末尾。
  • 行数和列数都减一
  • 您应该直接传递数组,而不是传递数组元素或尝试传递目标数组的地址。

这是更正后的版本:

#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");
}

TL/DR版本

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

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

并将 declaration/definition 更改为

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 或一元 & 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,否则 表达式 [= "N-element array of T" 类型的 121=] 将被转换 ("decay") 为 "pointer to T" 类型的表达式,表达式的值将是数组第一个元素的地址。

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

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

首先,您没有将 arrays 作为参数传递给这个调用;您正在传递 Array1Array2 单个元素 和指向 Arraysum 的单个元素的指针,并且所有这些元素都是过去的它们各自数组的末尾(请记住,N 元素数组的索引是从 0N-1,因此每个数组的最后一个元素将位于索引 [rowSize-1][columnSize-1] 处) .

你要传递的是数组表达式,而不是单个元素,像这样:

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

由于三个数组表达式不是sizeof或一元&运算符的操作数,它们的类型将从“N-T" 到 "pointer to 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 参数使用 & 运算符(并注意表达式 &Arraysum 的类型是 int (*)[rowSize][columnSize] - 即int). While the expressionsArraysumand&Arraysum` 的 columnSize 数组指向 rowSize 的指针产生相同的 value(数组的地址是与数组第一个元素的地址相同),两个表达式的 types 不同,类型很重要。


1。函数参数声明中 T a[]T *a 的等价性是 B 编程语言的遗留物,C 是从该语言派生出来的。在 B 中,指针变量使用空方括号声明,如 auto p[]。就个人而言,我认为保留仅在一种上下文中有效的指针声明的替代形式是错误的,但我不是语言设计者。
2. 这 只有 对函数参数声明是正确的,而不是常规声明。