NubeToAdroit
NubeToAdroit

Reputation: 29

C, array of pointers: int n[5], int *p[5], assign p[i] = &n[i], why *p is the same as p?

SORRY, I misread my results, *p and p are different


I am trying to make an understanding about array of pointers.

I wrote

int n[5] = {1,2,3,4,5};
int *p[5];
for(i = 0; i < 5; i++){
    p[i] = &n[i];
}

so far so good.

and I understand that

printf("%0x\n", *p);

gives me the address of the first pointer in the array.


what's troubling me is p, just p, no asterisk, no brackets.

because

printf("%0x\n", *p);
printf("%0x\n", p);

[give me exactly the same thing. Why is p also the address of the first pointer in the array??] WRONG, SORRY!

What exactly does p mean, when an array of pointers like above is declared?


A related question

int main(int argc, char *argv[]){
    for(int i = 0; i < argc; i++){
        printf("%s\n",argv[i]); //why not *argv[i]??
    }
}

since argv is declared as an array of pointers, shouldn't argv[i] yield the address instead of the string where it points to? because it doesn't have an asterisk in front it.

Thanks in advance.

Upvotes: 1

Views: 133

Answers (3)

Haris
Haris

Reputation: 12270

p, just p, no asterisk, no brackets gives the address of the first element of the array p[]. *p on the other hand gives the value of the first element of the array p[], which happens to be the address of the first element of the array n[], according to the code you show.


Lets take an example, assuming an integer is of size 4 bytes and an address if of size 8 bytes, and the first program that you showed.

int n[5] = {1,2,3,4,5};
int *p[5];
for(i = 0; i < 5; i++)
{
    p[i] = &n[i];
}

The arrays would look something like this.. (addresses are assumed for explanation purpose, they are not real).

n[] = { 1,  2,  3,  4,  5};  //these are integers
     // ^   ^   ^   ^   ^
    // 100 104 108 112 116    these are the addresses of the elements of array n[]

p[] = { 100, 104, 108, 112, 116}; // these are pointer to integers
     //  ^    ^    ^    ^    ^
     // 200  208  216  224  232   these are adddress of the elements of array p[]

Now, p, just p, no asterisk, no brackets would give the value 200, which is the address of the first element of the array p[].

Like wise n would give the value 100.

*p would give the value 100 which is the element stored in the first position of the array p[].

Upvotes: 4

R Sahu
R Sahu

Reputation: 206607

Given,

int n[5] = {1,2,3,4,5};
int *p[5];
for(int i = 0; i < 5; i++){
   p[i] = &n[i];
}

printf("0x%p\n", *p);
printf("0x%p\n", p);

The output is definitely not expected to be the same.

I get

0x0x7fffe0c40b40
0x0x7fffe0c40b60

on my desktop.

If I use:

printf("%0x\n", *p);
printf("%0x\n", p);

I get the following warning when compiled using gcc -Wall

soc.c: In function ‘test’:
soc.c:12:4: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
    printf("%0x\n", *p);
    ^
soc.c:13:4: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int **’ [-Wformat=]
    printf("%0x\n", p);

Even then, I get the following output:

3ef18920
3ef18940

As you can see, they are not the same.

Perhaps you are seeing symptoms of undefined behavior due to use of incorrect format specifier.

See the output of both forms at http://ideone.com/73UoDa.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409186

When you use just p it decays to a pointer to the first element in the array p, i.e. p is equivalent to &p[0].

When you dereference that pointer you get the pointer stored in p[0]. I.e. when you do *p it's the same as doing as doing *&p[0], and the dereference and address-of operators take out each-other giving you only p[0], which in your case is equal to &n[0].

Also note that when you want to print pointers using printf you should be using the format "%p" (and really pass a void * as argument).


The not really related question is because argv is an array of pointer to characters. For any valid index i the expression argv[i] gives you a pointer, of type char *. If you dereference this pointer you get the character pointed to by argv[i], i.e. a single character.

Upvotes: 1

Related Questions