Linux C语言高级学习第七天(结构体)

结构体struct

1.声明结构体

struct 结构体名

{    

    成员表列;

};

#include<stdio.h>
struct data
{
    int year;
    int month;
    int day;
};                        //一定记得这个 ;分号

在声明结构体时,允许嵌套结构体(上文声明过的结构体)

#include<stdio.h>
struct data
{
    int year;
    int month;
    int day;
};
struct student
{
    int num;
    char name[16];
    char sex;
    struct data days;            //结构体嵌套结构体
    float score;
};

使用时必须要有struct跟在前面

int main()
{
    struct student stu1,stu2;
    return 0;
}

※结构体占内存大小

1.地址对齐数

在分配内存时,一次划分多少个字节

char        1

short       2

int           4

float        4

double    4(32位)    8(64位);;测试发现:二者都是8,有待探讨

在结构体成员分配内存时,地址对齐数一旦上升就不会下降

2.基准点+偏移量

基准点:结构体首地址

偏移量:基于基准点向后偏移多少字节

最终的结构体占用内存大小需要符合以下两点:

              条件1、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)。

    条件2、结构体大小必须是最大内存地址对齐数的大小的整数倍。

#include<stdio.h>
struct A
{
    int a;
    char b;
    int c;
};
struct B
{
    char a;
    int b;
    char c;
};
struct C
{
    char a;
    char b;
    int c;
};
struct D
{
    char a;
    int b;
    char c;
    short d;
};
struct E
{
    short a;
    short b;
    char c;
    char d;
};
int main()
{
    printf("The A is %d\n",sizeof(struct A));
    printf("The B is %d\n",sizeof(struct B));
    printf("The C is %d\n",sizeof(struct C));
    printf("The D is %d\n",sizeof(struct D));
    printf("The E is %d\n",sizeof(struct E));
    return 0;
}

2.定义结构体

1.先声明再定义:struct 关键字在结构体时不可省略

2.在声明结构体时直接定义

#include<stdio.h>
struct student
{
    char sex;
    int num;
    int score;
    char name[16];
}stu2;
int main()
{
    struct student stu3;
    return 0;
}

3.声明结构体过程中,省略结构体名,然后直接定义

struct
{
    char sex;
    int num;
    int score;
    char name[16];
}stu1;

在Jave这个叫匿名内部类

.    :直接引用结构体成员运算符

如果两个结构体变量类型完全相同,结构体变量允许直接赋值

#include<stdio.h>
#include<string.h>
struct student
{
    int num;
    char name[16];
    char sex;
};
int main()
{
    struct student stu1,stu2;
    stu1.num = 10101;
    strcpy(stu1.name,"Jiang Tiancai");
    stu1.sex = 'm';
    stu2 = stu1;        //直接赋值
    printf("stu2.num is %d\n",stu2.num);
    printf("stu2.name is %s\n",stu2.name);
    printf("stu2.sex is %c\n",stu2.sex);
    return 0;
}

结构体初始化

struct student stu3={10102,"Yang Gunian",'f'};
printf("stu3.num is %d\n",stu3.num);
printf("stu3.name is %s\n",stu3.name);
printf("stu3.sex is %c\n",stu3.sex);

如果出现嵌套结构体,那么必须寻找(. . .)最里面的成员才可以进行操作

3.结构体数组

一个数组里面全都是结构体

#include<stdio.h>
#include<string.h>
struct student
{
    int num;
    char name[16];
    char sex;
};
int main()
{
    struct student stu[3]={
        10101,"Jiang Tiancai",'m',
        10102,"Yang Guniang",'f',
        10103,"Jiang Shuaige",'m'
    };
    int i;
    for(i = 0; i<3; i++)
    {
        printf("第%d个人的信息:\n",i+1);
        printf("The stu[%d] num is %d\n",i,stu[i].num);
        printf("The stu[%d] name is %s\n",i,stu[i].name);
        printf("The stu[%d] sex is %c\n",i,stu[i].sex);
        printf("\n");
    }
    return 0;
}

