C语言程序设计-11 结构体与共用体

11.1 定义一个结构的一般形式

11.2 结构类型变量的说明

1. 先定义结构,再说明结构变量。

2. 在定义结构类型的同时说明结构变量。

3. 直接说明结构变量。

11.3 结构变量成员的表示方法

11.4 结构变量的赋值

结构变量的赋值就是给各成员赋值。可用输入语句或赋值语句来完成。
【例 11.1】给结构变量赋值并输出其值。

c 复制代码
#include <math.h>
#include <stdio.h>

void main()
{
    struct stu
    {
        int num;
        char *name;
        char sex;
        float score;
    } boy1, boy2;
    boy1.num = 102;
    boy1.name = "Zhang ping";
    printf("input sex and score\n");
    scanf("%c %f", &boy1.sex, &boy1.score);
    boy2 = boy1;
    printf("Number=%d\nName=%s\n", boy2.num, boy2.name);
    printf("Sex=%c\nScore=%f\n", boy2.sex, boy2.score);
    
}

本程序中用赋值语句给 num 和 name 两个成员赋值,name 是一个字符串指针变量。用 scanf

函数动态地输入 sex 和 score 成员值,然后把 boy1 的所有成员的值整体赋予 boy2。最后分

别输出 boy2 的各个成员值。本例表示了结构变量的赋值、输入和输出的方法。

11.5 结构变量的初始化

和其他类型变量一样,对结构变量可以在定义时进行初始化赋值。
【例 11.2】对结构变量初始化。

c 复制代码
#include <math.h>
#include <stdio.h>

void main()
{
    struct stu /*定义结构*/
    {
        int num;
        char *name;
        char sex;
        float score;
    } boy2, boy1 = {102, "Zhang ping", 'M', 78.5};
    boy2 = boy1;
    printf("Number=%d\nName=%s\n", boy2.num, boy2.name);
    printf("Sex=%c\nScore=%f\n", boy2.sex, boy2.score);
}

本例中,boy2,boy1 均被定义为外部结构变量,并对 boy1 作了初始化赋值。在 main 函

数中,把 boy1 的值整体赋予 boy2,然后用两个 printf 语句输出 boy2 各成员的值。

11.6 结构数组的定义

【例 11.3】计算学生的平均成绩和不及格的人数。

c 复制代码
#include <math.h>
#include <stdio.h>

struct stu
{
    int num;
    char *name;
    char sex;
    float score;
} boy[5] = {
    {101, "Li ping", 'M', 45},
    {102, "Zhang ping", 'M', 62.5},
    {103, "He fang", 'F', 92.5},
    {104, "Cheng ling", 'F', 87},
    {105, "Wang ming", 'M', 58},
};
void main()
{
    int i, c = 0;
    float ave, s = 0;
    for (i = 0; i < 5; i++)
    {
        s += boy[i].score;
        if (boy[i].score < 60)
            c += 1;
    }
    printf("s=%f\n", s);
    ave = s / 5;
    printf("average=%f\ncount=%d\n", ave, c);
}

本例程序中定义了一个外部结构数组 boy,共 5 个元素,并作了初始化赋值。在 main 函

数中用 for 语句逐个累加各元素的 score 成员值存于 s 之中,如 score 的值小于 60(不及格)

即计数器 C 加 1,循环完毕后计算平均成绩,并输出全班总分,平均分及不及格人数。

【例 11.4】建立同学通讯录

c 复制代码
#include "stdio.h"
#define NUM 3


struct mem
{
    char name[20];
    char phone[10];
};
void main()
{
    struct mem man[NUM];
    int i;
    for (i = 0; i < NUM; i++)
    {
        printf("input name:\n");
        gets(man[i].name);
        printf("input phone:\n");
        gets(man[i].phone);
    }
    printf("name\t\t\tphone\n\n");
    for (i = 0; i < NUM; i++)
        printf("%s\t\t\t%s\n", man[i].name, man[i].phone);
}

本程序中定义了一个结构 mem,它有两个成员 name 和 phone 用来表示姓名和电话号码。

在主函数中定义 man 为具有 mem 类型的结构数组。在 for 语句中,用 gets 函数分别输入各

个元素中两个成员的值。然后又在 for 语句中用 printf 语句输出各元素中两个成员值。

11.7 结构指针变量的说明和使用

11.7.1 指向结构变量的指针

