1

I am trying to manipulate some 2D array using pointers, I know the basics of pointers but I am having difficulties with this code :

{
    

    char a[3][10] = { "Malek", "Zied","Nicolas" };
    char* ptr = a;

    char c = *(*(a + 1) + 1);
    char r = *(ptr + 1)+1;
    printf("i from Zied is %c :\n", c);
    printf("i from zied is also : %c", c);
    return 0;
}

Now ptr contains the adress of a so I don't understand why the *(ptr + 1)+1 give back a char and not an adress. should not a and ptr be similar in this case ? how are : * (* (a + 1) + 1) and (* (ptr + 1)+1) not the same and also * (ptr + 1)+1 and * ( *(a + 1) + 1) the same ? Thanks in advance

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Malek
  • 13
  • 3
  • 2
    The line `char* ptr = a;` is invalid, because the expression `a` [decays](https://stackoverflow.com/q/1461432/12149471) to a pointer to the first element of the array `a` and therefore has type `char(*)[10]` (pointer to an array of 10 elements of type `char`), whereas `ptr` is of type `char*` (pointer to `char`). Since both pointers are of different type, the assignment is invalid (unless you use an explicit cast). Your compiler should be at least giving you a warning about this invalid line. – Andreas Wenzel Feb 25 '23 at 04:22
  • This distinction is important, because pointer arithmetic is performed in units of the type that it points to. – Barmar Feb 25 '23 at 06:17

2 Answers2

0

The compiler should issue a message for the declaration of the pointer ptr:

char a[3][10] = { "Malek", "Zied","Nicolas" };
char* ptr = a;

because the type of the pointer ptr and the pointer type of the initializing expression are not compatible and there is no implicit conversion between the pointer types. The array a used as an initializer is implicitly converted to pointer to its first element of the type char ( * )[10] while the initialized pointer ptr has the type char *.

You should write:

char a[3][10] = { "Malek", "Zied","Nicolas" };
char* ptr = ( char * )a;

That is in this initialization the two-dimensional array is interpreted as a one-dimensional array and the pointer ptr now points to the character 'M' of the first "row" of the two-dimensional array a.

In fact the above declaration of the pointer ptr is equivalent to:

char* ptr = &a[0][0];

Thus the expression ptr + 1 points to the second character (a[0][1]) that is to the character 'a' of the string "Malek". Dereferencing the pointer expression *( ptr + 1 ) you get the pointed character 'a' and adding 1 to the character 'a' *(ptr + 1)+1 you get the character 'b'.

In fact this expression *(ptr + 1)+1 is equivalent to p[1] + 1.

As for this expression *(*(a + 1) + 1) then as it was already mentioned the a is implicitly converted to pointer to its first element ("row") of the type char ( * )[10]. The expression a + 1 points to the second "row" of the array that is to the second element of the array. The expression *( a + 1 ) yields lvalue of the of the one-dimensional array of the type char[10] that is the second "row" of the array a.

In this expression *(a + 1) + 1 the expression *( a + 1 ) is in turn implicitly converted to pointer to its first element of the type char *. That is the expression of the type char[10] is converted to an expression of the type char * that points to the first character of the second "row". So the whole expression points to the second character of the second "row" that is to the character 'i' Dereferencing the pointer expression you get this character 'i'.

And this expression *(*(a + 1) + 1) is equivalent to a[1][1].

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you very much. I have a small question : `char* ptr = &a[0][0];` can be written as `char**ptr = &a[0]` right ? Such as the double pointer ptr contains the address of the first 1D array of 10 elements. I can also use `ptr + ` to simply point to the second 1D array and finally use `*(ptr+1)` or `ptr[1] ` to point to the first element of the second 2D array and finally `ptr[1][1]` or `*(*(ptr+1))` to access its content, but it can't be changed to another value due to the fact that we have a string lateral here,. Is that correct ? – Malek Feb 26 '23 at 16:03
  • @Malek The expression a[0] has the type char[10]. So the expression &a[0] has the type char ( * )[10]. It is not the same as char **. – Vlad from Moscow Feb 26 '23 at 17:17
0

pointer arithmetic won't work with arrays. pointers and arrays are not the same. read this

niki
  • 23
  • 7