Pointers and matrices catching something unexpected

Asked

Viewed 111 times

2

#include <stdio.h>

int main()
{
    int vetor[][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int valor= *(vetor[1] + 1) + **(vetor + 3);
    printf("%d", valor);
}

The code above was taken from theoretical exercises, but I do not have the feedback, but I checked that compiles and prints the value 15. However my doubts are as follows:

  1. Why the array was declared with the empty line subscript int vetor[][3] and what’s the difference between int vetor[0][3]?

  2. I understood that the excerpt vetor[1]+1 returns the value 5 of the array, but why the excerpt **(vetor+3) returns the value 10?

  3. Why the pointer to pointer **(vetor+3) works but the pointer *(vetor+3) doesn’t work?

2 answers

9

First let’s agree that this code is potentially wrong. It compiles into bad or poorly configured compilers. I wouldn’t try to learn from him.

Why the array was declared with empty line subscript int vetor[][1] and what’s the difference between int vetor[0][1]?

Because he picks up the size informed in the literal just ahead in the assignment, he tells that he has 12 and as one of the dimensions is 3 he adopts 4 and uses this number.

If using 0 will have a size of 0, it’s not what you want, it makes no sense to have a array that fits 0 elements. In good compiler nor would accept.

Needless to do these crazy things, better write code readable and according.

I understood that the excerpt vetor[1] + 1 returns the 5 value of array, but why the passage **(vetor+3) returns the value 10?

For the same reason that the previous section took 4 and added with 1 (first element of the second dimension within element 1 of the first dimension). He took the first element of the second dimension inside element 3 of the first dimension, which is 10.

Why the pointer to pointer **(vetor+3) works but the pointer *(vetor+3) doesn’t work?

Because you’re taking the value of the second dimension and not the first, so there are two indirect.

This code does the same thing with the same commitments and is much more readable:

#include <stdio.h>

int main() {
    int vetor[4][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
    printf("%d", vetor[1][0] + 1 + vetor[3][0]);
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

2


Why the array was declared with the empty line int'subscript vector[][3] and the difference between int vector[0][3]?

In this line you are creating an array. When you stop specifying the amount of elements in a vector it is generated based on the amount of elements that you place on its initialization. For example:

int v[] = {1, 2, 3};

In this case the vector v will be generated with 3 elements. In your case, only the number of columns of the matrix has been defined. As at startup we have 12 elements, the program will create an array of 4 rows by 3 columns. It would be a better practice to define beforehand the amount of elements, thus:

int vetor[4][3] = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};

The code above makes it clear how the matrix will be organized, in addition to previously defining the amount of elements.

I understood that the vector chunk[1]+1 returns the value 5 of the array, but by that the passage **(vector+3) returns the value 10 ?

Let’s look at the case first *(vetor[1]+1). Remember that the vector is a pointer to the first element and the following elements are stored in sequence. As the variable vetor is a matrix (i.e., a vector vector) when placed vetor[1] the address is returned to row 1 of the matrix (i.e., the address for element 0 of row 1). When adding 1 to this address we get the address of the next element (element 1 of row 1 of the matrix, remembering that rows and columns are counted from 0). When placing * before vetor, which is storing the address, we took the amount that is stored at that address, hence 5. In part **(vetor+3) what happens is we take vetor (which is a pointer to a pointer, because it’s a vector vector and each vector is a pointer) and we add 3 to it. What happens then is that we take the pointer that contains the address for vetor[3]. vetor is a pointer to pointer. So when you use *vetor[3] you are accessing the content of v[3], which will be a pointer, and then accessing the content of that other pointer.

Why the pointer for pointer **(vector+3) works but the pointer *(vector+3) does not work?

As stated in the previous answer, *(vetor+3) is only the address for the content you want to access. To access it you must use **(vetor+3).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.