下面通过例子来说明结构指针变量的具体说明和使用方法。
【例 11.5】

c 复制代码
#include "stdio.h"
#define NUM 3

struct stu
{
    int num;
    char *name;
    char sex;
    float score;
} boy1 = {102, "Zhang ping", 'M', 78.5}, *pstu;
main()
{
    pstu = &boy1;
    printf("Number=%d\nName=%s\n", boy1.num, boy1.name);
    printf("Sex=%c\nScore=%f\n\n", boy1.sex, boy1.score);
    printf("Number=%d\nName=%s\n", (*pstu).num, (*pstu).name);
    printf("Sex=%c\nScore=%f\n\n", (*pstu).sex, (*pstu).score);
    printf("Number=%d\nName=%s\n", pstu->num, pstu->name);
    printf("Sex=%c\nScore=%f\n\n", pstu->sex, pstu->score);
}

本例程序定义了一个结构 stu,定义了 stu 类型结构变量 boy1 并作了初始化赋值,还定

义了一个指向 stu 类型结构的指针变量 pstu。在 main 函数中,pstu 被赋予 boy1 的地址,因

此 pstu 指向 boy1。然后在 printf 语句内用三种形式输出 boy1 的各个成员值。从运行结果

可以看出:

结构变量.成员名

(*结构指针变量).成员名

结构指针变量->成员名

这三种用于表示结构成员的形式是完全等效的。

11.7.2 指向结构数组的指针

【例 11.6】用指针变量输出结构数组。

c 复制代码
#include "stdio.h"
#define NUM 3

struct stu
{
    int num;
    char *name;
    char sex;
    float score;
} boy[5] = {
    {101, "Zhou ping", 'M', 45},
    {102, "Zhang ping", 'M', 62.5},
    {103, "Liou fang", 'F', 92.5},
    {104, "Cheng ling", 'F', 87},
    {105, "Wang ming", 'M', 58},
};
main()
{
    struct stu *ps;
    printf("No\tName\t\t\tSex\tScore\t\n");
    for (ps = boy; ps < boy + 5; ps++)
        printf("%d\t%s\t\t%c\t%f\t\n", ps->num, ps->name, ps->sex, ps->score);
}

11.7.3 结构指针变量作函数参数

【例 11.7】计算一组学生的平均成绩和不及格人数。用结构指针变量作函数参数编程。

c 复制代码
#include "stdio.h"

struct stu
{
    int num;
    char *name;
    char sex;
    float score;
} boy[5] = {
    {101, "Li ping", 'M', 45},
    {102, "Zhang ping", 'M', 62.5},
    {103, "He fang", 'F', 92.5},
    {104, "Cheng ling", 'F', 87},
    {105, "Wang ming", 'M', 58},
};
main()
{
    struct stu *ps;
    void ave(struct stu * ps);
    ps = boy;
    ave(ps);
}
void ave(struct stu *ps)
{
    int c = 0, i;
    float ave, s = 0;
    for (i = 0; i < 5; i++, ps++)
    {
        s += ps->score;
        if (ps->score < 60)
            c += 1;
    }
    printf("s=%f\n", s);
    ave = s / 5;
    printf("average=%f\ncount=%d\n", ave, c);
}

本程序中定义了函数 ave,其形参为结构指针变量 ps。boy 被定义为外部结构数组,因

此在整个源程序中有效。在 main 函数中定义说明了结构指针变量 ps,并把 boy 的首地址赋

予它,使 ps 指向 boy 数组。然后以 ps 作实参调用函数 ave。在函数 ave 中完成计算平均成

绩和统计不及格人数的工作并输出结果。

由于本程序全部采用指针变量作运算和处理,故速度更快,程序效率更高。

11.8 动态存储分配

【例 11.8】分配一块区域,输入一个学生数据。

c 复制代码
#include "stdio.h"
#include <stdlib.h>

main()
{
    struct stu
    {
        int num;
        char *name;
        char sex;
        float score;
    } *ps;
    ps = (struct stu *)malloc(sizeof(struct stu));
    ps->num = 102;
    ps->name = "Zhang ping";
    ps->sex = 'M';
    ps->score = 62.5;
    printf("Number=%d\nName=%s\n", ps->num, ps->name);
    printf("Sex=%c\nScore=%f\n", ps->sex, ps->score);
    free(ps);
}

