简体   繁体   中英

C language struct accessing elements

#include <stdio.h>
struct Ournode {
  char x, y, z;
};

int main() {
  struct Ournode p = {'1', '0', 'a' + 2};
  struct Ournode *q = &p;
  printf("%c, %c", *((char *)q + 1), *((char *)q + 2));
  return 0;
}

I came across this question on geeksforgeeks( https://www.geeksforgeeks.org/c-language-2-gq/input-and-output-gq/ ) (question 21). How is *q accessing the elements of p? what if we had struct like

struct Ournode {
  int a,b,c;
  char x, y, z;
  int d;
};
int main() {
  struct Ournode p = {3,4,5,'1', '0', 'a' + 2,6};
  struct Ournode *q = &p;
  printf("%c, %c", *((char *)q + 1), *((char *)q + 2));
  printf("%d, %d\n", *((int *)q + 1), *((int *)q +2 ));
  return 0;
}

In this case how can we access the elements?I get garbage output sometimes depending upon the order in which i create Ournode (ie a,b,c first then x,y,z or x,y,z first then a,b,c).

what is happening behind the scenes here? how is q accessing the elements?

How is *q accessing the elements of p ?

It does so through a char pointer, using a rule that the address of the struct must match the address of its initial element (ie field px ). However, the standard allows the compiler to insert padding after x , so adding 1 to ((char*)q) may not necessarily yield the address of y .

You can fix your program as follows:

printf(
    "%c, %c"
,   *((char *)q + offsetof(struct Ournode, y))
,   *((char *)q + offsetof(struct Ournode, z))
);

Since ((char*)q) points to part of int field a , printing %c from these addresses yields implementation-defined re-interpretations of parts of int 's representation as char . As far as printing int s is concerned, you should add the same offsetof trick to counter the results of potential padding.

Note: I am yet to see a compiler that inserts padding between char s, but I didn't find anything in the standard preventing it from doing so. The situation would be different if instead of char x, y, z you used char x[3] , because padding between array members is not allowed.

how is q accessing the elements?

This has been already answered, so I want to answer this other question of yours.

In this case how can we access the elements? I get garbage output sometimes depending upon the order in which i create Ournode (ie a,b,c first then x,y,z or x,y,z first then a,b,c).

If you want to access the members of struct Ournode through a pointer q to that node, there is an operator -> that makes this possible. Your code will now look like this.

int main() {
  struct Ournode p = {3,4,5,'1', '0', 'a' + 2,6};
  struct Ournode *q = &p;
  printf("%d, %d, %d, %c, %c, %c, %d", , q->a, q->b, q->c, q->x, q->y, q->z, q->d );
  return 0;
}

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