#include <stdio.h>
struct dog
{
int name[10];
char breed[10];
int age;
char color[10];
};
int main()
{
struct dog frodo;
struct dog **ptr=&frodo.name;
for(int i=0;i<10;i++)
frodo.name[i]=i;
for(int i=0;i<10;i++)
printf(" frodo.name[%d]%d\n",i,frodo.name[i]);
for(int i=0;i<10;i++)
printf(" ptr =%d\n",ptr[i]);
}
I tried using double pointer but the index is not matching when value is being printed.
O/P: frodo.name[0]0 frodo.name[1]1
ptr =0 ptr =2
Your question indicates that you are new to C and still learning fundamentals, so in order to help you I'll go through your code and explain what it does, and then provide that code fixed to do what I think you are trying to do. I will try to be precise and thorough at the risk of sounding pedantic.
Consider this declaration:
int name[10];
This defines name
as a field in struct dog
which declares name to be the
type of "an array of 10 int
s". Note that an array can be assigned to a
pointer to its "inner" type (int
), in which assignment it is said to "decay"
into a "pointer to int
". So int * pint = name;
is valid code which show
this facility in C. None-the-less, the type of name
is "array of 10 int
s".
This if you take it's address (&name
) you don't get a "pointer to int
; you
get a "pointer to an array of 10 int
s".
#include <stdio.h>
struct dog
{
int name[10];
char breed[10];
int age;
char color[10];
};
So you declare a new "aggregate type", struct dog
, whose objects will contain
a field called name
whose type is an "array of 10 int
s", followed by a field
called breed
whose type is an "array of 10 char
s", followed by a field age
whose type is int
, then a field color
with type "array of 10 char
s".
int main()
{
struct dog frodo;
Define an object frodo
of type struct dog
, which then contains all of the
fields of a struct dog. It is allocated memory on the stack, which will be
cleaned up and removed when main
returns.
struct dog **ptr=&frodo.name;
Here is the first sign of misunderstanding. If you were to declare a variable
ptr_to_dog
like this: struct dog * ptr_to_dog
, you would declare it as a
pointer ("address of") an object whose type is struct dog
, or "pointer to
struct dog
", for short. frodo
is such an object, so setting pointer to this
address of frodo
is valid: ptr_to_dog = &frodo;
. &frodo
is an expression
which takes the address of the frodo
object, so the type of this expression
"pointer to struct dog
", which matches the type of ptr_to_dog
, so the
assignment is correct.
Your declaration struct dog **ptr
creates an object ptr
whose type is
"pointer to a pointer to a struct dog
. If you take the address of
ptr_to_dog
, you get an expression whose type is "pointer to a pointer to
struct dog
. This is the same type as the ptr
you declared, so if you were
to make the assignment ptr = &ptr_to_dog
, that is valid.
Now let's look at the right side of the assignment, &frodo.name
. Note that
.
is said to "bind tighter" than the &
, so this is the same as
&(frodo.name)
. The expression frodo.name
gets the value of the field name
in the foo
object, which is of type struct dog
. So the expression
&frodo.name
gives a pointer to that field, so its type is "pointer to the
field name
in the frodo
object. The type of name
is "array of 10 int
s",
so &frodo.name
is "pointer to an array of 10 int
s". So the declaration you
gave could be described as "get the pointer to the array of 10 int
s name
and
assign it to the "pointer to the pointer to the struct dog
foo
" ptr
. The
types are not compatible. However, all pointers can be reduced to a kind of
unnamed type "pointer to memory", so the compiler can convert the "pointer to 10
int
s" &frodo.name
to the "pointer to the pointer to frodo
" ptr
. This is
almost never usefull, so most compiler will emit a warning about this.
Now you could do this struct dog * ptr_to_dog = &frodo
, which assigns the address of
frodo
to the "pointer to a struct dog
" ptr_to_dog
, so here the types match and
the assignment is proper. Note that a "pointer to struct dog
" does not mean
"pointer to a single struct dog
"; so pointer could point to memory that hold
an indefinite series of struct dog
s in succession, ie an array. So you can do
ptr_to_dog[3]
, which means "get the fourth struct dog
from the series of
struct dog
s beginning at the address ptr_to_dog
. If ptr_to_dog
contains
only one struct dog
, what you get from that will be meaningless, but it is a
valid expression.
for(int i=0;i<10;i++)
frodo.name[i]=i;
for(int i=0;i<10;i++)
printf(" frodo.name[%d]%d\n",i,frodo.name[i]);
for(int i=0;i<10;i++)
printf(" ptr =%d\n",ptr[i]);
}
Remember that the type of ptr
is "pointer to a pointer to a struct dog
, but
given your assignment, ptr
does not point to a pointer to a struct dog
; it
points to an "array of 10 int
s" in the field name
of the struct dog
object frodo
. So the value of ptr
here is meaningless; its value is some
section of the memory of the name
array interpreted as a "pointer to a pointer
to struct dog
". From this I take it that you wanted ptr
to point to the
"array of 10 int
s" called name
in the struct dog
object frodo
. To get
this, the declaration should have been
int * ptr = frodo.name;
Remember that an array type (name
) can be assigned to a pointer to its inner
type (int
), in which the array expression (frodo.name
) will "decay" into
that type of pointer. This this says "get the array of 10 int
s name
inside
the struct dog
frodo
, decay it to a pointer to the beginning of the series
of int
s in name
and assign that pointer to the pointer to int
s called
ptr
". A proper assignment.
Note that @tstanisl's answer is wrong in one place; it declares ptr
to be a
"pointer to char
". But frodo.name
consists of int
s not char
s, so his
assignment is invalid. The expression &frodo.name[0]
says "get the first
int
in the array of 10 int
s frodo.name
and take its address, yielding a
"pointer to the first int
in frodo.name
". But the address of the first
int
here is also the address of the series of int
s in frodo.name
. So
the address &frodo.name
and frodo.name
when it is "decayed" to a
pointer-to-int
have the same value and type.
Here is your code, fixed with the above in mind:
#include <stdio.h>
struct dog
{
int name[10];
char breed[10];
int age;
char color[10];
};
int main()
{
struct dog frodo;
int *ptr= frodo.name;
for(int i=0;i<10;i++)
frodo.name[i]=i;
for(int i=0;i<10;i++)
printf(" frodo.name[%d]%d\n",i,frodo.name[i]);
for(int i=0;i<10;i++)
printf(" ptr =%d\n",ptr[i]);
}