Reading notes of C language programming (Chapter 11 - structure and common body)

Posted by silvercover on Tue, 22 Feb 2022 14:26:25 +0100

11.1 structure

11.1.1 general

Sometimes different types of data need to be combined into an organic whole for easy reference, so a structure appears. Similar to classes in high-level languages such as Java. For example, a student has attributes such as student number / name / gender / age / address:

int num;
char name[20];
char sex;
int age;
char addr[30];

The syntax for defining a structure is as follows:

struct Structure name {
    Member table column
};

The member table column consists of several members, and each member is an integral part of the structure. Each member must also have a type description in the form of:

Type specifier member name;

The naming of member names shall comply with the writing provisions of identifiers. For example:

struct student {
    int num;
    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
}

After learning the structure of Java classes, you can find the similarities between the structure of Java classes. In fact, some of them are not good after learning the structure of Java classes. For example:

class Student {
    int num;
    String name;
    String sex;
    int age;
    float score;
    String addr;
}

11.1.2 method of defining structure type variables

There are three ways to declare structure variables:

  • The first method: declare the structure type first, and then define the variable name.
// Declare structure type
struct Structure name {
    Member table column
};
// Define variable name
struct Structure name variable name,Variable name,...

example:

// Declare structure type
struct student {
     int num;
     char name[20];
     char sex;
     int age;
     float score;
     char addr[30];
 };
// Define variables
struct student stu1,stu2;

After the structure variable is defined, the system will allocate memory units for it. stu1 and stu2 occupy (4 + 20 + 1 + 4 + 4 + 30 = 67) bytes in memory respectively.

  • The second method is to declare the structure type and define variables at the same time.
struct Structure name {
    Member table column
} Variable name table column;

example:

// Declare the structure type and define variables at the same time
struct student {
     int num;
     char name[20];
     char sex;
     int age;
     float score;
     char addr[30];
 } stu1,stu2;
  • The third method: directly define the structure type variable, that is, there is no structure name.
struct {
    Member table column
} Variable name table column;

example:

// Structure name does not appear
struct {
     int num;
     char name[20];
     char sex;
     int age;
     float score;
     char addr[30];
 } stu1,stu2;

The list member can be a structure. For example, the structure definition is given according to the following figure:

struct date
{
	int year;
	int month;
	int day;
};

struct student
{
	int num;
	char name[20];
	char sex;
	struct date birthday;
	float score;
} stu1;

If you want to access members in a structure, the basic syntax is as follows:

Structure variable name.member name;

If the member itself belongs to a structure type, you need to use several member operators to find the lowest level member level by level. Only the lowest level members can be assigned or accessed and operated. For example:

stu1.num; // Access num
stu1.birthday.month; // Visit month in birthday

Members of structural variables can perform various operations like ordinary variables. For example:

stu2.score=stu1.score;
sum=stu1.score+stu2.score;
stu1.age++;
++stu2.age;

You can refer to the address of the structural variable member or the address of the structural variable. However, structural variables cannot be read as a whole with the following statements:

scanf("%d, %d, %c, %d, %f, %s", &student1);

The address of the structure variable is mainly used as a function parameter, and the address of the structure variable is passed.

11.1.3 initialization of structure variables

The syntax of initialization is as follows:

// Declare structure type
struct Structure name{
    Member table column
};
// Define and initialize structure variables
struct Structure name variable name = {...};

// Note that the following syntax is incorrect
struct Structure name variable name;
Variable name = {...};

Structure variables can be initialized directly, for example:

#include <stdio.h>

struct student
{
	int num;
	char *name;
	char sex;
	float score;
} student1,student2={102, "Zhang San", 'M', 99.5};

int main()
{
	student1=student2;
	
	printf("No.:%d\n full name:%s\n Gender:%c\n fraction;%1.1f\n", student1.num, student1.name, student1.sex, student1.score);
	printf("\n");
	printf("No.:%d\n full name:%s\n Gender:%c\n fraction;%1.1f\n", student2.num, student2.name, student2.sex, student2.score);
} 

11.1.4 structure array

11.1.4.1 general

A structural variable can store a set of data (such as a student's student number, name, grade and other information).

If the data of 50 students need to participate in the operation, they should use the array to store it. This is the structure array.

Each element in the structure array is a variable of structure type.

11.1.4.2 define structure array

Similar to the method of defining structure variables, you only need to specify that they are arrays. The syntax is as follows:

// Declare structure type
struct Structure name {
    Member table column
};
// Define structure array
struct Structure name array name[Array length];

For example:

struct student {
    int num;
    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
};
struct student stu1[10];// Represents a structure array with 10 elements

11.1.4.3 initialization of structure array

The general syntax of structure array initialization is as follows:

// Declare structure type
struct Structure name {
    Member table column
};
// Define structure array
struct Structure name array name[Array length] = {{...}, {...}, {...}};

That is, first declare the structure type, then define the array as the structure type, and initialize when defining the array. For example:

struct student {
    int num;
    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
};
struct student stu[2] = {
    {121, "Zhang San", 'm', 18, 56.5, "Beijing"},
    {122, "Li Si", 'f', 20, 68, "Shanghai"}
};

11.1.5 description and use of structure pointer variables

11.1.5.1 pointer to structure type data

11.1.5.1.1 declaration of structure pointer variable

A pointer variable is called a structure pointer variable when it is used to point to a structure variable. The value in the structure pointer variable is the first address of the structure variable pointed to. The structure variable can be accessed through the structure pointer, which is the same as that of array pointer and function pointer. The general form of structure pointer variable description is:

struct Structure name *Structure pointer variable name;

For example:

// Declare structure type
struct student {
    int num;
    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
};
// Define structure pointer variables
struct student *stu;
11.1.5.1.2 assignment of structure pointer variable

Structure pointer variables must be assigned before they can be used.

Note: assignment is to assign the first address of the structure variable to the pointer variable, and the structure name cannot be assigned to the pointer variable.

// Declare structure type
struct student {
    int num;
    char name[20];
    char sex;
    int age;
    float score;
    char addr[30];
};
// Define structure variables
struct student stu1,stu2;
// Define structure pointer variables
struct student* stu;
// Assign value
stu = &stu1;// This is true because stu1 is a struct variable
stu = &student;// This is wrong because student is the structure name

Structure name and structure variable are two different concepts. Structure name only represents one structure form, and the compiling system does not allocate memory space to it.

Only when a structure variable is described as a structure of this type, the storage space is allocated to the variable.

Structure pointer variable, which can more conveniently access each member of structure variable.

11.1.5.1.3 access to structure pointer variables

The general form of access is:

(*Structure pointer variable name).member name;

// perhaps

Structure pointer variable->member name;

For example:

(*stu).num;

// perhaps

stu->num;

example:

#include <stdio.h>

struct student {
    int num;
    char *name;
    char sex;
    float score;
} student1 = {101, "Zhang San", 'M', 55.4};

int main() {
    // Declaration of structure pointer variables
    struct student* stu;
    // Assignment of structure pointer variables
    stu = &student1;
    // Access to structure pointer variables
    printf("%d %s %c %1.1f\n", (*stu).num, (*stu).name, (*stu).sex, (*stu).score);// 101 sheets III M 55.4
    printf("%d %s %c %1.1f\n", stu->num, stu->name, stu->sex, stu->score);// 101 sheets III M 55.4
}

11.1.5.2 structure pointer variable as function parameter

You can transfer the value of a structure variable to a function in the following three ways:

  • Using members of structural variables as parameters
  • Using structural variables as arguments
  • Use the pointer pointing to the structure variable (or array) as the argument to pass the address of the structure variable (or array) to the formal parameter

Example, using structure variables as function parameters:

#include <stdio.h>

// Declare structure type
struct student {
    int num;
    char *name;
    char sex;
    float score;
};

// Structure variables as function parameters
void print(struct student stu) {
    printf("num=%d\tname=%s\tsex=%c\tscore=%f", stu.num, stu.name, stu.sex, stu.score);
}

int main() {
    // Define and assign structural variables
    struct student stu = {121, "Zhang San", 'm', 85.5};
    // Pass structure variables into the function as arguments
    print(stu);// num=121 name = Zhang San sex = m score = 85.500000
}

Instance, using structure pointer variable as function parameter:

#include <stdio.h>

// Declare structure type
struct student {
    int num;
    char *name;
    char sex;
    float score;
};

// Structure pointer variable as function parameter
void print(struct student* stu) {
    // You can use (* stu) Name can also be accessed through stu - > name
    printf("num=%d\tname=%s\tsex=%c\tscore=%f", (*stu).num, (*stu).name, stu->sex, stu->score);
}

int main() {
    // Define and assign structural variables
    struct student stu = {121, "Zhang San", 'm', 85.5};
    // Pass structure variables into the function as arguments
    print(&stu);// num=121 name = Zhang San sex = m score = 85.500000
}

11.1.6 dynamic storage allocation

11.1.6.1 general

Because the length of the array must be defined first, it is fixed in the whole program. Dynamic array types are not allowed in C language.

For example, note: int a[n]; The length is expressed by variables. It is impossible to dynamically explain the size of the array.

In practice, the required memory space often depends on the data actually entered by the user, but the actual size is not clear and cannot be known in advance.

Therefore, C language provides some memory management functions to dynamically allocate memory space, or recycle unnecessary memory space to effectively manage memory resources. It also lays the foundation for the following linked list and other data structures.

There are three common memory management functions:

  • Allocate memory space functions malloc and calloc, where malloc is used more.
  • The free function to free memory space is also commonly used.

Before using the above three functions, you need to introduce

#include <stdlib.h>

11.1.6.2 malloc function

The function prototype is void *malloc(unsigned int size);, The calling syntax is as follows:

(type specifier *)malloc(size);
  • The type specifier indicates which data type the region is used for.
  • (type specifier *) means to cast the return value to a pointer of this type.
  • "size" is an unsigned number.

The function of this method is to allocate a continuous area with a length of "size" bytes in the dynamic storage area of memory. The return value of the function is the first address of the region. For example:

// Indicates that 100 bytes of memory space is allocated and forcibly converted to the type of character array. The return value of the function is the pointer to the character array, and the pointer is given to the pointer variable pc
char* pc = (char*)malloc(100);

11.1.6.3 calloc function

The function prototype is void *calloc(unsigned n, unsigned size);, The calling syntax is as follows:

(type specifier *)calloc(n, size);
  • (type specifier *) is used to cast types.
  • The difference between calloc function and malloc function is that n blocks can be allocated at one time.

The function of this method is to allocate n consecutive areas with a length of "size" bytes in the memory dynamic storage area. The return value of the function is the first address of the region. For example:

// sizeof(struct stu) is to find the structure length of stu. Therefore, the meaning of this statement is: allocate two continuous areas according to the length of stu, forcibly convert them to stu type, and assign their first address to the pointer variable ps.
struct stu* ps = (struct stu*)calloc(2, sizeof(struct stu));

11.1.6.4 free function

The function prototype is void free(void *p);, The calling syntax is as follows:

free(void* ptr);

The function of this method is to release a memory space pointed by ptr. ptr is an arbitrary type of pointer variable, which points to the first address of the released area. The released area should be the area allocated by malloc or calloc function.

11.1.7 defining types with typedef

11.1.7.1 basic use

11.1.7.1.1 for basic types

typedef keyword is used to declare a new type name to replace the existing type name. The syntax is as follows:

typedef Old type name new type name;

For example:

typedef int INTEGER;
// Where int is the existing type and INTEGER is the new type name
// INTEGER is declared

example:

#include <stdio.h>
#include <stdlib.h>

typedef int INTEGER;

int main() 
{
	INTEGER i=1;
	int j=2;
	
	printf("%d %d\n", i, j);
} 
11.1.7.1.2 type of structure

The basic syntax is as follows:

typedef struct [Structure name] {
    Member table column
} Structure variable name;// The structure name can be omitted

For example:

#include <stdio.h>

// Declare structure type
typedef struct date {
    int year;
    int month;
    int day;
} DATE;

int main() {
    // Previous usage:
    // struct date DATE;
    // Current usage:
    DATE d;
    d.year = 2021;
    d.month = 12;
    d.day = 25;

    printf("%d-%d-%d\n", d.year, d.month, d.day);// 2021-12-25
}
11.1.7.1.3 for array types

The basic syntax is as follows:

typedef Type specifier array name[Array length];

For example:

#include <stdio.h>
#include <stdlib.h>

typedef int NUM[100];

int main() {
    NUM num = {0};
    printf("%d\n\n", sizeof(num));
    return 0;
} 
11.1.7.1.4 pointer type for characters

The basic syntax is as follows:

typedef char* name;

For example:

#include <stdio.h>

typedef char* String;

int main() {
    String str = "Hello World!";
    printf("%s", str);// Hello World!
}
11.1.7.1.5 pointer type used to point to function

The basic syntax is as follows:

typedef return type (*Function name)();

For example:

#include <stdio.h>

// Declare the type of pointer to the function
typedef int (*fun)(int, int);

int max(int x, int y) {
    return x > y ? x : y;
}

int main() {
    // Assign the real function name
    fun f = max;
    // Call the function to get the return value result
    int result = f(1, 2);
    printf("%d", result);
}

11.1.7.2 steps to define types with typedef

Steps:

  • First write out the definition body according to the method of defining variables (such as int i)
  • Change the variable name to the new type name (e.g. change i to COUNT)
  • Add typedef at the front (e.g. typedef int COUNT)
  • Then you can define constants with new type names (e.g. count, I, J;)

For example:

#include <stdio.h>


// int i;
// int COUNT;
typedef int COUNT;

int main() {
    COUNT num = 123;
    printf("%d", num);// 123
}

11.1.7.3 some notes on typedef

Typedef can be used to declare various type names, but it cannot be used to define variables, such as typedef i;, This is wrong.

Using typedef just adds a type name to an existing type without creating a new type.

When different source files use the same type of data, typedef is often used to declare some data types, put them separately in a file, and then use the #include command to include them in the files that need them.

The use of typedef is conducive to the universality and transplantation of the program.

Typedef is similar to #define, for example: typedef int COUNT# The function of define COUNT int is to use COUNT to represent int. However, they are different.

#Define is processed during precompiling. It can only be used for simple string replacement, while typedef is processed at compile time. In fact, instead of using a string to define a variable, it uses a simple method to replace it.

About the difference between typedef and #define:

typedef (int*) p1;

// and

#define p2 int*

//Note that one has a semicolon and the other has no semicolon

Topics: C Back-end