c language - structure 1

struct declaration

Basic knowledge of structs

A struct is a custom type that consists of several primitive types. Each member of a structure can be a variable of a different type.

declaration of structure

struct tag    //type declaration
{
member-list;   //structure member variable
}variable-list;  //Created struct variable

For example to describe a person:

struct person
{
	int id[20];    //identification number
	char name[10];//Name
	char sex[5];//gender
};

special statement

When declaring a structure, you can declare it incompletely.

struct
{
	int a;
	char c;
}n;
//anonymous struct type
struct
{
	int a;
	char c;
}*p;

The names of the above two structures are omitted, and the structure members are the same. Are they equal?

struct
{
	int a;
	char c;
}n;
struct
{
	int a;
	char c;
}*p;
int main()
{
	p = &n;
	return 0;
}


Obviously the compiler will treat the above two declarations as two completely different types

Definition and initialization of structure variables

struct  book        //type declaration
{
	char name[20];  
	int price;

}a1;  // Declare the variable a1 while declaring the type
struct book a2;  //Define the structure variable a2
struct book a3 = { "sword finger offer",99 };  //Initialization: Assign an initial value while defining a variable.
struct person
{
	char name[20];
	int age;
	struct book a4;
}b1 = { "Zhang San",85,{"0 basic learning C language",66}};  //Structure nested initialization
struct person b2 = { "Li Si",48,{"How Coca-Cola is Made",28} }; //Structure nested initialization

Self-referencing of structs

Self-referencing means referencing itself, so can a member of the structure be referenced in a structure?

struct person
{
	char name[20];
	int age;
	struct person a1;
};
int main()
{
	printf("%zd", sizeof(struct person));
	return 0;
}


Obviously the size of person cannot be calculated.
How to use it correctly?
We have learned about pointers before, its size is fixed 4/8 bytes, then we can try pointers

struct person
{
	char name[20];
	int age;
	struct person *next;
};
int main()
{
	printf("%zd\n", sizeof(struct person));
	

	return 0;
}


The size can then be calculated.
Another point to note is that the structure referenced when using typedef to customize the type name cannot omit struct, for example:

typedef struct person
{
	char name[20];
	int age;
	struct person* next;    //This struct cannot be omitted
}person;

If omitted, an error will be reported.

Structure memory alignment

Calculate the size of the following structure

struct a
{
	char a;       
	char b;       
	int c;        
};
struct b
{
	char i;
	int n;
	char p;
};
struct c
{
	char c1;
	struct b b1;                //structure nesting problem
	double d;
};
int main()
{
	printf("%zd\n", sizeof(struct a));
	printf("%zd\n", sizeof(struct b));
	printf("%zd\n", sizeof(struct c));
	return 0;
}

The first two structures have the same number of structure member variables, but they occupy different memory sizes, which involves a particularly popular test point: structure memory alignment.
How to calculate?
First, you must master the alignment rules of the structure:
1. The first member is at the address at offset 0 from the structure variable.
2. Other member variables should be aligned to an address that is an integer multiple of a number (alignment number).
Alignment = the lesser of the compiler's default alignment and the size of the member.
The default value in VS is 8
3. The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).
4. If a structure is nested, the nested structure is aligned to an integer multiple of its own maximum alignment number, and the overall size of the structure is an integer of all maximum alignment numbers (including the alignment number of nested structures). times.
E.g:

struct b
{
	char i;    
	int n;
	char p;
	double c;
};
int main()
{
	printf("%zd", sizeof(struct b));
	return 0;
}


Therefore, the size of the memory space occupied by this structure is 24 bytes.
The gray part is wasted space.

  • Why does memory alignment exist?
  1. Platform reasons (porting reasons):
    Not all hardware platforms can access any data at any address; some hardware platforms can only fetch certain types of data at certain addresses, otherwise a hardware exception will be thrown.
  2. Performance reasons:
    Data structures (especially stacks) should be aligned on natural boundaries as much as possible.
    The reason is that in order to access unaligned memory, the processor needs to make two memory accesses; aligned memory accesses require only one access.
    Summary: trade memory space for time.

Modify the default alignment

Earlier we said that the default value in VS is 8, which can actually be modified.

  • The #pragma preprocessing directive can modify our default alignment.
    E.g:
#pragma pack(1) //Set the default alignment number to 1
struct b
{
	char i;    
	int n;
	char p;
	double c;
};

#pragma pack() //Unset the default alignment number, restore to the default
struct c
{
	char i;
	int n;
	char p;
	double c;
};
int main()
{
	printf("%zd\n", sizeof(struct b));      //14
	printf("%zd\n", sizeof(struct c));      //24
	return 0;
}

Summary: When the alignment of the structure is not suitable, we can change the default alignment by ourselves.

structure parameter

struct person
{
	char name[15];
	int age;
	char sex[5];
};
void print1(struct person a1)      //pass by value
{
	printf("%s %d %s\n", a1.name, a1.age, a1.sex);
}
void print2(struct person* a2)   //pass address
{
	printf("%s %d %s", a2->name, a2->age, a2->sex);
}
 int main()
{
	struct person a = { "Mahathir",55,"male"};
	print1(a);//transfer structure
	print2(&a);//pass structure address
}

Pass-by-value and pass-by-address, preferably pass-by-address.
The formal parameter is a temporary copy of the actual parameter, so when the content to be passed is very large, it will waste a lot of space and cause performance degradation, but passing the address will solve the problem very well!
in conclusion:
When passing parameters to a structure, you need to pass the address of the structure.

Tags: Algorithm C

Posted by CooKies37 on Wed, 05 Oct 2022 11:46:22 +1030