1

I need help finding the appropriate way to provide values to my function in C which can be seen below:

void matrixMultiply(int *A[], int *B[]) I have the following function that needs 2 pointer to arrays, and those pointers point to two 2d arrays. I have the following main function, but I just can't seem to figure out a way to pass my arrays to the function.

int main()
{
    int arr[2][2] = {
        { 1, 2 },
        { 5, 6 }
    };

    int(*p)[2];

    p = &arr;

    int arr2[2][1] = {
        { 11 },
        { 55 }
    };
    int(*l)[1];

    l = arr2;

    for (int i = 0; i < 4; i++) // I don't know if I need this but I used it before when I was experimenting with the form p[i].
    {
        matrixMultiply(p, l);   // p and l are the pointers to the two 2d arrays I have
    }

    return 0;
}

This is the updated code:

int main()
{
    int arr[2][2] = {
        { 1, 2 },
        { 5, 6 }
    };

    int(**p);

    p = &arr;

    int arr2[2][1] = {
        { 11 },
        { 55 }
    };
    int(**l);

    l = arr2;

    for (int i = 0; i < 4; i++) // I don't know if I need this but I used it before when I was experimenting with the form p[i].
    {
        matrixMultiply(p, l);   // p and l are the pointers to the two 2d arrays I have
    }

    return 0;
}

new errors: enter image description here

C:\WINDOWS\system32\cmd.exe /C ""C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/mingw32-make.exe" -j12 SHELL=cmd.exe -e -f  Makefile"

C:/Users/Owner/Desktop/Codes/aee22eeCodes/main.c: In function 'main':
C:/Users/Owner/Desktop/Codes/aee22eeCodes/main.c:49:16: warning: passing argument 1 of 'matmul' from incompatible pointer type [-Wincompatible-pointer-types]
         matmul(&arr, &arr2);   // p and l are the pointers to the two 2d arrays I have
                ^~~~
C:/Users/Owner/Desktop/Codes/aee22eeCodes/main.c:12:18: note: expected 'int **' but argument is of type 'int (*)[2][2]'
 void matmul(int *A[], int *B[])
             ~~~~~^~~
C:/Users/Owner/Desktop/Codes/aee22eeCodes/main.c:49:22: warning: passing argument 2 of 'matmul' from incompatible pointer type [-Wincompatible-pointer-types]
         matmul(&arr, &arr2);   // p and l are the pointers to the two 2d arrays I have
                      ^~~~~
C:/Users/Owner/Desktop/Codes/aee22eeCodes/main.c:12:28: note: expected 'int **' but argument is of type 'int (*)[2][1]'
 void matmul(int *A[], int *B[])
                       ~~~~~^~~
