Detail the self referencing and cross referencing of structures in C

  • 2020-05-10 18:30:41
  • OfStack

A self-reference to a structure (self reference) contains a pointer to a structure of its own type inside the structure.
The mutual reference of structs (mutual reference), that is, in multiple structs, contains Pointers to other structs.
1. Self-referential structure
1.1 when typedef is not used
The wrong way:


struct tag_1{ 
  struct tag_1 A;  /*  The structure of the body  */ 
  int value; 
}; 

              this declaration is wrong, because this declaration is actually an infinite loop, the member b is a structure, the member b will have inside the member b is a structure, and so on, the wireless loop. When allocating memory, this is illegal because the length of the structure cannot be determined due to infinite nesting.
Correct way: (using pointer) :


struct tag_1{ 
  struct tag_1 *A; /*  Pointer to the  */ 
  int value; 
}; 

              because the length of the pointer is specified (4 on a 32-bit machine), the compiler is able to determine the length of the structure.
1.2 when using typedef
The wrong way:


typedef struct { 
  int value; 
  NODE *link; /*  Although Pointers are also used, the problem here is: NODE Not yet defined  */ 
} NODE; 

The purpose here is to create a single name NODEP for the structure using typedef. This is an error, however, because the scope of the type name begins at the end of the statement and cannot be used inside the structure because it is not defined.
The right approach: there are three, not too different, and you can use either one.


/*  methods 1 */ 
typedef struct tag_1{ 
  int value; 
  struct tag_1 *link;  
} NODE; 
 
 
/*  methods 2 */ 
struct tag_2; 
typedef struct tag_2 NODE; 
struct tag_2{ 
  int value; 
  NODE *link;   
}; 
 
 
/*  methods 3 */ 
struct tag_3{ 
  int value; 
  struct tag *link;  
}; 
typedef struct tag_3 NODE; 

2. Cross-reference structures
The wrong way:


typedef struct tag_a{ 
  int value; 
  B *bp; /*  type B It's not defined yet  */ 
} A; 
 
typedef struct tag_b{ 
  int value; 
  A *ap; 
} B; 

 
The reason for the               error is the same as the one above, where the type B is used before it is defined.
The right way :(use "incomplete declaration")


/*  methods 1  */  
struct tag_a{ 
  struct tag_b *bp; /*  Here, struct tag_b  It's not defined yet, but the compiler accepts it  */ 
  int value; 
}; 
struct tag_b{ 
  struct tag_a *ap; 
  int value; 
}; 
typedef struct tag_a A; 
typedef struct tag_b B;  
 
 
/*  methods 2  */  
struct tag_a;  /*  Using an incomplete declaration of a struct ( incomplete declaration )  */ 
struct tag_b; 
typedef struct tag_a A;  
typedef struct tag_b B; 
struct tag_a{ 
  struct tag_b *bp; /*  Here, struct tag_b  It's not defined yet, but the compiler accepts it  */ 
  int value; 
}; 
struct tag_b{ 
  struct tag_a *ap; 
  int value; 
}; 

3. Example:
Applies a struct pointer variable to print information about a struct member variable.


#include <stdio.h>
struct Point
{
double x; /*x coordinates */
double y; /*y coordinates */
double z; /*z coordinates */
};
int main()
{
struct Point oPoint1={100 . 100 . 0};
struct Point oPoint2;
struct Point *pPoint; /* Defines struct pointer variables */
pPoint=& oPoint2;   /* Struct pointer variable assignment */
(*pPoint).x= oPoint1.x;
(*pPoint).y= oPoint1.y;
(*pPoint).z= oPoint1.z;
printf("oPoint2={%7.2f . %7.2f . %7.2f}" . oPoint2.x .  oPoint2.y .  oPoint2.z);
return(0);
}

The results of the program are as follows:


oPoint2={ 100.00 . 100.00 . 0.00}

Where the function of the expression &oPoint2 is to obtain the address of the structure variable oPoint2. The effect of the expression pPoint=&oPoint2 is to store the address of oPoint2 in the struct pointer variable pPoint, so pPoint stores the address of oPoint2. *pPoint represents the contents of the pointer variable pPoint, so *pPoint is equivalent to oPoint2.
The 1 form of the member variable of the struct variable obtained through the struct pointer variable is as follows:
(* struct pointer variables). Member variables
Where, "struct pointer variable" is the struct pointer variable, "member variable" is the name of the struct member variable, and ". "is the operator to take the struct member variable.
In addition, a new operator "-" has been introduced into the C language > ", the member variables of the struct variables can be directly obtained through the struct pointer variables. The form of 1 is as follows:
Struct pointer variable - > Member variables
Where "struct pointer variable" is the struct pointer variable, and "member variable" is the name of the struct member variable, "-" > "Is the operator.
Therefore, part of the code in the example


 ... 
(*pPoint).x= oPoint1.x;
(*pPoint).y= oPoint1.y;
(*pPoint).z= oPoint1.z;
 ... 

Is equivalent to


 ... 
pPoint->x= oPoint1.x;
pPoint->y= oPoint1.y;
pPoint->z= oPoint1.z;
 ... 


Related articles: