0

I have the following basic C example:

#include <stdio.h>

struct Example {
    double arr[4][4];
    int size;
};

int main()
{
    struct Example e = {
        {{1., 0., 0., 0.},
         {0., 1., 0., 0.},
         {0., 0., 1., 0.},
         {0., 0., 0., 1.}},
         4
    };
    double** arr = e.arr;

    printf("%8.5f %8.5f %8.5f %8.5f\n", arr[0][0], arr[0][1], arr[0][2], arr[0][3]);
    printf("%8.5f %8.5f %8.5f %8.5f\n", arr[1][0], arr[1][1], arr[1][2], arr[1][3]);
    printf("%8.5f %8.5f %8.5f %8.5f\n", arr[2][0], arr[2][1], arr[2][2], arr[2][3]);
    printf("%8.5f %8.5f %8.5f %8.5f\n", arr[3][0], arr[3][1], arr[3][2], arr[3][3]);
}

What do I have to do to make the printf successfully print out the values in the matrix? If I declare arr as double** I get a segfault. If I try double* then it complains when I try to do double indexing. I've also tried double arr[4][4] = e.arr, but the compiler just tells me that it's an invalid initializer. What's the proper way to do this?

(I realize size is redundant in this example, I just wanted the struct to have more than one member.)

3
  • 1
    You can use a pointer to array like this double (*arr)[4] = e.arr. Note that e.arr is the same as &e.arr[0], but &e.arr[0] is the address of an entire array with 4 doubles (a line of the 2D matrix), so you need a pointer that can point to an entire array of length 4. Commented Jun 5, 2020 at 4:18
  • 2
    There is no copy of the array being made here, you are actually storing the address of the array in a pointer variable, so the pointer points to the original array, and the values printed belong to the original array, not a copy of it. Commented Jun 5, 2020 at 4:49
  • c-faq.com/aryptr will be helpful background information for you here. Commented Jun 5, 2020 at 5:08

2 Answers 2

1

You can do like this since the values of double arr[4][4] are consecutive in memory

double* arr = e.arr[0]; // points to first value

printf("%8.5f %8.5f %8.5f %8.5f\n", arr[0], arr[1], arr[2], arr[3]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr[4], arr[5], arr[6], arr[7]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr[8], arr[9], arr[10], arr[11]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr[12], arr[13], arr[14], arr[15]);

or alternatively, as @ismick pointed out in his comment you can write it like

double (*arr2)[4] = e.arr ;

printf("%8.5f %8.5f %8.5f %8.5f\n", arr2[0][0], arr2[0][1], arr2[0][2], arr2[0][3]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr2[1][0], arr2[1][1], arr2[1][2], arr2[1][3]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr2[2][0], arr2[2][1], arr2[2][2], arr2[2][3]);
printf("%8.5f %8.5f %8.5f %8.5f\n", arr2[3][0], arr2[3][1], arr2[3][2], arr2[3][3]); 

if you want that syntax.

Sign up to request clarification or add additional context in comments.

Comments

0

Alternative to the answer given by @AndersK, you can also try this.

#include <stdio.h>

struct Example {
    double arr[4][4];
    int size;
};

int main()
{
    int i, j;
    struct Example e = {
        {{1., 0., 0., 0.},
         {0., 1., 0., 0.},
         {0., 0., 1., 0.},
         {0., 0., 0., 1.}},
         4
    };
    double *arr = (double *)e.arr;

    for(i = 0; i < 4; ++i)
    {
        for(j = 0; j < 4; ++j)
            printf("%8.5f ", *(arr+i*4+j));
        putchar('\n');
    }
    return 0;
}

In this we are pointing to the first block of memory where e.arr[0] is stored, then we are traversing through the consecutive memory location using this expression (arr+i*4+j).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.