← 返回首页
C语言基础(五)
发表时间:2024-05-21 04:11:27
结构体/结构体对象/结构体指针/综合案例

结构体

1.如何定义结构体

struct 结构体名{
     成员属性1;
     成员属性2;
     成员属性3;
};
#include <stdio.h>
//1.定义一个日期的结构体
struct date
{
    int year;
    int month;
    int day;
};

//定义一个日期的结构体 strut date
//1,定义一个结构体数据类型
struct student
{
    char name[20];  //姓名
    int height;     //身高
    struct date birDay; //出生日期
};


2.如何定义结构体变量并访问成员

#include <stdio.h>

//定义一个日期的结构体 strut date
//1,定义一个结构体数据类型
struct student
{
    char name[20];  //姓名
    int height;     //身高
};

//定义一个结构体数据类型,该数据类型的名字叫struct student
int main(void)
{
    //2.定义一个结构体变量  类型名  变量名
    struct student s1={"zhangsan",176};

    //3.结构体变量访问成员  变量名.成员名
    printf("请输入姓名和身高\n");
    scanf("%s",s1.name);
    scanf("%d",&s1.height);
    printf("s1:   name:%s height=%d\n",s1.name,s1.height);


    //4.定义一个结构体变量
    struct student s2;
    s2=s1; //将s1中的值赋值给s2

    printf("s2:   name:%s height=%d\n",s2.name,s2.height);
    return 0;
}

3.如何定义结构体指针并访问

#include <stdio.h>

//1.在定义结构体数据类型的同时给它取别名

typedef struct student
{
    char name[20];
    int height;
}Stu;

//该结构体数据类型的名字叫Stu
int main(void)
{
    //2.定义一个结构体变量并赋值
    //类型名  变量名
    Stu s1={"zhangsan",178};

    printf("name:%s height=%d\n",s1.name,s1.height);

    //定义一个指向int的指针
    int * pi=NULL;       //sizeof(pi)=8
    //3.定义一个指向结构体的指针
    Stu * ps=NULL;       //sizeof(ps)=8

    ps=&s1; //ps指向s1   s1<===>*ps
    printf("name:%s height=%d\n",(*ps).name,(*ps).height);

    printf("name:%s height=%d\n",ps->name,ps->height);

    return 0;
}

4.结构体指针和动态空间

#include <stdlib.h>
void *malloc(size_t size);
#include <stdio.h>
#include <stdlib.h>

//1.定义一个结构体数据类型,并取别名
typedef struct student
{
    char name[20];
    int height;
}Stu;
//2.编写一子函数,对ps指向的空间输入数据
//参数1:空间的首地址  Stu * ps
//参数2:元素的个数    int size
void input(Stu * ps,int size);
void input(Stu * ps,int size)
{
    int i=0;
    for(i=0;i<size;i++)
    {

        printf("请输入姓名和身高\n");
        scanf("%s%d",ps->name,&ps->height);
        ps++;
    }
}


//3.编写一子函数,对ps和指向的空间输出数据
//参数1:空间的首地址  Stu * ps
//参数2:元素的个数    int size
void output(Stu * ps,int size);
void output(Stu * ps,int size)
{
    int i=0;
    for(i=0;i<size;i++)
    {
        printf("name:%-20s height:%d\n",ps->name,ps->height);
        ps++;
    }
}
int main(void)
{
    int op=0;
    //1.在堆区分配5个存结构体的空间
    Stu * ps=NULL;
    ps=(Stu *)malloc(sizeof(Stu)*5);
    free(ps);
    ps=NULL;
}

5.结构体占用空间计算

结构体的对齐方式确实很浪费空间,可是按照计算机的访问机制,这种对齐方式大大提升了计算机的访问效率。

从结构体的第一个成员向下开始计算,并遵循以下原则: 1. 前面所有成员所占地址空间的大小必须是其后一个成员占地址空间大小的整数倍。(0是任何数的整数倍,或第一个成员除外) 2. 结构体的大小必须是结构体里面各个成员(数组除外;结构中包含结构体,且被包含的结构体只声明,没有定义结构体变量除外;结构体中包含联合体,且联合体只声明,没有定义联合体变量除外)大小的整数倍。

实例:

#include <stdio.h>

typedef struct A {
   double a; //8
   short b; //2
   int c; //4
   char d;//1
} obj;

int main(){
   printf("size of obj is :%ld\n",sizeof(obj));
   return 0;
}

运行结果:

size of obj is :24

注意:结构体的长度计算与成员的定义顺序也有很大的关系,上面代码改写如下:

#include <stdio.h>

typedef struct A {
   double a; //8
   int c; //4
   short b; //2
   char d;//1
} obj;

int main(){
   printf("size of obj is :%ld\n",sizeof(obj));
   return 0;
}

运行结果:

size of obj is :16

6.综合案例