====0 errors, 4 warnings====
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • I love your code indent, I'm definitely saving this. – Captain Trojan Jun 02 '21 at 19:31
  • Im new to coding allow me :( – HelpMEInCPls Jun 02 '21 at 19:41
  • why exactly do you call the function 4 times in the loop with absolutely the same args? – Serge Jun 02 '21 at 19:55
  • Pls ignore that, like I said in the comments I was trying everything before like my call was matrixMultiply(p[i], l[i]); or matrixMultiply(p+i, l+i); which didn't really work. that for loop just stuck around even though in this iteration of the code it was not used – HelpMEInCPls Jun 02 '21 at 20:04
  • `int(*p)[2];`, by the way, is an array of two `int` *function* pointers. – Captain Trojan Jun 02 '21 at 20:08
  • Would I change that to 4? – HelpMEInCPls Jun 02 '21 at 20:17
  • Well, a *function* is not really an *array*. If you feel like assigning your arrays to new variables `p` and `l` instead of passing the original arrays directly, declare `p` and `l` as `int** p` and `int** l` (double pointer, pointer to pointer). – Captain Trojan Jun 02 '21 at 20:19
  • Hey, could you please look at the update code, is that what I was supposed to do? because its still not working, also I can't change the matrixMultiply parameters – HelpMEInCPls Jun 02 '21 at 20:30
  • 2
    @CaptainTrojan. No, 'int(*p)[2];' is no function pointer. It is a pointer to an array of two ints. – tstanisl Jun 02 '21 at 20:32
  • Im really sorry, I don't understand what I should be changing if its a pointer to a array of 2 ints should I change int(*p)[2]; to int(*p)[4]; since the array it points to contains 4 ints. Also maybe could you make the correct changes on the code I provided I would really appreciate it. I am kinda lost right now – HelpMEInCPls Jun 02 '21 at 20:44
  • Related: [Passing an array as an argument to a function in C](https://stackoverflow.com/questions/6567742/passing-an-array-as-an-argument-to-a-function-in-c) – Gabriel Staples Jun 02 '21 at 21:13
  • Please don't paste errors as screenshots or images; instead: paste the actual text. The screenshot can be added too to show coloring, but should be _in addition_ to the actual text, not instead of it. Once you paste the text, we can help you with formatting. – Gabriel Staples Jun 02 '21 at 21:15
  • @CaptainTrojan and tstanisl, see [my answer here](https://stackoverflow.com/a/51527502/4561887) where I talk about that. – Gabriel Staples Jun 02 '21 at 21:20
  • sorry I have updated the post with the error text. – HelpMEInCPls Jun 02 '21 at 21:28
  • It would improve the question to show the `matrixMultiply` function (and clarify whether that exact prototype is a requirement, or just something you did) – M.M Jun 02 '21 at 21:29
  • all the matrix multiply function does it multiply 2 matrices with the help of 3 for loops, I know that part of the function works perfectly because I actually tested it. And yes the prototype is a requirement, I can not change anything about it, So I have to pass the values according to what it required by the prototype. Also matmul is matrixMultiply function, I have just renamed it everything else is the same. – HelpMEInCPls Jun 02 '21 at 21:34
  • Related: [How to pass a multidimensional array to a function in C and C++](https://stackoverflow.com/questions/2828648/how-to-pass-a-multidimensional-array-to-a-function-in-c-and-c) and https://www.geeksforgeeks.org/pass-2d-array-parameter-c/. – Gabriel Staples Jun 02 '21 at 21:49
  • @HelpMEInCPls, would this _style_ of prototype be acceptable to you instead? `void printArray4(int *a, size_t num_rows, size_t num_cols)`. I have this working perfectly. NB: `a` is a pointer to the start of a contiguous 2D array of `int`s. So, I treat it as such. – Gabriel Staples Jun 02 '21 at 23:04

1 Answers1

0

This answer is a snippet of my full answer here.

Here are 4 techniques and when to use each. If your array sizes are fixed and known at compile-time, your prototype and call should look like this:

void matrixMultiply(int (*a)[2][2], int (*b)[2][1]);
matrixMultiply(&arr, &arr2);

...but I don't have enough information from you, so here are the 4 techniques and when to use each. You can follow these examples to create the right answer for your particular situation.

Assume you have the following 2D array:

int arr[][2] =
{
    {1, 2},
    {5, 6},
    {7, 8},
};

...and the following macro definitions:

// Get the number of elements in any C array
// - from my repo here:
//   https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/utilities.h#L42
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))

/// Definitions: `rows` = "rows"; `cols` = "columns"

/// Get number of rows in a 2D array
#define NUM_ROWS(array_2d) ARRAY_LEN(array_2d)

/// Get number of columns in a 2D array
#define NUM_COLS(array_2d) ARRAY_LEN(array_2d[0])
  1. If the 2D array is ALWAYS the same size each time (it has a FIXED number of rows, and a FIXED number of columns) (3 rows and 2 columns in the below example), do this:
    // 1. Function definition
    void printArray2(int (*a)[3][2])
    {
        // See my function definition here: 
        // https://stackoverflow.com/a/67814330/4561887
    }
    
    // 2. Basic usage
    // NB: `&` is REQUIRED! See my answer for why: https://stackoverflow.com/a/51527502/4561887
    printArray2(&arr);
    
    // 3. Usage via a pointer
    // `int (*a)[3][2]` is an explicit ptr to a 3x2 array of `int`. This array pointer does NOT
    // naturally decay to a simpler type.
    int (*p2)[3][2] = &arr; // must use `&` and MUST USE THESE PARENTHESIS!
    printArray2(p2);
    
  2. If the 2D array has a VARIABLE number of rows, but a FIXED number of columns (2 in this case), do this:
    // 1. Function definition
    void printArray3(int a[][2], size_t num_rows)
    {
        // See my function definition here: 
        // https://stackoverflow.com/a/67814330/456188
    }
    
    // 2. Basic usage
    printArray3(arr, NUM_ROWS(arr));
    
    // 3. Usage via a pointer
    // `int a[][2]` naturally decays to `int* [2]`
    int (*p3)[2] = arr; // MUST USE THESE PARENTHESIS!
    printArray3(p3, NUM_ROWS(arr));
    
  3. If the 2D array has a VARIABLE number of rows AND a VARIABLE number of columns, do this (this approach is the most-versatile and is generally my go-to approach for multidimensional arrays):
    // 1. Function definition
    void printArray4(int *a, size_t num_rows, size_t num_cols)
    {
        // See my function definition here: 
        // https://stackoverflow.com/a/67814330/456188
    }
    
    // 2. Basic usage
    printArray4((int *)arr, NUM_ROWS(arr), NUM_COLS(arr));
    // OR: alternative call technique:
    printArray4(&arr[0][0], NUM_ROWS(arr), NUM_COLS(arr));
    
    // 3. Usage via a pointer
    // The easiest one by far!
    int *p4_1 = (int*)arr;
    // OR
    int *p4_2 = &arr[0][0];
    printArray4(p4_1, NUM_ROWS(arr), NUM_COLS(arr));
    printArray4(p4_2, NUM_ROWS(arr), NUM_COLS(arr));
    

If you have the following "2D" array, however, you must do something different:

// Each row is an array of `int`s.
int row1[] = {1, 2};
int row2[] = {5, 6};
int row3[] = {7, 8};
// This is an array of `int *`, or "pointer to int". The blob of all rows
// together does NOT have to be in contiguous memory. This is very different
// from the `arr` array above, which contains all data in contiguous memory.
int* all_rows[] = {row1, row2, row3}; // "2D" array
  1. If the 2D array is actually built up of a bunch of ptrs to other arrays (as shown just above), do this:
    // 1. Function definition
    void printArray5(int* a[], size_t num_rows, size_t num_cols)
    {
        // See my function definition here: 
        // https://stackoverflow.com/a/67814330/456188
    }
    
    // 2. Basic usage
    printArray5(all_rows, ARRAY_LEN(all_rows), ARRAY_LEN(row1));
    
    // 3. Usage via a pointer
    // `int* a[]` naturally decays to `int**`
    int **p5 = all_rows;
    printArray5(p5, ARRAY_LEN(all_rows), ARRAY_LEN(row1));
    

See my full answer here for the full function definitions for each function above, more details, example output, and full, runnable code: How to pass a multidimensional array to a function in C and C++

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265