Chapter 14 structures and other forms of data

A structure (struct)

Structure similar to java in the class, but it is only property, no way

1.1 Definitions, declarations, initialization structure, access structure members

#include <stdio.h>
#define	SIZE 20

//定义结构
struct book
{
	char name[SIZE];
	char author[SIZE];
	double price;
};

int main(void)
{
    //声明结构
	struct book book_b;
	struct book book_c;

	//声明结构同时初始化
	struct book book_a = {
		"C Primer Plus",
		"Stephen Prata",
		60
	};

	//使用初始化器初始化,这种方式会指定的成员初始化,其他成员使用默认值
	struct book book_d = {
		.author = "d"
	};		

	//使用访问结构成员的方式进行初始化,这种方式初始化会导致如果访问未被初始化的属性发生内存泄漏
	gets_s(book_c.name, SIZE);
	gets_s(book_c.author, SIZE);
	book_c.price = 50;

	//把一个结构初始化为另一个结构
	book_b = (struct book){
		"b",
		"B",
		60
	};

	printf("book_a: \n");
	printf("name: %s, author: %s, price: %.2f", book_a.name, book_a.author, 		book_a.price);
	printf("\n--------------------------------\n");

	printf("book_b: \n");
	printf("name: %s, author: %s, price: %.2f", book_b.name, book_b.author,           book_b.price);
	printf("\n--------------------------------\n");

	printf("book_c: \n");
	printf("name: %s, author: %s, price: %.2f", book_c.name, book_c.author, book_c.price);
	printf("\n--------------------------------\n");

	printf("book_d: \n");
	printf("name: %s, author: %s, price: %.2f", book_d.name, book_d.author, book_d.price);
	printf("\n--------------------------------\n");

	getchar();

}

/*运行结果
c
C
book_a:
name: C Primer Plus, author: Stephen Prata, price: 60.00
--------------------------------
book_b:
name: b, author: B, price: 60.00
--------------------------------
book_c:
name: c, author: C, price: 50.00
--------------------------------
book_d:
name: , author: d, price: 0.00
--------------------------------
*/

Detailed codes:

Structure has two meanings. A layer of meaning is "structural layout", layout structure to tell the compiler how to represent data, but it does not allow the compiler to allocate space for the data. Another meaning is a structure variable, create a structure variable:

​ struct book book_a;

The compiler performs this line of code will create a structure variable book_a. The compiler uses to allocate space for the book template variables: SIZE contains two elements of an array of char and a variable of type double.

1.5 structure array

An array is an array of structures inside the store structure.

Example:

#include <stdio.h>
#define SIZE 20

struct book
{
        char name[SIZE];
        char author[SIZE];
        double price;
};

int main(void)
{
        int i;
    	//创建结构数组
        struct book books[SIZE] =
        {
                {"aa", "AA", 20.5},
                {"bb", "BB", 30},
                {"cc", "CC", 40}
        };

    	//输出数组
        printf("%15s %15s %15s\n", "name", "autor", "price");
        for(i = 0; i < 3;  i++)
                printf("%15s %15s %13.2f\n", books[i].name, books[i].author, 	 books[i].price);

        return 0;
}
/*运行结果
 name           autor           price
 aa              AA         20.50
 bb              BB         30.00
 cc              CC         40.00
 */

A pointer to a struct 1.6

This example demonstrates two methods:

Ⅰ. The pointer to the structure of an already declared

Ⅱ. Allocation of space using a pointer malloc

Example 1:

#include <stdio.h>
#define SIZE 20

struct book
{
        char name[SIZE];
        char author[SIZE];
        double price;
};


int main(void)
{
        struct book book_a ={
                "C Primer Plus",
                "Stephen Prata",
                60
        };
        //声明结构指针
        struct book * book_ptr_a;
        struct book * book_ptr_b;

        //指针指向 book_a
        book_ptr_a = &book_a;
		//输出
        printf("%15s %15s %15s\n", "name", "autor", "price");
        printf("%15s %15s %13.2f\n", book_ptr_a->name, book_ptr_a->author, book_ptr_a->price);
        return 0;
}
/*结果
name           autor           price
C Primer Plus   Stephen Prata         60.00
*/

