C语言学习-结构体

  结构体是用来存放一组不同类型数据的数据类型。

结构体的定义和使用

##结构体的定义
结构体的定义方式为:

struct 结构体名
{
结构体所包含的变量或数组
};

举个栗子:

struct stu
{
    char name[100];  //姓名
    int num;  //学号
};

为什么要使用结构体

那么为什么我们要学习结构体呢?因为之前学习的数组只能存放一组相同类型的数据,如果想要存放不同类型的数据,就需要使用结构体了。例如对于学生成绩管理系统,我们需要字符串类型的姓名,整型的年龄以及浮点型的成绩,请看下面的一个例子:

struct Student
{
    char name[100];
    int age;
    float score;
}; //分号不能少

Student为结构体名,它包含了 3 个成员,分别是 name、age、score。结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化。

结构体变量

既然结构体是一种数据类型,那么就可以用它来定义变量。例如:

struct Student stu1, stu2;

这里定义了两个变量 stu1 和 stu2,它们都是 stu 类型,都由 3 个成员组成。注意关键字struct不能少。

也可以在定义结构体的同时定义结构体变量:

struct stu
{
    char name[100];  
    int age;
    float score;
} stu1, stu2;

如果只需要 stu1、stu2 两个变量,后面不需要再使用结构体名定义其他变量,那么在定义时也可以不给出结构体名,如下所示:

struct //没有写 stu
{
    char name[100];  
    int age;
    float score;
} stu1, stu2;

但以上两种写法都不推荐,因为使用起来不够灵活。

成员的获取和赋值

结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。数组使用下标[ ]获取单个元素,结构体使用点号.获取单个成员。获取结构体成员的一般格式为:

结构体变量名.成员名;

通过这种方式可以获取成员的值,也可以给成员赋值:

# include <stdio.h>

struct Student
{
    char name;
    int age;
}; //要有分号

int main(void)
{
    struct Student stu1;
    stu1.name = "Tom";
    stu1.age = 18;

    printf("%c %d\n", stu1.name, stu1.age);

    return 0;
}

也可以在声明时直接赋值,例如:

struct Student stu1 = {'a', 18};

我们也可以定义一个Student类型的指针变量,然后通过变量名->成员的方式赋值,例如:

struct Student * pStu1 = &stu1;
pStu1->name = 'Jerry';
pStu1->age = 20;

结构体使用实例——学生成绩排名系统

# include <stdio.h>
# include <malloc.h>

struct Student
{
    char name[100];
    int age;
    int score;
};

void Stu_in(struct Student * pArr, int len)
{
    int i;
    for(i=0;i<len;i++)
    {    
        printf("请输入第%d个学生的信息:\n", i+1);
        printf("name:");
        scanf("%s", pArr[i].name);
        printf("age:");
        scanf("%d", &pArr[i].age);
        printf("score:");
        scanf("%d", &pArr[i].score);    
        printf("\n");
    }
}

void Stu_out(struct Student * pArr, int len)
{
    int i;
    for(i=0;i<len;i++)
    {
        printf("第%d名为:\n", i+1);
        printf("name:%s\n", pArr[i].name);
        printf("age:%d岁\n", pArr[i].age);
        printf("score:%d分\n", pArr[i].score);    
        printf("\n");
    }
}

void exchange(struct Student * a, struct Student * b)
{
    struct Student c;
    c = *a;
    *a = *b;
    *b = c;
}

void sort(struct Student * pArr, int len)
{
    int i;
    int    left = 0;
    int right = len-1;
    while(left < right)
    {
        int flag = 0;
        for(i=left;i<right;i++)
        {
            if(pArr[i].score < pArr[i+1].score)
            {
                exchange(&pArr[i], &pArr[i+1]);
                flag = 1;
            }
        }
        if(flag == 0)
        {
            break;
        }
        right--;
        flag = 0;

        for(i=right;i>left;i--)
        {
            if(pArr[i-1].score < pArr[i].score)
            {
                exchange(&pArr[i-1], &pArr[i]);
                flag = 1;
            }
        }
        if(flag == 0)
        {
            break;
        }
        left++;
    }
}

int main(void)
{
    int amount;
    struct Student * pArr;
    printf("请输入您想要添加的学生的数量:");
    scanf("%d", &amount);
    pArr = (struct Student *)malloc(amount * sizeof(struct Student));

    printf("\n");
    printf("---------输入数据---------\n");
    Stu_in(pArr, amount); //输入学生的相关信息

    sort(pArr, amount); //使用鸡尾酒排序进行排序

    printf("\n");
    printf("---------学生排名---------\n");
    Stu_out(pArr, amount); //输出排名后的学生信息

    return 0;
}

关于结构体的内存分配

理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似。但是在编译器的具体实现中,各个成员之间可能会存在缝隙,可能会造成一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。关于这个问题,我将会在《结构体中的内存对齐问题》中详细讲解。

坚持原创技术分享,您的支持将鼓励我继续创作!