Member Avatar for Rahul47

Here is my code along with question in it.

#include<stdio.h>

int main(){
    int i,a[2][3]={{1,2,3},{4,5,6}},*p=&a;
    printf("%d",p);      // Printing the base value.

    printf("\n%d",p[4]); // Q) Does this means *(p + 4) ?
    printf("\n%d",p[5]); // Q) Does this means *(p + 5) ?
    getch();
    return 0;
}

Did it compiled and print out the result?

Anyway if I remember correctly, the array created should be...

a00 a01 a02     ==>   1  2  3
a10 a11 a12           4  5  6

Even though it looks like a 2 dimentional array, it can be seen as 1 dimentional array as well. The position of one dimentional array from this 2-D array would start from the top row first, and read through each column from left to right. Then go to the next row and read from left to right again.

[a00, a01, a02, a10, a11, a12]

Now when you call for p[4], what should the value you would see in the printf? And what is p[5]? I don't think you can use p[6] though because it may be out of range...

*p=&a is a type mismatch if you want to flatten the array. Try *p = &a[0] instead. Also note that this trick isn't strictly portable due to how C restricts pointers walking past the end of an array. It'll work on every implementation I'm aware of though.

Member Avatar for Rahul47

Did it compiled and print out the result?

Yep, It did printed out 5 and 6 as a[4]=5 and a[5]=6.

p[6] is out of question.

*p=&a is a type mismatch if you want to flatten the array.

I don't exactly follow how you say it. *p=&a or *p=a will assign base address to p, which is equivalent to *p=&a[0].

So p[4] is same as *(p+4) ?

*p=&a or *p=a will assign base address to p, which is equivalent to *p=&a[0].

Type matters, even if the addresses are all the same. *p = &a assigns a pointer to 2D array (ie. int(*)[2][3]) to a pointer to int, thus a type mismatch. *p = a assigns a pointer to a 1D array (ie. int(*)[3]) to a pointer to int, also a type mismatch. Only *p = &a[0] will do what you want, which is assign a pointer to int to another pointer to int.

So p[4] is same as *(p+4) ?

Yes.

Member Avatar for Rahul47

Is there any place I can read more about this type mismatch. I just started learning pointers and these things are getting a little Out Of Bound.

Member Avatar for Rahul47

It looks like as if p is hidden array of pointers and it is declared by default as p is assigned address of an array. Is it so ?

Is there any place I can read more about this type mismatch.

Click Me.

It looks like as if p is hidden array of pointers and it is declared by default as p is assigned address of an array. Is it so ?

I'm having difficulty deciphering that question, can you rephrase it for me?

Member Avatar for Rahul47

I'm having difficulty deciphering that question, can you rephrase it for me?

What I meant to say is 'p' is declared as Pointer Variable and not Array of Pointers, so as to point to multiple variables.

this is not work
you must do that
a = p;
and
printf("%d",p[i][i]);

Member Avatar for Rahul47

this is not work

It works fine my friend.

What I meant to say is 'p' is declared as Pointer Variable and not Array of Pointers, so as to point to multiple variables.

A pointer is just a pointer. It points to a single entity of the declared type, but using pointer arithmetic can traverse over multiple entities if they exist. Is that what you're asking?

It works fine my friend.

"Works" and "correct" are two different things. Just because something works doesn't mean it'll always work. Predictable, portable behavior is the key for correctness.

Member Avatar for Rahul47

Is that what you're asking?

Here is what I meant. Consider the following program.

#include<stdio.h>
int main(){
    int *p[6];
    int i,a[2][3]={{8,9,10},{11,12,13}};
    p[0]=&a;
    printf("%d",p[0]);      // Printing the base value.
    printf("\n%d",p[4]);    // It no longer prints *(p+4) i.e 11, rather                                   // it prints the address of 11.
    getch();
    return 0;
}

Your code is still broken. A correct variation would be:

int a[2][3] = {{8, 9, 10}, {11, 12, 13};
int *p = a;

printf("%p\n", p[1]); // Prints the address of a[1]
printf("%d\n", *(p[1] + 1)); // Prints 12

p in this case points to the first row of a. It can be indexed to get to subsequent rows or using pointer arithmetic.

Member Avatar for Rahul47

Let us consider two cases.
1)

int main(){
    int a[3]={10,11,14}, *p=a;
    printf("\n%d", p[1]);   // It prints 11 as p[1] means *(p+1)
    getch();
    return 0;
}

In above there's only one pointer i.e p

Now,
2)

int main(){
    int a[3]={10,11,14}, *p[3], i;
    p[0]=a;
    printf("\n%d", p[1]);   // In this some garbage is printed.
    getch();
    return 0;
}

In this we have declared array of pointer i.e *p[3].

Now I understood why garbage is printed in 2nd case.
What I am trying to say is when we dont declare pointer as an array(as in 1st), usage of a[1] is equivalent to p[1]. There is no distinction between an array and a pointer this (1st) case.

Thats why I said

It looks like as if p is hidden array of pointers.

Feel free to criticize my views. . . am just a newbie in it. :-)

There is no distinction between an array and a pointer this (1st) case.

Yes, that's close enough.

It looks like as if p is hidden array of pointers.

No, it's just a pointer. Since it points to the address of an item in an array, you can treat that pointer like an array to get other items. The concept here is that pointers give you largely unrestricted access to memory. If a char pointer (call it p) points to address 12345, you can use *(p + 1) to get the value at address 12346. Because array indexing is just syntactic sugar for pointer arithmetic, that means you can also say p[1] for the same effect.

Member Avatar for Rahul47

That solved my queries. Thanx folks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.