조성현
조성현

Reputation: 31

About array pointer

How can I get 'l' from this array pointer?

char *p[3][2] = {"abc", "defg", "hi", "jklmno", "pqrstuvw", "xyz"};

like

printf("%c\n",*((*p)) + 2);

Upvotes: 0

Views: 123

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

If I have understood correctly you are going to output the letter 'l' from the string literal "jklmno" using pointers.

This literal is in the row with the index 1 and in the column also with the index 1.

So to get access to the literal using the subscript operator you could write the expression p[1][1] that yields the pointer to the first character of the string literal. Now to get the character 'l' of the string literal you could write the expression p[1][1][2].

printf( "%c\n", p[1][1][2] );

Now let's do the same using pointers without the subscript operator.

An array designator used in expression with rare exceptions is converted to pointer to its first element.

Thus used in expressions the array designator p is converted to a pointer of the type char * ( * )[2] that points to the first row of the array.

To get a pointer to the second row of the array you should write p + 1.

To get the row itself you have to dereference the pointer

*( p + 1 )

This expression has the type char *[2].

But again as this expression is a designator of a one-dimensional array then used in expressions it is converted to pointer to its first element and has the type char **.

To access a pointer to the second element of the row you can use the pointer arithmetic

*( p + 1 ) + 1

To get the pointed element (string literal) you have to dereference the pointer

*( *( p + 1 ) + 1 )

this expression has the type char * and points to the first character of the string literal "jklmno".

To get a pointer to the third character of the string literal you have to use this expression

*( *( p + 1 ) + 1 ) + 2

Now you need to dereference the pointer to output the pointed letter 'l'.

*( *( *( p + 1 ) + 1 ) + 2 )

So the function call will look like

printf( "%c\n", *( *( *( p + 1 ) + 1 ) + 2 ) );

Compare it with the previously shown function call

printf( "%c\n", p[1][1][2] );

Take into account that if you have an array like

T a[N];

where T is some type then using the subscript operator to access the i-th element of the array you can write the expression a[i]. Under the hood this expression is evaluated using the pointer arithmetic like *( a + i ). Due to the commutative nature of the addition operator this expression can be written also like *( i + a ).. So using the subscript operator you may write the expression i[a] that is equivalent to the expression a[i].

From the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

Thus the expression

*( *( *( p + 1 ) + 1 ) + 2 )

may be rewritten like

*( 2 + *( 1 + *( 1 + p ) ) )

and correspondingly like

2[1[1[p]]]

and the call of the function printf

printf( "%c\n", p[1][1][2] );

also may be rewritten like (though you should not do this making the code obfuscated)

printf( "%c\n", 2[1[1[p]]] );

Here is a demonstrative program.

#include <stdio.h>

int main() 
{
    char *p[3][2] = 
    {
        { "abc", "defg" }, 
        { "hi", "jklmno" },
        { "pqrstuvw", "xyz" }
    };
    
    printf( "%c\n", 2[1[1[p]]] );
}   

Its output is

l

Upvotes: 2

mch
mch

Reputation: 9814

Let's use fully brace-enclosed declarations to make your array initializer clearer

char *p[3][2] = {{"abc", "defg"}, {"hi", "jklmno"}, {"pqrstuvw", "xyz"}};

now you can see that p[1] is the array {"hi", "jklmno"}.
then you want to get the second string, which is p[1][1] and then the 3rd character: p[1][1][2].

Here is a running example: https://ideone.com/Jd9GWI

Upvotes: 2

Related Questions