In which case I need ampersand in pointers?

168 Views Asked by At

I am trying to understand pointer to pointers and I can not understand why in first case I need (&) ampersand ( I receive a message [Error] cannot convert 'char*' to 'char**' in assignment ) and in the second case I don't need ampersand

first case :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


int main ()
{
    
    char *p ={"jack is a good boy"};
    
    char**p1;
    
    p1=p; //why I need & in this case
    
    return0;
}

second case :

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


int main ()
{
    
    char *p[5] ={"jack","is", "a","good","boy"};
    
    int i=0;
    
    char**p1;
    
    p1=p;
    
    //p1=&p[0];
    
    for(p1=p; *p1; p1++)
    {
        
        
        printf("\n the words are %s",*p1);
    }
    
    return 0;
}
2

There are 2 best solutions below

2
On

p1=p; //why I need & in this case

The variable p has the type char *

char *p ={"jack is a good boy"};

While the variable p1 has the type char **

char**p1;

So you are trying to use incompatible pointer types in the assignment statement.

You need to write

p1 = &p;

In this case the pointer p1 will point to the object p that has the type char *. That is a pointer to the object p will have the type char **.

In the second program you declared an array with the element type char *.

char *p[5] ={"jack","is", "a","good","boy"};

Array designator used in expressions with rare exception is implicitly converted to pointer to its first element

So in this assignment statement

p1=p;

that is equivalent to

p1 = &p[0];

the expression p used as an initializer is converted to the type char **. So the left and the right operands of the assignment have the same pointer type.

Pay attention to that this for loop

for(p1=p; *p1; p1++)
{
    
    
    printf("\n the words are %s",*p1);
}

invokes undefined behavior because the array p does not have a null pointer among its elements. Thus the condition of the for loop *p1 that is the same as *p1 != NULL will not be evaluated for elements of the array p.

If the loop will be correct you need to include an element that is equal to null pointer, For example

char *p[6] ={"jack","is", "a","good","boy"};
       ^^^

or

char *p[] = {"jack","is", "a","good","boy", NULL };
0
On

The unary & operator could be seen as a pointer-to operator.

From the first example, p is a pointer to char and p1 is a pointer to a pointer to a char. But when you have &p it becomes a pointer to a pointer to a char, of the type char **, which makes is the same type as p1.

In the second example, p is an array of pointers. And as all arrays it can decay to a pointer to its first element. So just using p alone is the same as &p[0]. And as p[0] is a pointer to char (i.e. char *) then &p[0] is a pointer to a pointer to char (i.e. char **).

So in the first example the pointer-to operator must be used to get a pointer to a pointer to char. This isn't needed in the second example because the pointer-to operator is used implicitly.