Introduction to C language lesson 7: structure

Lesson 7: structure

catalogue

Lesson 7: structure

1.1 declaration of structure

1.2. Access of structure members

1.3. Structure transmission parameters

1.4. Compound literal and structure in C99

1.5. Scalable array members in C99

Anonymous structure in 1.6 · C11

1.1 declaration of structure

Before explaining the structure, let's look at a problem: creating a book catalog

Requirement Description: Gwen Glenn wants to print a book catalogue. He wants to print all kinds of information about each book: title, author, publisher, publication date, number of pages, number of copies and price. The data type is customized.

//book.c catalogue of the book
#include<stdio.h>
#include<string.h>
#Define maxitl 41 / / maximum length of book title + 1
#define MAXAUTL 31 / / maximum length of author name + 1
char* s_gets(char* st,int n);

struct book//Structure template: tag is book
{
    char title[MAXTITL];//title
    char author[MAXAUTL];//Author name
    float value;//Unit Price
};

int main(void)
{
    struct book library;//Declare library as a variable of type book
    printf("Now please enter the title of the book.\n");
    s_gets(library.title,MAXTITL);//Visit the title section
    printf("Now please enter the author of the book.\n");
    s_gets(library.author,MAXAUTL);//Visit the author section
    printf("Now please enter the unit price of the book.\n");
    scanf("%f",&library.value);//Enter unit price
    printf("%s from%s The unit price is%f",library.title,library.author,library.value);
    return 0;
}

char* s_gets(char* st,int n)
{
    char* ret_val;
    char* find;
    ret_val=fgets(st,n,stdin);
    if(ret_val)
    {
        find=strchr(st,'\n');//Find line breaks
        if(find)            //If the address is not NULL
            *find='\0';     //Place an empty character here
        else
            while(getchar()!='\n')
                continue;//Process the remaining characters in the input line
    }
    return ret_val;
}

Running result: the content written here

Now please enter the title of the book

Chicken of the Andes

Now please enter the author

Disma Lapoult

Please enter the unit price now

29.99

Chicken of the Andes was written by Dima lapoult and the unit price is 29.99

Therefore, we master and understand three skills:

① Create a format or style for the structure

② Declare a variable suitable for the style

③ Accessing parts of a structure variable

Basic knowledge of structure
A structure is a collection of values called member variables. Each member of the structure can be a different type of variable.

Type of structure member: the members of a structure can be scalars, arrays, pointers, or even other structures

Declaration of structure:

A structure declaration describes the organizational layout of a structure. Enclosed in a pair of curly braces in a structure declaration is a list of structure members. Each member is described with its own declaration. If you place a structure declaration outside a function, all functions after the declaration can use its tag. For example: struct book dickens; In this way, the function creates a structure variable dickens, whose structure layout is book.

For calculation purposes, the following statement:

//First kind
struct book
{
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};

struct book library;

//Second
struct book
{
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
}library;//The declared closing curly bracket is followed by the variable name

//The first is the simplification of the second
//The process of declaring structure and the process of defining structure variables can be combined into one step, that is, declaration and definition together

Definition and initialization of structure variables: with structure types, how to define variables is actually very simple.
 

struct Point
{
int x;
int y;
}p1; //Define the variable p1 while declaring the type
struct Point p2; //Define structure variable p2
//Initialization: define variables and assign initial values at the same time.
struct Point p3 = {x, y};

struct Stu //Type declaration
{
char name[15];//name
int age; //Age
};
struct Stu s = {"zhangsan", 20};//initialization

struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL}; //Structure nesting initialization
struct Node n2 = {20, {5, 6}, NULL};//Structure nesting initialization

In short (use the data of the book catalog here): we initialize with an initialization list enclosed in a pair of curly braces, and each initialization item is separated by commas. Therefore, the title member can be initialized to a string and the value member can be initialized to a number. In order to make the association between initialization items and members in the structure more obvious, we let the initialization items of each member monopolize one line. In order to improve the readability of the code, the compiler only needs to separate the initialization items of each member with commas.

Extended knowledge: initializer of structure

C99 and C11 provide specified initializers for structures. The specified initializer of the structure identifies a specific element using a dot operator and a member name instead of square brackets and subscripts. For example, to initialize only the value member of the book structure:

struct book surprise={  .value=10.99};

Initializers can be specified in any order:

struct book gift={ .value=25.99,

                            .author="James Boradfool",

                            .title="Rue for the Toad"};

Similar to arrays, the normal initializer after the specified initializer provides the initial value for the member after a specific member. In addition, the last assignment to a particular member is the value it actually gets. For example:

struct book gift={  .value=18.90,

                             .author="Philionna Pestle",

                              0.25 

                                }

