简体   繁体   中英

How to Access a array in the structure after assigning the structure variable to a pointer without arrow operator

#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

I expect that ptr should be a pointer to the first element of frodo.name which is array of 10 int s. Therefore the type of ptr should be int* . Use:

int *ptr=&frodo.name[0];

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]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM