10- c language compound data type (C language)

a structure

1.1 Introduction

1. Any object in nature has multiple attributes . If it is described in computer language, an attribute may be represented by a certain basic data type, but when there are multiple attributes, a basic data type is Can't express anymore. Example: Student: Name Gender Age Phone Number Home Address. . .

char name[32];
char gender;
int age;
char tel[12];
char addr[100];

2. How can we store all the attributes of students in a data type?

struct student{
    char name[32];
    char sex;
    int age;
    char tel[12];
    char addr[100];
};

struct : structure
struct student: type name
define a variable: struct student s ;

1.2 Definition of structure

1. Structure type definition:
struct structure name
{         member variable 1;         member variable 2;         ...         member variable n; }; note: functions cannot be defined in the structure





2. Definition of structure variables

  • struct structure name variable name;   struct student s ;
  • struct structure name * variable name;  struct student *p ;
  • struct structure name variable name[length];  struct student s[10] ;

Definition of uncommonly used structure variables:

struct
{         member variable 1;         member variable 2;         ...         member variable n; } structure variable 1, structure variable 2, structure variable 3; for example: struct {         int age; } A, B, C; A, B , C is a structure variable










1.3 Initialization of member variables in the structure

1. The initialization value of this method must be consistent with the definition order of the member variables when defining the structure !

strcut student s = {
        "zhangsan",
        18,
        'm'
};

2. The period symbol in front of the member variable name .

struct student s = {
        .name = "zhangsan",
        .age = 18,
        .sex = 'm',
        .f1 = func;
};

1.4 Access to member variables in the structure

1. : Domain operation
Prerequisite: The structure variable is an ordinary variable/array

struct student s;
s.age = 18;
s.sex = 'f';

2. -> : Pointer operation
Premise: The structure variable is a pointer variable

struct student *p;
p = &s1;

3. If the structure pointer variable p points to a certain memory space , there are three ways to operate the pointed memory space through the pointer p:
Method 1: Subscript method
p[i]. Member variable
Method 2: Pointer method , not commonly used
( *(p+i)). Member variable
method 3: used pointer operator
(p+i) == &p[i]
(p+i)-> member variable

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

struct Stu{
    int age;
};

int main() {
    struct Stu *s;
    s = (struct Stu *)malloc(3*sizeof(struct Stu));
    s[0].age = 10;
    
    (s+1)->age = 12;
    (*(s+1)).age = 15;
    return 0;
}

4. Exercise:
Design a structure to store the student's name, gender, and age.
Define a structure pointer variable to store the information of 3 students, and use this pointer to assign values ​​to the member variable rows in each structure.

1.5 Application of function pointers in structures

Thinking:
If the student's hobby is ball games, multiple functions can be defined to describe each ball game, for example:

void play_basketball();
void play_pingpong();
void play_football();

Thinking: How to design a variable in the structure to save the student's hobbies?
Function pointer
Thinking: How to let the student do this hobby?
The function pointer points to the corresponding function, and the function is called through the function pointer

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

typedef void(*FUNC)(char *);

//定义结构体类型
struct student1{
    char name[32];
    char sex;
    int age;
    FUNC
    f;   //函数指针
};

void play_basketball(char *name){
    printf("%s play basketball\n", name);
}

void play_pingpong(char *name){
    printf("%s play pingpong\n", name);
}

void play_football(char *name){
    printf("%s play football\n", name);
}

//操作结构体中的成员变量为函数指针变量
void test2(){
    struct student1 s;
    memset(s.name, 0, sizeof(s.name));
    strcpy(s.name, "zhangsan");
    //zhangsan的爱好是 play football
    //将s.f 指向 play_football函数
    s.f = play_football;
    //zhangsan 开始踢足球了
    s.f(s.name);
}

int main(){
    test2();
    return 0;
}

1.6 typedef redefines the structure type

1. Use typedef to redefine the type
typedef struct structure name
{         member variable 1;         member variable 2;         ...         member variable n; } new type 1, *new type 2;




  • new type 1 variable name 1;
  • New type 2 variable name 2; //The data type of variable name 2 is a pointer type

2. Written test questions

#define struct stu* stu;
typedef struct stu* p_stu;

stu a,b;     //struct stu *a, b;
p_stu a, b;  //struct stu *a, *b;

What is the difference between these a and b, and which method is best to use (#define /typedef)

1.7 The member variables in the structure are other structure variables/pointers

1. Assume the following scenario: use a structure to describe a certain book, the attributes of the book: name, price, author, publisher

Define the structure description author :

struct author{
    char name[32];  //名字
    int age;   //年龄
};

Define a structure describing the press :

struct publish{
    char name[32];   //名字
    char addr[32];   //地址
};

Define the structure description :

struct book{
    char name[32];   //名字
    unsigned int price;   //价格
    struct author ath;    //作者
    struct publish *publish;   //出版社
};

2. Access the structure member variables in the structure

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

struct author{
    char name[32];  //名字
    int age;   //年龄
};

struct publish{
    char name[32];   //名字
    char addr[32];   //地址
};

struct book{
    char name[32];   //名字
    unsigned int price;   //价格
    struct author ath;    //作者
    struct publish *publish;   //出版社
};

int main(){
    struct book book;
    struct book book2;

    //初始化作者
    memset(book.ath.name, 0, sizeof(book.ath.name));
    strcpy(book.name, "zhangsan");
    book.ath.age = 30;

    //为指针变量pblish 分配空间     //书籍有两个出版社
    book.publish = (struct publish *)malloc(2*sizeof(struct publish));
    strcpy(book.publish[0].name, "hunan");
    strcpy(book.publish[1].name, "renming");

    printf("view the book name: %s\n", book.name);  //zhangsan
    printf("view the book publish: %s\n", book.publish);   //hunan
    return 0;
}

1.8 Direct assignment of structures

1. Use = to assign the content in one structure to another structure

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

struct A {
    int x;
    int y;
};

struct author{
    char name[32];  //名字
    int age;   //年龄
};

struct publish{
    char name[32];   //名字
    char addr[32];   //地址
};

struct book{
    char name[32];   //名字
    unsigned int price;   //价格
    struct author ath;    //作者
    struct publish *publish;   //出版社
};

int main(){
    struct A a, b;
    a.x = 100;
    a.y = 1000;
    b = a;
    printf("view the data b.x: %d, b.y: %d\n", b.x, b.y);

    struct book b1, b2;
    memset(b1.name, 0, sizeof(b1.name));
    strcpy(b1.name, "aiot");
    b1.price = 100;

    //对书的作者进行赋值
    strcpy(b1.ath.name, "lisi");
    b1.ath.age = 30;

    //对出版社进行赋值
    //在堆上分配了一个struct publish大小的空间
    b1.publish = (struct publish *)malloc(sizeof(struct publish));
    strcpy(b1.publish[0].name, "renmin");
    strcpy(b1.publish[0].name, "renmin");

    b2 = b1;
    printf("name: %s\n", b2.name);  //aiot
    printf("price:%d\n", b2.name);  //6421872
    printf("ath.name:%s\n", b2.ath.name);  //lisi
    printf("ath.age: %d\n", b2.ath.age);   //30
    printf("pbl.name: %s\n", b2.publish[0].name);  //renmin
    printf("pbl.addr: %p\n", b2.publish[0].addr);  //
    printf("pbl: %p  %p\n", b1.publish, b2.publish);

    printf("view line --------------------------------------\n");

    //strcpy(b2.publish -> name, "jixie");
    free(b2.publish);   //释放堆上的空间
    printf("pbl.name:%s\n", b1.publish[0].name);

    strcpy(b2.name, b1.name);
    b2.price = b1.price;
    b2.ath = b1.ath;
    //为 b2.publish 单独分配空间
    b2.publish = (struct publish *)malloc(sizeof(struct publish));
    //将 b1.publish 这个指针所指向的空间中的内容拷贝 b2.publish 这个指针所指向的空间中
    memcpy(b2.publish, b1.publish, sizeof(struct publish));

    return 0;
}

Judging from the running results of the above program, a structure variable can be assigned to another structure variable through =, and the contents of the two structure variables are exactly the same.
If there are pointer variables in the structure, the pointer variables in the two structures point to the same memory space (the two pointers will affect each other): because
book2.pblish and book.pblish point to the same memory space , where Any variable that frees the space pointed to by pblish will affect another structure variable operation pulish, if you execute free (book.pblish);

printf("%s %s\n", book2.pblish[0].name, book2.pblish[1].name);  //这条语句可能会执行失败。

Two Unions/Communities

2.1 Definition of Community

union name
{         member variable 1;         member variable 2;         ...         member variable n;};




2.2 Memory layout of the union

  • Storage of member variables of the union: All member variables share a memory space .
  • The size of the union: the size of the variable that occupies the largest memory space among the member variables .
union un {
    char ch[2];
    int x;
};

union un2{
    char ch[2];
    short x;
};

union un u1;
union un2 u2;
sizeof(u1) == 4;
sizeof(u2) == 2;

2.3 Practical use of the union

1. In actual work, if you know the value of an integer variable (int a) and you need to find out the value of each byte of this variable, you can use the union.

union un{
    char ch[4];
    int x;
};

union un u;

You only need to set ux = a; then the value of each byte that makes up a has been saved in the u.ch array.
On the contrary, if you know the value of each byte that makes up a, you need to find the value of a, just need Assign each element of u.ch to the value of each byte that makes up a, then ux is the value of a.
2. The sensor GY39 can measure temperature, humidity, atmospheric pressure and altitude. If we develop a device and connect it to the GY39 module, the data format returned by GY39 is as follows: 0x5a 0x5a 0x01 0x02 0x03 0x02 0x00 0x01 0x02 0x03
0x00 0x02 0x03 0x04 0x5a 0x5a
Suppose we define a character array char ch[16] to save the data transmitted by GY39
Temperature: ch[2]<<8 | ch[3]
Humidity: ch[4]<<8 | ch[5] ]
Atmospheric pressure: ch[6]<<24 | ch[7]<<16 | ch[8]<<8 | ch[9] altitude: ch
[10]<<24 | ch[11]<<16 | ch[12]<<8 | ch[13]
If you use the union to find the temperature or humidity