本例中,定义了结构 stu,定义了 stu 类型指针变量 ps。然后分配一块 stu 大内存区,

并把首地址赋予 ps,使 ps 指向该区域。再以 ps 为指向结构的指针变量对各成员赋值,并用

printf 输出各成员值。最后用 free 函数释放 ps 指向的内存空间。整个程序包含了申请内存

空间、使用内存空间、释放内存空间三个步骤,实现存储空间的动态分配。

11.9 链表的概念

【例 11.9】建立一个三个结点的链表,存放学生数据。为简单起见, 我们假定学生数据结
构中只有学号和年龄两项。可编写一个建立链表的函数 creat。程序如下:

c 复制代码
#include <stdio.h>
#include <stdlib.h>

#define NULL1 0
#define TYPE struct stu
#define LEN sizeof(struct stu)
struct stu
{
    int num;
    int age;
    struct stu *next;
};
TYPE *creat(int n)
{
    struct stu *head, *pf, *pb;
    int i;
    for (i = 0; i < n; i++)
    {
        pb = (TYPE *)malloc(LEN);
        printf("input Number and Age\n");
        scanf("%d%d", &pb->num, &pb->age);
        if (i == 0)
            pf = head = pb;
        else
            pf->next = pb;
        pb->next = NULL1;
        pf = pb;
    }
    return (head);
}

在函数外首先用宏定义对三个符号常量作了定义。这里用 TYPE 表示 struct stu,用 LEN

表示 sizeof(struct stu)主要的目的是为了在以下程序内减少书写并使阅读更加方便。结构

stu 定义为外部类型,程序中的各个函数均可使用该定义。

creat 函数用于建立一个有 n 个结点的链表,它是一个指针函数,它返回的指针指向 stu

结构。在 creat 函数内定义了三个 stu 结构的指针变量。head 为头指针,pf 为指向两相邻结

点的前一结点的指针变量。pb 为后一结点的指针变量。

11.10 枚举类型

11.10.1 枚举类型的定义和枚举变量的说明

11.10.2 枚举类型变量的赋值和使用

【例 11.10】

c 复制代码
#include <stdio.h>
#include <stdlib.h>

main()
{
    enum weekday
    {
        sun,
        mon,
        tue,
        wed,
        thu,
        fri,
        sat
    } a,
        b, c;
    a = sun;
    b = mon;
    c = tue;
    printf("%d,%d,%d", a, b, c);
}

【例 11.11】

c 复制代码
#include <stdio.h>
#include <stdlib.h>

main()
{
    enum body
    {
        a,
        b,
        c,
        d
    } month[31],
        j;
    int i;
    j = a;
    for (i = 1; i <= 30; i++)
    {
        month[i] = j;
        j++;
        if (j > d)
            j = a;
    }
    for (i = 1; i <= 30; i++)
    {
        switch (month[i])
        {
        case a:
            printf(" %2d %c\t", i, 'a');
            break;
        case b:
            printf(" %2d %c\t", i, 'b');
            break;
        case c:
            printf(" %2d %c\t", i, 'c');
            break;
        case d:
            printf(" %2d %c\t", i, 'd');
            break;
        default:
            break;
        }
    }
    printf("\n");
}

11.11 类型定义符 typedef

typedef 定义的一般形式为:

typedef 原类型名 新类型名

相关推荐
马浩同学29 分钟前
【GD32】从零开始学GD32单片机 | DAC数模转换器 + 三角波输出例程
c语言·单片机·嵌入式硬件·mcu
我要学编程(ಥ_ಥ)32 分钟前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
埃菲尔铁塔_CV算法34 分钟前
FTT变换Matlab代码解释及应用场景
算法
一个没有本领的人39 分钟前
win11+matlab2021a配置C-COT
c语言·开发语言·matlab·目标跟踪
一只自律的鸡1 小时前
C项目 天天酷跑(下篇)
c语言·开发语言
许野平1 小时前
Rust: enum 和 i32 的区别和互换
python·算法·rust·enum·i32
长安——归故李1 小时前
【C语言】成绩等级制
c语言·开发语言
chenziang11 小时前
leetcode hot100 合并区间
算法
chenziang11 小时前
leetcode hot100 对称二叉树
算法·leetcode·职场和发展
szuzhan.gy2 小时前
DS查找—二叉树平衡因子
数据结构·c++·算法