The value assigned to value is 0.25 because it follows the author member in the structure declaration, and the new value of 0.25 replaces the previous 18.9. (the structure storage member is placed in a continuous memory space. After initializing the author, the value is read along the memory) for example:

 

1.2. Access of structure members

Structural variable access members: members of structural variables are accessed through the point operator (.) Access (you can also use - > access, which is not discussed here). The point operator accepts two operands.

 

struct stu
{
    char name[20];
    int age;
};
struct stu s;

//We can see that s has member name and age;
//How do we access members of s?

struct S s;
strcpy(s.name, "zhangsan");//use. Access name member
s.age = 20;//use. Access age members

Structure pointer accesses members pointing to variables. Sometimes we get a pointer to a structure instead of a structure variable. How do I access members?

As follows:

struct Stu
{
char name[20];
int age;
};
void print(struct Stu* ps)
{
printf("name = %s age = %d\n", (*ps).name, (*ps).age);
//Use structure pointers to access members that point to objects
printf("name = %s age = %d\n", ps->name, ps->age);
}
int main()
{
struct Stu s = {"zhangsan", 20};
print(&s);//Structure address transfer parameter
return 0;
}

1.3. Structure transmission parameters

For the same reason, just go to the code and have a good look:

struct S
{
int data[1000];
int num;
};
struct S s = {{1,2,3,4}, 1000};

//Structure transfer parameter I
void print1(struct S s)
{
printf("%d\n", s.num);
}

//Structure address transfer parameter 2
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}

int main()
{
print1(s); //Transmission structure
print2(&s); //Transmission address
return 0;
}

Think: which of the print1 and print2 functions is better?

Answer: print2 function is preferred

Reason: when the function passes parameters, the parameters need to be pressed on the stack. If the structure is too large when passing a structure object, the system overhead of parameter stack pressing is relatively large, which will lead to performance degradation.

Conclusion: when the structure passes parameters, the address of the structure should be passed.

1.4. Compound literal and structure in C99

The compound literal property of C99 can be used for structures and arrays. If only one temporary structure value is required. Compound literal is easy to use. For example, you can use compound literals to create a structure as an argument to a function or assign it to another structure. Syntax is to put the type name in parentheses, followed by an initialization list enclosed in curly braces. For example, the following is the compound literal of srtuct book type:

(struct book) {"The Idiot","Fyodor Dostoyevsky",6.99}

give an example:

If the compound literal is outside all functions, it has a static storage period;

If the compound literal is in a block, it has an automatic storage period;

The specified initializer can be used in a compound literal.

1.5. Scalable array members in C99

C99 adds a new feature: scalable array members. The last array member of the structure declared by this feature has some characteristics. The first feature is that the array does not exist immediately. The second feature is that using this scalable array member can write appropriate code as if it really exists and has the required number of elements. This may sound strange, so let's create and use a structure with scalable array members step by step.

First, declare a scalable array member with the following rules:

① The scalable array member must be the last member of the structure

② Structure must have at least one member

③ The declaration of a telescopic array is similar to an ordinary array, except that its square brackets are empty

example:

struct flex
{
    int count;
    double average;
    double scores[];//Scalable array member
};

When declaring a struct flex type structural variable, you can't do anything with scores because there is no storage space reserved for this array. In fact, the intention of C99 is not to let you declare variables of struct flex type, but to declare a pointer to struct flex type, and then use malloc() to allocate enough space to store the general contents of struct flex type structure and the additional space required by scalable array members. For example, suppose you use scores to represent an array containing five double type values. You can do this:

struct flex* pf;//Declare a pointer
//Request to allocate storage space for a structure and an array
pf=malloc(sizeof(struct flex)+5*sizeof(double));

There is now enough storage space to store count, average, and an array of five double type values. These members can be accessed with pointers pf:

pf->count=5;//Set count member
pf->scores[2]=18.5;//Accessing an element of an array member

Anonymous structure in 1.6 · C11

An anonymous structure is a structure member without a name. To understand how it works, let's first consider how to create a nested structure:

struct names
{
    char first[20];
    char last[20];
};
struct person
{
    int id;
    struct names name;//Nested structure members
};
struct person ted={8483,{"Ted","Grass"}};

Here, the name member is a nested structure, which can be passed through a function similar to Ted name. The expression of first accesses "red"; For example: puts(ted.name.first).

In C 11, a person can be defined with a nested anonymous member structure:

struct person
{
    int id;
    struct {char first[20];char last[20];};//anonymous structure 
};
initialization ted The method is the same:
struct person ted={8483,{"Ted","Grass"}};
However, during the visit ted It simplifies the steps, just put first As time person Use it like members of
 For example: Puts(ted.first);
Of course, you can also first and last Direct act person Delete the nested loop.
Anonymous features make you more useful in nested unions.

Keywords: C Back-end

Added by elToro on Tue, 25 Jan 2022 06:19:14 +0200