实现一个学生身高排名案例。

代码如下:

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

// 定义一个结构体数据类型,并取别名
typedef struct student
{
    char name[20];
    int height;
} Stu;

// 1. 完成下面菜单
void menu(void);

// 2.编写一子函数,对ps指向的空间输入数据
// 参数1:空间的首地址  Stu * ps
// 参数2:元素的个数    int size
void input(Stu *ps, int size);

// 3.编写一子函数,对ps和指向的空间输出数据
// 参数1:空间的首地址  Stu * ps
// 参数2:元素的个数    int size
void output(Stu *ps, int size);

// 编写一子函数,获得ps指向的空间中身高最高的那个人的首地址
// 参数1:空间的首地址   Stu * ps
// 参数2:元素的个数     int size
// 返回值:身高最高的那个人的首地址  Stu *
Stu *calpMax(Stu *ps, int size);

// 编写一子函数,获得ps指向的空间中身高最矮的那个人的首地址
// 参数1:空间的首地址   Stu * ps
// 参数2:元素的个数     int size
// 返回值:身高最矮的那个人的首地址  Stu *
Stu *calpMin(Stu *ps, int size);

// 编写一子函数,交换两个人的位置
// 参数1:第一个人的首地址   参数2:第二个人的首地址
// 返回值:void
void swap(Stu *pMax, Stu *pMin);

// 编写一子函数,按照身高进行排序
// 参数1:空间的首地址  Stu * ps
// 参数2:元素的个数    int size
// 返回值:void
void sortByHeight(Stu *ps, int size);

int main(void)
{
    int op = 0;
    // 1.在堆区分配5个存结构体的空间
    Stu *ps = NULL;
    ps = (Stu *)malloc(sizeof(Stu) * 5);
    Stu *pMax = NULL;
    Stu *pMin = NULL;

    while (1)
    {
        menu();
        printf("请输入选项\n");
        scanf("%d", &op);
        if (-1 == op)
            break;
        switch (op)
        {
        case 1:
            input(ps, 5);
            break;
        case 2:
            output(ps, 5);
            break;
        case 3:
            pMax = calpMax(ps, 5);
            printf("身高最高是 %s %d\n", pMax->name, pMax->height);
            break;
        case 4:
            pMin = calpMin(ps, 5);
            printf("身高最矮是 %s %d\n", pMin->name, pMin->height);
            break;
        case 5:
            sortByHeight(ps, 5);
            break;

        }
    }
    // 2.释放
    free(ps);
    ps = NULL;
    return 0;
}

void menu(void)
{
    printf("1-----input\n");
    printf("2-----output\n");
    printf("3-----calpMax\n");         // 求身高最高的人的首地址
    printf("4-----calpMin\n");         // 求身高最低的人的首地址
    printf("5-----sortByHeight\n");
    printf("-1----exit\n");
}

void input(Stu *ps, int size)
{
    int i = 0;
    for (i = 0; i < size; i++)
    {

        printf("请输入姓名和身高\n");
        scanf("%s%d", ps->name, &ps->height);
        ps++;
    }
}

void output(Stu *ps, int size)
{
    int i = 0;
    for (i = 0; i < size; i++)
    {
        printf("name:%-20s height:%d\n", ps->name, ps->height);
        ps++;
    }
}

Stu *calpMax(Stu *ps, int size)
{
    // 1.定义一个指针变量,用它来保存最大值的地址
    Stu *pMax = NULL;

    // 2.假设第一个为最大
    pMax = ps;

    // 3.用pMax->height和后面的每一个height进行比较,循环size-1次
    int i = 0;
    for (i = 0; i < size - 1; i++)
    {
        ps++;
        if (pMax->height < ps->height)
        {
            pMax = ps;
        }
    }
    // 4.返回pMax;
    return pMax;
}

Stu *calpMin(Stu *ps, int size)
{
    // 1.定义一个指针变量,用它来保存最大值的地址
    Stu *pMin = NULL;

    // 2.假设第一个为最矮
    pMin = ps;

    // 3.用pMax->height和后面的每一个height进行比较,循环size-1次
    int i = 0;
    for (i = 0; i < size - 1; i++)
    {
        ps++;
        if (pMin->height > ps->height)
        {
            pMin = ps;
        }
    }
    // 4.返回pMin;
    return pMin;
}

void swap(Stu *pMax, Stu *pMin)
{
    Stu tmp;
    tmp = *pMax;
    *pMax = *pMin;
    *pMin = tmp;
}

void sortByHeight(Stu *ps, int size)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < size - 1; i++)
    {
        for (j = 0; j < size - 1 - i; j++)
        {
            if ((ps + j)->height > (ps + j + 1)->height)
            {
                // 交换ps+j    ps+j+1 这两个人的位置
                swap(ps + j, ps + j + 1);
            }
        }
    }
    printf("sort over\n");
}