例题:有三个候选人,有10个选民进行投票,每个选民只能投票给一个人,要求编写一个统计选票的程序,先后输入被选人的姓名,最后输出每个人的选票结果。

#include<stdio.h>
#include<string.h>
struct piao        //定义结构体变量
{
    char name[16];
    int cc;
};
int main()
{
    struct piao Bxr[4]={
        [0]={"Jiang",0},
        [1]={"Yang",0},
        [2]={"Liu",0},
        [3]={"Wang",0}
};
    char name[16];
    int i,j;
    int x;
    printf("请输入有多少选民:");
    scanf("%d",&x);
    for(i = 0; i<x;i++)
    {
        printf("备选人有:Jiang;Yang;Liu;Wang\n");
        printf("你是选民%d你的选择是:",i+1);
        scanf("%s",name);
        for(j = 0; j<4; j++)
        {
            if(strcmp(name,Bxr[j].name)==0)            //输入的数据与结构体数组的数据进行比较
            {
                Bxr[j].cc++;
                break;
            }
        }
        if(j>=4)            //错误相应机制
        {
            printf("输入错误请重新输入");
            i--;            //通过 i-- 让循环停留在这次(相当于这次循环没有做)
        }
    }
    printf("结果是:Jiang\tYang\tLiu\tWang\t\n");
    printf("选票为:");
    for(j = 0; j<4; j++)
    {
        printf("%d\t",Bxr[j].cc);
    }
    printf("\n");
    return 0;
}

例题:有五个人学生的成绩信息如下:

        1011,"jiang",100,

        1013,"li",78,

        1012,"Yang",99,

        1015,"Hu",89,

        1014,"Liu",95       先按照学号从小到大输出,再按照分数从大到小输出(使用冒泡排序)

#include<stdio.h>
struct student
{
    int num;
    char name[24];
    float score;
};
void print(struct student stu[],int len)        //输出函数
{
    int i;
    printf("学号\t姓名\t成绩\n");
    for(i = 0; i<len; i++)
    {
        printf("%d\t%s\t%.2f\n",stu[i].num,stu[i].name,stu[i].score);
    }
}
void bubble_num(struct student stu[],int len)        //按照学号从小到大排序
{
    int i,j;
    struct student tmp;            //交换时不能只交换学号,而是要交换整个学生的信息
    for(i = 0; i<len; i++)        //冒泡排序
    {
        for(j = 0; j<len-i-1; j++)
        {
            if(stu[j].num>stu[j+1].num)
            {
                tmp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tmp;
            }
        }
    }
}
void bubble_sc(struct student stu[],int len)        //按照成绩从大到小排序
{
    int i,j;
    struct student tmp;
    for(i = 0; i<len; i++)
    {
        for(j = 0; j<len-i-1; j++)
        {
            if(stu[j].score<stu[j+1].score)
            {
                tmp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tmp;
            }
        }
    }
}
int main()
{                                       //对结构体数组的初始化
    struct student stu[]={
        1011,"jiang",100,
        1013,"li",78,
        1012,"Yang",99,
        1015,"Hu",89,
        1014,"Liu",95
    };
    int len = sizeof(stu)/sizeof(stu[0]);            //计算数组的长度-->可以说是有几个结构体
    bubble_num(stu,len);
    print(stu,len);
    printf("--------------------我是分隔符----------------------\n");
    bubble_sc(stu,len);
    print(stu,len);
    return 0;
}

4.结构体指针

直接引用结构体成员运算符

struct student stu1;
struct student *p;
p = &stu1;
(*p).number = 10101;

间接引用结构体成员运算符(语法糖)

(*p).number    <-->    p->number

结构体指针与malloc()应用

可以创建一种,一次创建一个结构体,不会出现空间多余或缺少的情况

二者可以结合构成链表(数据结构详细说明)

用户重命名数据类型

typedef

typedef 旧类型 新类型

typedef unsigned int uint32

uint32 a,b,c; <==> unsigned int a,b,c;

函数指针的重命名方法

Linux C语言高级学习第七天(结构体)

猜你喜欢

转载自blog.csdn.net/nan_lei/article/details/81208004