C语言结构体和其他数据形式(C Primer Plus 第六版)

420 阅读6分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

这节会学到->运算符和struct结构 学完这些,再去学数据结构就很简单了! 加油!

资源在这

Screenshot_20211001_171431_com.tencent.mm.jpg

一、主要内容

关键字:struct、union、typedef

运算符:. ->

什么是C结构,如何创建结构模板和结构变量

如何访问结构的成员,如何编写处理结构的函数

联合和指向函数的指针

二、生活中的实例

书店老板要去打印一份图书目录。她想打印每本书的各种信息,如作者,书名,出版社、价格等等,这些项目可以存放在不同的数组中,可是用这么多数组表示有点麻烦和繁琐了,因此如果能把图书目录的信息都包含在一个数组里更好,其中每个元素包含一个本书的相关信息

C结构就能满足这个需求

实例

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

char * s_gets(char * st,int n);

#define MAXTITL 41  /*书名的最大长度+1*/
#define MAXAUTL 31  /*作者姓名的最大长度*/

struct book {   //结构模板:标记是book
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};              //结构模板结束

int main(void)
{
    struct book library;   //把library声明为一个book类型的变量

    printf("Please enter the book title.\n");
    s_gets(library.title,MAXTITL);  //访问title部分
    printf("Now enter the author.\n");
    s_gets(library.author,MAXAUTL);
    printf("Now enter the value.\n");
    scanf("%f",&library.value);
    printf("%s by %s: $%.2f\n",library.title,library.author,library.value);
    printf("%s: \"%s\" ($%.2f)\n",library.author,library.title,library.value);
    printf("Done.\n");

}

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');
        if (find)
        
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    return ret_val;    
}


输出的结果为:
PS D:\Code\C\结构> cd "d:\Code\C\结构\" ; if ($?) { gcc struct.c -o struct } ;
 if ($?) { .\struct }
Please enter the book title.
Now enter the author.
罗贯中
Now enter the value.
99.9
三国演义 by 罗贯中: $99.90
罗贯中: "三国演义" ($99.90)
Done.

程序中创建的结构有3部分,每个部分都称为成员(member))或字段(field)。这3部分中,一部分储存书名,一部分储存作者名,一部分储存价格。下面是必须掌握的3个技巧:

  • 为结构建立一个格式或样式;
  • 声明一个适合该样式的变量;
  • 访问结构变量的各个部分。

三、建立结构声明

结构声明(structure declaration)描述了一个结构的组织布局。声明类似下面这样:

struct book {   //结构模板:标记是book
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
}; 

​ 该声明描述了一个由两个字符数组和一个float类型变量组成的结构。该声明并未创建实际的数据对象,只描述了该对象由什么组成。(有时,我们把结构声明称为模板,因为它勾勒出结构是如何储存数据的.如果读者知道C++的模板,此模板非彼模板,C++中的模板更为强大。)我们来分析一些细节。首先是关键字struct,它表明跟在其后的是一个结构,后面是一个可选的标记(该例中是 book),稍后程序中可以使用该标记引用该结构。所以,我们在后面的程序中可以这样声明: ​ struct book library; 这把library声明为一个使用book 结构布局的结构变量。

四、定义结构变量

​ 结构有两层含义。一层含义是“结构布局”,刚才已经讨论过了。结构布局告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。下一步是创建一个结构变量,即是结构的另一层含义。程序中创建结构变量的一行是: ​ struct book library; ​ 编译器执行这行代码便创建了一个结构变量library。编译器使用book模板为该变量分配空间:个内含MAXTITL个元素的char数组、一个内含MAXAUTL个元素的char数组和一个float类型的变量。这些存储空间都与一个名称library结合在一起 ​ 在结构变量的声明中,**struct book所起的作用相当于一般声明中的int或float。**例如,可以定义两个struct book类型的变量,或者甚至是指向struct book类型结构的指针: ​ struct book doyle, panshin, * ptbook;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nI9ueNJZ-1634262932337)(E:\Typora\Image\image-20211014180105069.png)]

结构变量 doyle和 panshin中都包含title、author和 value部分。指针 ptbook可以指向doyle,panshin或任何其他book类型的结构变量。从本质上看, book结构声明创建了一个名为structbook的新类型。 就计算机而言,下面的声明:

​ struct book library;

​ 是以下声明的简化:

​ struct book { ​ char title [ MAXTITL];

​ char author [AXA0TL];

​ float value; ​ }library; //声明的右右花括号后跟变量名

换言之,声明结构的过程和定义结构变量的过程可以组合成一个步骤。如下所示,组合后的结构声明和结构变量定义不需要使用结构标记: struct { //无结构标记 char title [ MAXTITL];

​ char author [ MAXAUTL];

​ float value; ​ } library; 然而,如果打算多次使用结构模板,就要使用带标记的形式;在这个例子中,并未初始化结构变量。

4.1 初始化结构

初始化变量和数组如下:

int count = 0 ;

int fibo [ 7] = {0,1,1,2,3,5,8 };

​ 结构变量是否也可以这样初始化?是的,可以。初始化一个结构变量(ANSI之前,不能用自动变量初始化结构:ANSI之后可以用任意存储类别)与初始化数组的语法类似

​ 简而言之,我们使用在一对花括号中括起来的初始化列表进行初始化,各初始化项用逗号分隔 因此,**title成员可以被初始化为一个字符串,value 成员可以被初始化为一个数字。**为了让初始化项与结构中各成员的关联更加明显,我们让每个成员的初始化项独占一行。这样做只是为了提高代码的可读性,对编译器而言,只需要用逗号分隔各成员的初始化项即可。

不是我说,这本书写的真好!

4.2 访问结构成员

结构类似于一个“超级数组”,这个超级数组中,可以是一个元素为char类型,下一个元素为forat类型,下一个元素为int 数组。可以通过数组下标单独访问数组中的各元素,那么,如何访问结构中的成员﹖使用结构成员运算符——一点( .)访问结构中的成员。例如,library.value即访问library的value部分。可以像使用任何float类型变量那样使用library.value。与此类似,可以像使用字符数组那样使用library.title。因此,上面的程序中有 s_gets(library.title,MAXTITL);和scanf(""号f",&library.value);这样的代码。

C语言不亏是基础,如果首先学会C语言,学面向对象这种访问方式应该更好理解了!

学过其他语言应该会很好理解,就像Java中访问类中的方法也是类名.方法名()