union un{
    char ch[2];
    unsigned short x;
};

union un u; 
u.ch[0] = ch[3], u.ch[1] = ch[2];

ux is the value of temperature! !

2.4 Little endian mode and big endian mode

1. The storage of data in memory is stored in binary form, but if the memory space occupied by the data exceeds 1Byte, we can also understand that the data is stored byte by byte in memory.
For example, int x = 100; x occupies 4 bytes, and x is split into 4 bytes in memory and stored separately.

What are the values ​​stored in these four bytes? We can get it through the union. 

union un{
    char ch[4];
    int x;
};

int main(){
    union un un;
    un.x = 0x01020304;
    printf("0x%x 0x%x 0x%x 0x%x\n", un.ch[0], un.ch[1], un.ch[2], un.ch[3]);
    // 0x4 0x3 0x2 0x1
}

The memory layout of the union is as follows:

According to the running results of the program, we found that because we can draw a conclusion: the data of the low byte is stored in the low address, and the data of the high byte is stored in the high address. We call this storage mode: little-endian mode
2. If the data of the low byte is stored in the high address, the data of the high byte is stored in the low address. We call this storage mode: big endian mode .
Because our computer is in little-endian mode, we cannot demonstrate the large-segment mode. The memory layout of the big-endian mode is as follows: 

3. Note: big-endian mode and little-endian mode have nothing to do with the operating system! It is related to the processor (CPU).
At present, most processors are in little-endian mode, but some embedded processors are in big-endian mode, and even some embedded processors can be set to big-endian mode or little-endian mode. (Both are supported).
4. Written test questions
Please write code to test whether a processor is in big-endian mode or little-endian mode.

three enumeration

3.1 Definition of enumeration

enum type name {         member 1,         member 2,         ...         member n};Note: there is no need to declare the data type in front of the member, just write the member name





3.2 Initialization of enumeration members

Enumeration is to enumerate all the members one by one ! , if the first member is not initialized, the value of the first member is 0, and the value of each subsequent member is +1 in turn, until the enumeration is completed or a member is assigned using an assignment statement, +1 stops , the value of the assigned member is the assigned value, and the value of each subsequent member of the member is sequentially +1 based on the value of the member.

3.3 Practical uses of enumerations

If an array is used to store the number of days in each month, February is 28 days by default
int mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if It is necessary to obtain the number of days in a certain month, such as the number of days in May. The subscript method accesses the mon array: mon[4], but the readability of the code written in this way is not strong, and readers of mon[4] may not necessarily know what it represents It is the number of days in May. If it is written like this: mon [May], it will be more readable!
Follow this line of thought: January: Jan, February: Feb March: March.... 

 

Guess you like

Origin blog.csdn.net/March_A/article/details/131367248