Example 2:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 20

struct book
{
        char name[SIZE];
        char author[SIZE];
        double price;
};

int main(void)
{
        struct book* book_ptr_b;
        double* p = (double *) malloc(5 * sizeof(double));
        //使用 malloc 分配空间
        book_ptr_b = (struct book*) malloc(sizeof(struct book));
        //设置属性
        scanf("%s%s", book_ptr_b->name, book_ptr_b->author);
        book_ptr_b->price = 50;
              
        printf("%15s %15s %15s\n", "name", "autor", "price");
        printf("%15s %15s %13.2f\n", book_ptr_b->name, book_ptr_b->author, book_ptr_b->price);
    	//malloc 分配的空间不会自动释放,养成好的编程习惯,要使用 free 释放空间
    	free(p);

        return 0;
}
/*运行结果
bb cc
name           autor           price
bb              cc         50.00
*/

Example 3: stretchable members of the array, is an array of structures is not initialized when defining

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

struct class
{
        int grade;
        int stdunts[];  //stdunts的长度未指定
};

int main(void)
{
    	//声明并初始化一个 students 的长度未5 的结构 class
        struct class * c = (struct class *) malloc(sizeof(struct class) + 5 * sizeof(int));
    	
    	free(c);

        return 0;
}

1.7 transfer information structure to function

You can pass three types of information:

Ⅰ. Transfer structure members

Ⅱ. Transferred structured pointer (Address transfer)

Ⅲ. A transfer structure (passed by value)

1.8 Use malloc () to allocate memory for the pointer member structure

Example:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 20

struct book
{
        char * name;	//name 是一个指针,它存储字符串的地址
        char * author;
        double price;
};

int main(void)
{
        //声明一个 book 结构
        struct book mybook;

        //分配 name 指向的内存  
        mybook.name = (char *) malloc(SIZE);
        //分配 author 指向的内存        
        mybook.author= (char *) malloc(SIZE);

        //为 name 指向的内存设置一个值
        scanf("%s %s", mybook.name, mybook.author);

        //输出值
        printf("%s, %s\n", mybook.name, mybook.author);
        return 0;
}
/*运行结果
aaa AAA(输入)
aaa, AAA (输出)
*/

1.10 Save configuration to a file

/*fwrite 把结构保存到文件中,注:保存到文件中的是二进制格式*/
#include <stdio.h>
#define SIZE 20

//定义结构体
struct book
{
        char name[SIZE];
        char author[SIZE];
        double price;
};

int main(void)
{
        FILE *bookfile;
        int i;
        //定义一个结构数组
        struct book books[3] = {
                {"aa", "AA", 20},
                {"bb", "BB", 30},
                {"cc", "CC", 40}
        };

        bookfile = fopen("books", "wb");
        fwrite(books, sizeof(struct book), 3, bookfile);        //把数组中内容写到 bookfile 文件中

        fclose(bookfile);

        return 0;
}
/*使用 fread() 从文件中读取结构*/
#include <stdio.h>
#define SIZE 20

//定义一个结构体
struct book
{
        char name[SIZE];
        char author[SIZE];
        double price;
};

int main(void)
{
        int i;
        FILE *bookfile;         //文件指针
        struct book books[3];   //结构数组

        bookfile = fopen("books", "rb");        //打开books
        fread(books, sizeof(struct book), 3, bookfile); //把文件中的内容读到结构数组中 

        //输出
        printf("books: \n");
        for(i = 0; i < 3; i++)
                printf("name: %s, author: %s, price: %.2f\n", books[i].name, books[i].author, books[i].price);

        return 0;
}
/*结果:
books: 
name: aa, author: AA, price: 20.00
name: bb, author: BB, price: 30.00
name: cc, author: CC, price: 40.00
*/

Second, the joint (union)

Joint is a data type, in the same memory space can store different types of data (memory not simultaneously).

2.1 Joint

Example:

#include <stdio.h>

//定义一个联合
union data {
        int a;
        double b;
};

int main(void)
{
        //声明联合
        union data a = {88};            //初始化联合成员
        union data b = {.b = 55.5};     //使用初始化器初始化元素 b
        union data c;

        //查看数据
        printf("union a: \n");
        printf("a = %d, b = %.2f\n", a.a, a.b);

        printf("union b: \n");
        printf("a = %d, b = %.2f\n", b.a, b.b);

        printf("union c: \n");
        c.a = 1;
        printf("before set b, a = %d, b = %.2f \n", c.a, c.b);
        c.b = 2;
        printf("after set b, a = %d, b = %.2f \n", c.a, c.b);

        //查看联合大小
    	printf("--------------------------------\n");
        printf("size of union: %zd\n", sizeof(union data));

        return 0;
}
/*运行结果
union a: 
a = 88, b = 0.00
union b: 
a = 0, b = 55.50
union c: 
before set b, a = 1, b = 0.00 
after set b, a = 0, b = 2.00 
--------------------------------
size of union: 8
*/

The results:

The results meet the definition of joint can only store a variable, the other variable is the default. Joint space occupied the largest space is occupied by a data type.

Third, the enumeration (enum)

You can declare symbolic names enumeration type (enmuerated type) to represent the integer constant. Enumerated type aims to improve readability.

Example:

#include <stdio.h>

enum spectrum { red, orange, yellow, green, blue, violet};
int main(void)
{
        enum spectrum color;
		
    	//查看枚举的值
        printf("red = %d, orange = %d, yellow = %d, green = %d, blue = %d, violet = %d\n", red, orange, yellow, green, blue, violet);

        color = 1;      //使用整形常量给 color 赋值
        switch(color)
        {
                case 0: printf("I'm red\n");
                        break;
                case orange: printf("I'm orange\n");    //使用枚举来接受整形常量
                             break;

                default: printf("I'm others");
                         break;
        }

        return 0;
}
/*运行结果
red = 0, orange = 1, yellow = 2, green = 3, blue = 4, violet = 5
I'm orange
*/

Fourth, the function pointer

Address common variables, function also has an address. Pointer to a function in the function code stored in the start address, the main use is to function pointer as a parameter to a function of another function.

Statement as function pointer as a function declaration, but also specify a name, arguments, return type value.

​ 例:void (*pf) (char *)

Example 1:

/*练习声明、使用函数指针*/
#include <stdio.h>

void (*pf) (char *); //声明一个函数指针
void show(char *);      //声明一个函数,用函数指针指向它

int main(void)
{
        pf = show;

        //ANSI 认为这两种方法等价
        pf("I'm 'pf'");
        (*pf)("I'm '*pf'");

        return 0;
}

void show(char * str)
{
        printf("%s\n", str);

        return;
}
/*运行结果
I'm 'pf'
I'm '*pf'
*/

Example 2:

#include <stdio.h>

void (*pf) (char *); //声明一个函数指针
void show(char *);      //声明一个函数,用函数指针指向它
void usePf (void (*pf)(char *), char *, int choice);    //声明一个函数,它的参数是一个函数参数为 char* 的函数指针、一个 char* 、一个 int 值

int main(void)
{
        pf = show;
        int choice;
        char str[20];

        //写一个死循环接受用户选择,当输入的不是数字则停止
        printf("enter your choice: ");
        while(scanf("%d", &choice) == 1)
        {
                printf("enter a string: ");
                scanf("%s", str);

                usePf(pf, str, choice);         //调用 usePf
                printf("enter your choice: ");
        }


        return 0;
}

void show(char * str)
{
        printf("%s\n", str);

        return;
}

void usePf(void (*pf)(char *), char * str, int choice)
{
        switch(choice)
        {
                case 1: printf("No.1, ");
                        break;

                case 2: printf("No.2, ");
                        break;

                case 3: printf("No.3, ");
                        break;
        }

        pf(str);        //使用函数指针来调用 show 函数
}
/*运行结果
enter your choice: 1
enter a string: hello
No.1, hello
enter your choice: 2
enter a string: chi
No.2, chi
enter your choice: 3
enter a string: hh
No.3, hh
*/

Reference books

C Primer Plus (sixth edition) Chinese version

Published 42 original articles · won praise 3 · Views 2083

Guess you like

Origin blog.csdn.net/stable_zl/article/details/104147986