简体   繁体   中英

Passing 2D Arrays with Pointers (C)

Below is the code I am working with. This works perfectly fine when I run it and comment out the code dealing with the addArray s function.

I believe I am not using the pointers properly in the addArrays function. Any help will be appreciated.

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

Replace your addArrays(..) function:

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;
}

You don't need the * at sumloc in your function prototype, and you don't have to allocate any more memory for it.

Your code has several issues:

  • You should not use <= in your for loops, you access elements beyond the end of the arrays.
  • The number of rows and columns are of by one.
  • You should pass the arrays directly instead of passing the array elements or tentatively passing the address of the destination array.

Here is a corrected version:

#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 Version

You don't need to muck with pointers (directly) in this code at all; just call the addArrays function as

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

and change the declaration/definition to

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

lose the call to malloc completely, and lose the * operator from any references to sumloc :

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

Similarly, change the call to printArray to

printArray(rowSize, columnSize, Arraysum);

Slightly Longer Version

Except when it is the operand of the sizeof or unary & operator, or is a string literal used to initialize another array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array.

Your first set of issues are in the function call:

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

First of all, you're not passing the arrays as parameters in this call; you're passing a single element of Array1 and Array2 and a pointer to a single element of Arraysum , and all of these elements are past the end of their respective arrays (remember that an N -element array is indexed from 0 to N-1 , so the last element of each array would be at index [rowSize-1][columnSize-1] ).

What you want to pass are the array expressions , not single elements, like so:

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

Since the three array expressions are not the operands of the sizeof or unary & operators, their types will be converted from " N -element array of T " to "pointer to T ". In this case, N is rowSize and T is " columnSize -element array of int ". Thus, what the function actually receives are three parameters of type int (*)[columnSize] .

Also, in the context of a function parameter declaration, T a[N] and T a[] are equivalent to T *a 1 ; all three declare a as a pointer to T , not as an array of T 2 .

That means

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

could be written as

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

or

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

Regardless of the form of declaration, you'd still access each array expression as a regular 2D array ( sumloc[i][j] = Array1[i][j] + Array2[i][j]; ).

Note that since you're actually passing pointers , any changes made to the arrays in the addArray function are reflected in the caller ( main ). This is why you don't need to use the & operator for the Arraysum parameter (and note that the type of the expression &Arraysum is int (*)[rowSize][columnSize] - that is, a pointer to a rowSize by columnSize array of int). While the expressions int). While the expressions Arraysum and &Arraysum` yield the same value (the address of an array is the same as the address of the first element of the array), the types of the two expressions are different, and types matter.


1. The equivalence of T a[] and T *a in a function parameter declaration is a holdover from the B programming language, from which C was derived. In B, a pointer variable was declared using empty square brackets like auto p[] . Personally, I think keeping an alternative form of pointer declaration that's only valid in one context is a mistake, but I'm not a language designer.
2. This is only true for function parameter declarations, not regular declarations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM