2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
The data types we have seen before, such as int, float, char, etc., are simply used in the program. If we want to create some complex data according to our needs, we need to use structures.
For example, a student's student ID, name, gender, age, etc. belong to the same student, but these variables are of different types. If we simply define them using different variables, it is difficult to reflect the internal connection between them. So we create a variable that can combine these data and put them in the variable, which makes it much easier to use. This is what leads to the study of structures;
- 结构体类型:
- struct Student
- {
- int num;//学号为整形;
- char name[20];//姓名为字符串;
- char sex;//性别为字符型;
- int age;//年龄为整形
- float score;//成绩为浮点型
- char addr[30];//地址为字符型;
- }
in:
struct Student is a structure type;
Struct is a keyword that declares a structure type.
Student is the name of the structure, in order to distinguish it from other structures;
The curly braces contain the members of the structure, which are grouped together and are called a member list. Their naming is consistent with that of variables.
Note: There can be multiple structure types; for example: struct Student; struct Teacher; struct Worker;
A structure's members can also be of the type of another structure;
struct Date
{
int month;
int day;
int year;
};
struct Student
{
int num;
char name[20];
char sex;
int age;
struct Date birthday;
char addr[30];
}
Previously, we only defined a structure type, which is equivalent to a model, and did not define variables. Now we define structure variables and store specific data in them in three ways;
Method 1: Declare the structure type first, then define the structure variable
Based on the previous structure type struct Student, define structure variables;
struct Student student1,student2;
This method is similar to int a, b; the only difference is that the premise is that there is already a structure type, and the structure variable is defined based on the type.
Method 2: Declare the variable while declaring the type
form:
struct structure name
{
Member list;
} variable name list;
Example:
struct Student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student1,student2;
Method 3: Define a structure type variable directly without specifying a type name
form:
struct
{
Member variables;
} variable name list;
It is an unnamed structure type and is not often used;
Note: 1. The member name in the structure variable can be the same as the variable name in the program;
2. The members of the structure variable can be used individually; their status and function are equivalent to ordinary variables;
Initialize the structure variable when defining it;
Example:Put a student's information (including student number, name, gender, and address) in a structure variable, and then output the student's information;
- #include <stdio.h>
-
- int main()
- {
- struct Student
- {
- int num;
- char name[20];
- char sex;
- char addr[20];
- }student1 = {101,"Li li",'M',"123XiAn"};
- printf("NO:%d,nname:%snssex:%cnaddress:%sn",student1.num,student1.name,student1.sex,student1.addr);
- return 0;
Result analysis:
When defining a structure variable, its members are initialized at the same time. The initialization list is some constants enclosed in curly braces. These constants are assigned to the members of the structure variable at one time. Note: it is the structure variable that is initialized, not the structure type.
The values of the members in the structure variable are referenced as follows:
Structure variable name. Member name
student1.name
If the structure member belongs to the same structure type, you need to find the lowest level member one level at a time. For example, the struct Student mentioned above contains struct Date birthday; the reference method is:
Student birthday.month
Structures of the same type can be assigned to each other: student1= student2;
Example:Input the student ID, name and grade of two students, and output the student ID, name and grade of the student with the higher grade;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- int main()
- {
- struct Student
- {
- int num;
- char name[20];
- float score;
- }student1,student2;
- scanf("%d%s%f", &student1.num, student1.name, &student1.score);
- scanf("%d%s%f", &student2.num, student2.name, &student2.score);
- printf("The higher score is:n");
- if (student1.score > student2.score)
- {
- printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
- }
- else if (student1.score < student2.score)
- {
- printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
- }
- else
- {
- printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
- printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
- }
- }
When using the scanf function to input a structure variable, you must enter it separately. You cannot use the structure variable name in the scanf function to input the values of all members at once. Note that the scanf function does not have an & in front of student1.name because the array name already represents the address.
When we defined structure variables earlier, we defined them one by one. However, if a group of related data needs to be involved in the calculation, then data is obviously needed, such as the information of 10 students. This is a structure array, and each array element of the structure array is a structure.
For example: There are 3 candidates, and each voter can only vote for one person. You are required to write a program to count the votes. First, enter the name of the candidate, and then display the result of each vote.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Person
- {
- char name[20];
- int count;
- }leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
- int main()
- {
- int i, j;
- char lead_name[20];
- for (i = 0; i < 10; i++)
- {
- scanf("%s", lead_name);
- for (j = 0; j < 3; j++)
- {
- if (strcmp(lead_name, leader[j].name) == 0)
- leader[j].count++;
- }
- }
- printf("nResultn");
- for (i = 0; i < 3; i++)
- {
- printf("name:%s,count:%dn", leader[i].name, leader[i].count);
- }
- return 0;
- }
The general form of defining a structure array is:
struct structure name
{
Variable List
} array name [array length];
or
First declare a structure type, such as: struct student, and then define the structure array;
Structure type array name [array length];
The form of initialization for structure arrays is to add after the definition:
={initial value list};
Example:There are n students' information (including student number, name, and grades), and it is required to output the information of each student in the order of grades;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- int num;
- char name[20];
- float score;
- };
-
- int main()
- {
- struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };
- struct Student temp;
- printf("The order id:n");
- int i, j,k;
- for (i = 0; i < 4; i++)
- {
- k = i;
- for (j = i + 1; j < 5; j++)
- {
- if (stu[j].score>stu[k].score)
- {
- k = j;
- }
- }
- temp = stu[k];
- stu[k] = stu[i];
- stu[i] = temp;
- }
- for (i = 0; i < 5; i++)
- {
- printf("%d %s %5.2f", stu[i].num, stu[i].name, stu[i].score);
- printf("n");
- }
- return 0;
- }
The so-called structure pointer is a pointer to a structure variable. The starting address of a structure variable is the pointer to this structure variable.
A pointer variable pointing to a structure object can point to a structure variable or an element of a structure array. The base type of the pointer variable must be the same as the type of the structure variable.
For example: struct Student * pt;
Example:Output the member information in the structure variable through the pointer variable pointing to the structure variable;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- long num;
- char name[20];
- char sex;
- float score;
- };
-
- int main()
- {
- struct Student stu1;
- struct Student *pt;
- pt = &stu1;
- stu1.num = 10001;
- strcpy(stu1.name, "Lili");
- stu1.sex = 'M';
- stu1.score = 96.5;
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", stu1.num, stu1.name, stu1.sex, stu1.score);
- printf("n");
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);
- printf("n");
- printf("No:%dnname:%snsex:%cnscore:%5.1fn", pt->num, pt->name, pt->sex, pt->score);
- return 0;
- }
Result analysis:
In the function, the first printf function accesses members through the structure variable name stu1;
The second printf function accesses its members through the pointer variable pointing to the structure variable. (*pt) represents the structure variable pointed to, and (*pt).num represents the structure member pointed to.
In addition, in C language, (*pt).num is allowed to be replaced by pt->num;
Pointer variables can be used to point to elements of a structure array.
Example:There are three students' information, which are placed in a structure array, and the information of the students is required to be output;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
-
- struct Student
- {
- long num;
- char name[20];
- char sex;
- float score;
- };
-
- int main()
- {
- struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };
- struct Student *pt;
- printf("No. name sex scoren");
- for (pt = stu; pt < stu + 3; pt++)
- {
- printf("%d %s %c %5.2fn", pt->num, pt->name, pt->sex, pt->score);
- }
- return 0;
- }
In the program, pt is a pointer to a structure variable of type struct Student. It is used to point to the structure variable, not to a member of the structure. pt=stu[1].name is illegal because one is a structure variable and the other is a member variable of the structure. p++, the value of p increases the length of the structure.
There are three ways to pass the value of a structure variable to a function;
1. Use the members of the structure variable as parameters. This method is equivalent to passing ordinary variables. It should be noted that the types of the formal parameters and the actual parameters (structure members) are the same;
2. Use structure variables as actual parameters. When using structure variables as actual parameters, it is also value passing, and all the contents of the memory unit occupied by the structure variable are passed to the formal parameter. The formal parameter must also be a structure variable.
3. Use the pointer to the structure variable (array) as the actual parameter and pass the address of the structure variable (array) to the formal parameter.
Example:
There are n structures, including student ID, name and grades of 3 courses. The information of the student with the highest average grade (including student ID, name, grades of 3 courses, average grade) must be output.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <string.h>
- void print(struct Student stud);
- struct Student Max(struct Student stu[]);
- void input(struct Student stu[]);
- struct Student
- {
- int num;
- char name[20];
- float score[3];
- float aver;
- };
-
- int main()
- {
- struct Student stu[3], *pt;
- pt = stu;
- input(pt);
- print(Max(pt));
- return 0;
- }
- void input(struct Student stu[])
- {
- int i;
- printf("请输入各学生的信息:学号、姓名、3门成绩:n");
- for (i = 0; i < 3;i++)
- {
- scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
- stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
- }
- }
-
- struct Student Max(struct Student stu[])
- {
- int i, m = 0;
- for (i = 0; i < 3; i++)
- {
- if (stu[i].aver > stu[m].aver)
- m = i;
- }
- return stu[m];
- }
- void print(struct Student stud)
- {
- printf("成绩最好的学生是:n");
- printf("学号:%d 姓名:%s 三门课程:%5.2f %5.2f %5.2f平均成绩:%5.2fn", stud.num, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver);
- }
1. When calling the input function, the actual parameter is the pointer variable pt, the formal parameter is the structure array, the starting address of the structure element is passed, and the function has no return value;
2. When calling the Max function, the actual parameter is the pointer variable pt, the formal parameter is the structure array, the starting address of the structure element is passed, and the function return value is the structure type data.
3. When calling the print function, the actual parameter is a structure variable (structure array element), the formal parameter is a structure variable, and the values of each member in the structure variable are passed. The function has no return value.
A linked list is a common data structure that dynamically allocates storage.
When storing data in an array, the length of the array (multiple arrays) must be defined in advance. If some classes have 100 students and some classes have 30 students, if the same array is used to store the data of students in different classes, an array with a length of 100 must be defined. However, this often results in a waste of resources. A linked list does not have this disadvantage, as it allocates memory units as needed.
The linked list has a "head pointer" variable, represented by head in the figure. It stores an address that points to an element. Each element in the linked list is called a "node", and each node should consist of two parts:
1. Actual data required by users;
2. The address of the next element;
It can be seen that the addresses of the elements in the linked list in memory may not be continuous. To find a certain element, you must first find the previous element, and then find the next element based on the address of the previous element. If the "head pointer" is not provided, the entire linked list cannot be accessed.
In this case, it is most appropriate to use a structure to create a linked list. A structure contains several members, and a pointer type member is used to store the address of the next node.
struct Student
{
int num;
int score;
struct Student *next;
}
Among them, num and score are used to store user data, and next is used to store the address of the next node.
Examples:
Establish a static linked list consisting of nodes of 3 students' data, and require output of the data of each node;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- struct Student
- {
- int num;
- float score;
- struct Student * next;
- };
-
- int main()
- {
- struct Student a, b, c, *head, *p;
- a.num = 1001; a.score = 85.5;
- b.num = 1002; b.score = 95.5;
- c.num = 1003; c.score = 84.5;
- head = &a;
- a.next = &b;
- b.next = &c;
- c.next = NULL;
- p = head;
- do
- {
- printf("%d %5.2fn", p->num, p->score);
- p = p->next;
- } while (p != NULL);
- return 0;
- }
For example, create a linked list with head pointing to node a, a.next pointing to node b, b.next pointing to node c, and c.next pointing to null, which constitutes a linked list relationship.
When outputting a linked list, we must first use p to make p point to a, and then output the data in a. p=p->next is to prepare for outputting the next node.
Before talking about dynamic linked lists, let us first introduce dynamic memory allocation.
Earlier we said that variables are divided into global variables and local variables. Global variables are allocated in the static storage area of memory, and non-statically stored local variables are allocated in the dynamic storage area of memory. This storage area is calledStack。
In addition, C language also allows the establishment of dynamic memory allocation area to store some temporary data. These data are opened when needed and released when not needed. These data are temporarily stored in a special free storage area, which is calledheap。
Dynamic allocation of memory is achieved through functions provided by the system: malloc, calloc, free, and realloc functions.
1. Use malloc function to open dynamic storage area
function: void *malloc (unsigned int size);
Function:
Allocate a continuous space of length size (in bytes) in the dynamic storage area of memory.
return value:
The address of the first byte allocated; this address has no type, it is just a plain address;
2. Use calloc function to open dynamic storage area
function:void * calloc(unsigned n,unsigned size);
Function:
Allocate n bytes of continuous space of size in the dynamic storage area of memory. This space is large enough to store an array;
The calloc function can be used to allocate dynamic storage space for a one-dimensional array, where n is the number of array elements and size is the element length.
return value:
The address of the first byte allocated; this address has no type, it is just a plain address;
3. Use the realloc function to reallocate dynamic storage area
function:void * realloc(void *p ,unsigned int size);
Function:
Reallocate the allocated dynamic memory.
Use the recalloc function to change the size of the dynamic space pointed to by p to size. The value of p remains unchanged;
return value:
The address of the first byte of the updated dynamic memory is actually the address pointed to by p.
4. Use the free function to release the dynamic storage area
function: void free(void *p);
Function:
Release the dynamic space pointed to by the pointer variable p so that this space can be used by other variables.
p is the return value of the most recent call to the malloc or calloc function;
return value:
none;
Note: The declarations of the above 4 functions are all in the stdlib.h header file.
void pointer type:
In the above functions, the return values of malloc function and calloc function are both of void * type, which means that it does not point to any type of data. Do not understand it as pointing to any type, but pointing to empty type or not pointing to data of a certain type.
When calling dynamic memory, the program only uses the pure address brought back by the function, and does not use the attribute of pointing to any data type. If you want to use this address, you must convert it.
For example:
int *p;
p=(int*)malloc(100);
Examples:
Create a dynamic data set, input the scores of 5 students, and use a function to check if any of them score less than 60 points, and output the unqualified scores;
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- int main()
- {
- void check(int * p);
- int *p1, i;
- p1 = (int *)malloc(5 * sizeof(int));
- for (i = 0; i < 5; i++)
- {
- scanf("%d", p1 + i);
- }
- check(p1);
- return 0;
- }
- void check(int * p)
- {
- int i;
- printf("they are fail:n");
- for (i = 0; i < 5; i++)
- {
- if (*(p+i) < 60)
- printf("%d ", *(p + i));
- }
- }
operation result:
Result analysis:
No array is defined in the program, only a dynamically allocated free area is opened up for use as an array.
In the malloc function, no specific value is passed directly to allocate dynamic space. Instead, sizeof is used to calculate the number of bytes of this system integer, and then 5 elements are created. p is used to point to the first byte address and converted to int type, and p+1 points to the next element.
Write a function to create a dynamic linked list with 4 students' data.
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- #define LEN sizeof(struct Student)
-
- struct Student
- {
- long num;
- float score;
- struct Student * next;
- };
-
- int n;
- struct Student * creat(void)
- {
- struct Student * head, *p1, *p2;
- n = 0; p1 = p2 = malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- head = NULL;
- while (p1->num != 0)
- {
- n = n + 1;
- if (n == 1)
- head = p1;
- else p2->next = p1;
- p2 = p1;
- p1 = (struct Student *)malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- }
- p2->next = NULL;
- return (head);
- }
-
- int main()
- {
- struct Student * pt;
- pt = creat();
- printf("n num:%ld score:%5.2fn", pt->num, pt->score);
- return 0;
- }
-
-
operation result:
Result analysis: The creation of a dynamic linked list first specifies three structure pointers, then uses the malloc function to create a node, points the three structure pointers to this node, then p1 uses the malloc function to create a node, and points p2's next to the created node, after pointing p2=p1, p1 then creates p2's next to point to the created node, p2=p1.... until the value of the element in p1 is 0, p2's next does not point to the newly created node, but points to NULL, so that a dynamic linked list is created, head points to the first node, and itself is the head node.
Input and output of dynamic linked lists:
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
-
- #define LEN sizeof(struct Student)
-
- struct Student
- {
- long num;
- float score;
- struct Student * next;
- };
- int n;
- struct Student * creat(void)
- {
- struct Student * head, *p1, *p2;
- head = NULL;
- n = 0;
- p2 = p1 = malloc(LEN);
- scanf("%ld%f", &p1->num, &p1->score);
- while (p1->num != 0)
- {
- n = n + 1;
- if (n == 1)
- head = p1;
- else
- p2->next = p1;
- p2 = p1;
- p1 = malloc(LEN);
- scanf("%ld %f", &p1->num, &p1->score);
- }
- p2->next = NULL;
- return head;
- }
-
- void print(struct Student * p)
- {
- do
- {
- printf("%ld %5.2fn", p->num ,p->score);
- p=p->next;
- } while (p->num != NULL);
- }
-
- int main(void)
- {
- struct Student * pt;
- pt = creat();
- print(pt);
- return 0;
- }
operation result:
Sometimes, we want to store variables of different types in the same memory unit. For example, we can put integer variables, character variables, and floating-point variables in memory units starting at the same address. This allows several variables to share the same memory structure, which is called a "community".
The general form of defining a union is:
union name
{
Member list;
}variable list;
For example:
union Data
{
int i;
char ch;
float f;
}a,b,c;
The memory length occupied by a structure variable is the sum of the memory lengths occupied by each member; while the memory length occupied by a union is the length of the longest member.
Only when the union variable is defined in advance can it be referenced. Note that what we reference is not the union variable but the member of the referenced union variable.
ai references the integer variable in the union variable;
a.ch refers to the character variable in the union variable;
af refers to the real variable in the union variable;
1. A memory segment can be used to store several different types of members, but only one of them can be stored at any moment, rather than several at the same time.
2. Union variables can be initialized, but there can only be one constant in the initialization table.
3. The member of the union variable that it acts on is the member that is assigned a value for the last time, and the original variable is overwritten and replaced.
4. The address of the union variable is the same as the addresses of its members.
5. You cannot assign a value to a union variable name, nor can you attempt to reference a variable name to get a value.
If some variables have only a few possible values, they can be defined as enumeration types; the so-called enumeration is to list the possible values one by one.
To declare an enumeration type, start with "enum"; for example
eunm Weekday{sun,mon,tue,wed,thu,fri,sat};
The above declares an enumeration type enum Weekday. Then you can use this type to define variables.
enum Weekday workday,weekend;
Among them, workday and weekend are defined as enumeration variables, and the words in curly braces are called enumeration elements or enumeration constants.
The general form of declaring an enumeration type is:
enum [enumeration name] {enumeration element list};
Example:
There are 5 kinds of balls in the pocket: red, yellow, blue, white and black. Take out 3 balls from the pocket one by one each time. What are the possible ways to get 3 balls of different colors and arrange them?
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
-
- int main()
- {
- enum Color {red,yellow,bule,white,black};
- enum Color i, j, k, pri;
- int n, loop;
- n = 0;
- for (i = red; i <= black; i++)
- for (j = red; j <= black; j++)
- if (i != j)
- {
- for (k = red; k <= black; k++)
-
- if ((k != i) && (k != j))
- {
- n++;
- printf("%d ", n);
- for (loop = 1; loop <= 3; loop++)
- {
- switch (loop)
- {
- case 1:pri = i; break;
- case 2:pri = j; break;
- case 3:pri = k; break;
- default:break;
- }
-
- switch (pri)
- {
- case red:printf("%s ", "red"); break;
- case yellow:printf("%s ", "yellow"); break;
- case bule:printf("%s ", "bule"); break;
- case white:printf("%s ", "white"); break;
- case black:printf("%s ", "black"); break;
- default:break;
- }
- }
- printf("n");
- }
- }
- printf("n total:%dn", n);
- return 0;
- }
operation result:
Use typedef to specify a new type name to replace the existing type name;
1. Simply replace the original type name with a new type name
For example:
typedef int Integer;
typedef float Real;
Thus, the following two lines are equivalent:
int i,j;——— Integer i,j;
2. Name a simple type name instead of a complex type representation method
Give the new type name to represent the structure type:
typedef struct
{
int mun;
......
} Data;
Then use the new type name Data to define the variable;
Data brithday;
Data * p;
Give a new type name instead of the array type:
typedef int Num[100];
Num a;
Name a new type name to represent the pointer type:
typedef char * String;
String p,a[10];
Name a new type name to represent a pointer to a function;
typedef int (* Pointer)();
Pointer p1,p2;
In summary: By defining variables in the same way, replace the variable name with a new type name and add typedef at the beginning, it is declared that the new type name represents the original type.
typetef simply assigns a new type name to an existing type, but does not create a new type.
typetef and #define have superficial similarities.
typedef int Count
#define Count int
Their functions are both to replace int with Count, but in fact they are different. #define is processed in pre-compilation and can only be used as a simple string replacement, while typedef is processed in the compilation stage. In fact, it is not a simple replacement. Instead, a new type name is generated and then the variable is defined.