Pointers and arrays picking up something not expected

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 it compiles and prints the value 15. However my doubts are as follows:

  • Why is the array declared with the 'subscript' of empty line int vetor[][3] and what is the difference between int vetor[0][3] ?

  • I understood that the vetor[1]+1 snippet returns the value 5 of the array, but why does the% wrapper return the value 10?

  • Why the pointer to pointer **(vetor+3) it works but the **(vetor+3) pointer does not work?

  • asked by anonymous 25.09.2018 / 19:32

    2 answers

    1
      

    Why the array was declared with the 'subscript' of the empty line int   vector [] [3] and what is 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 put in the startup it. 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 in the array was defined. Since 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 prioritize the amount of elements, like this:

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

    The above code makes it clear how the array will be organized, as well as setting the number of elements in advance.

      

    I understood that the vector segment [1] +1 returns the value 5 of the array, but for   that the stretch ** (vector + 3) returns the value 10?

    Let's first look at the *(vetor[1]+1) case. Remembering that the vector is a pointer to the first element and the following elements are stored in sequence. Since the variable vetor is an array (that is, a vector of vectors), when you put vetor[1] , the address is returned to line 1 of the array (that is, the address for element 0 of line 1). Adding 1 to this address takes the address of the next element (element 1 of row 1 of the array, remembering that rows and columns are counted from 0). By putting the * before vetor , which is storing the address, we get the value that is stored in that address, therefore 5. In the **(vetor+3) part what happens is that we get vetor (which is a pointer to a pointer because it is a vector of vectors and each vector is a pointer) and we add 3 to it. What happens then is that we get 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 contents of v [3], which will be a pointer, and then accessing the contents of that other pointer.

      

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

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

        
    26.09.2018 / 21:19
    9

    First let's agree that this code is potentially wrong. It compiles into bad or misconfigured compilers. I would not try to learn from him.

      

    Why the array was declared with the 'subscript' of the empty line int vector and what is the difference between int vector 0 ?

    Because it takes the size informed in the literal just ahead in the assignment, it says that it has 12 and as one of the dimensions is 3 it adopts 4 and uses this number.

    If using 0 will have a size of 0, it is not what you want, it does not make sense to have an array that fits 0 elements. In a good compiler I would not even accept it.

    Unnecessary to do these crazy things, better write a readable and compliant code.

      

    I understood that the vector string 1 +1 returns the value 5 of the array , but why the snippet ** (vector + 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 inside element 1 of the first dimension). He took the first element of the second dimension into element 3 of the first dimension, which is 10.

      

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

    Because you're getting the value of the second dimension and not the first, then there are two Indents .

    This code does the same thing with the same appointments 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]);
    }
    

    See running on ideone . And in Coding Ground . Also put it on GitHub for future reference .

        
    25.09.2018 / 19:54