C-结构体

一、结构体类型的概念及定义


构造类型:
不是基本类型的数据结构也不是指针,它是若干个相同或不同类型的数据构成的集合
常用的构造类型有数组、结构体、共用体

  • 数组用于保存多个相同类型的数据
  • 结构体常用于保存多个不同类型的数据
#include <stdio.h>


// 注意:一般结构体类型都会定义在全局,也就是main函数的外面
// 所以在定义结构体类型的同时定义变量,这些变量一般都是全局变量
// 定义完类型之后定义的结构体变量,内存分配要看定义的位置在哪儿

struct stu{
    int num;
    char name[20];
    char sex;
}lucy, bob, lilei;

struct stu  xiaoming,xiaohong;

// 无名结构体由于没有结构体名,所以定义完之后是无法在定义结构体变量的,只能在定义类型的同时定义结构体变量
struct {
    int num;
    char name[20];
    char sex;
}lucy1, bob2, lilei3;


// 给结构体类型取别名
// 通常将一个结构体类型重新起个类型名,用新的类型名替代原先的类型
typedef struct stu1{
    int num;
    char name[20];
    char sex;
}STU1;

STU1 xiaoming11,xiaohong22;

int main()
{
    return 0;
}



二、结构体变量的定义初始化及使用

#include <stdio.h>

struct stu{
    int id;
    char name[32];
    char sex;
    int age;
};

typedef struct {
    int a;
    int b;
    char c;
}MSG;

int main()
{
    struct stu wangwu;
    struct stu wangwu1 = {1001, "wangwang", 'B', 20};

    MSG msg1, msg = {100, 200, 'w'};

    return 0;
}


结构体变量的使用

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

struct stu{
    int id;
    char name[32];
    char sex;
    int age;
} zhangsan;

int main()
{
    // 结构体变量的使用

    struct stu zhaoliu = {1001,"zhaoliu99",'B',20};

    zhangsan.id = 1001;

    // zhangsan.name = "zhangsan111";  // 错误用法  字符串常量的地址; 数组名是常量,不能赋值
    strcpy(zhangsan.name, "zhangsan111");

    zhangsan.sex = 'B';

    zhangsan.age = 18;

    printf("%d - %s - %c - %d\n", zhangsan.id, zhangsan.name, \
           zhangsan.sex, zhangsan.age);
    // 1001 - zhangsan111 - B - 18

    printf("%d - %s - %c - %d\n", zhaoliu.id, zhaoliu.name, \
           zhaoliu.sex, zhaoliu.age);
    return 0;
}



在结构体中嵌套结构体

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

typedef struct{
    int year;
    int month;
    int day;
}BD;

typedef struct{
    int id;
    char name[32];
    BD birthday;
}STU;

void test2()
{
    STU xiaoming;
    xiaoming.id = 1001;
    strcpy(xiaoming.name, "xiaoming66");

    xiaoming.birthday.year = 2002;
    xiaoming.birthday.month = 12;
    xiaoming.birthday.day = 20;

    printf("%d - %s - %d:%d:%d\n", xiaoming.id, xiaoming.name,\
           xiaoming.birthday.year, xiaoming.birthday.month, xiaoming.birthday.day);
    // 1001 - xiaoming66 - 2002:12:20
}

int main()
{
    test2();

    return 0;
}


结构体数组

结构体数组是个数组 ,由若干个相同类型的结构体变量构成的集合

#include <stdio.h>

typedef struct{
    int num;
    char name[20];
    float score;
}STU;

int main()
{
    // 定义一个结构体数组
    STU edu[3] = {
        {101,"Lucy",78},
        {102,"Bob",59.5},
        {103,"Tom",85}
    };

    int i;
    float sum = 0;
    for(i = 0; i<3; i++)
    {
        sum += edu[i].score;
    }

    printf("avg: %f\n", sum / 3);   // avg: 74.166667

    return 0;
}


结构体指针
结构体的地址,结构体变量存放内存中,也有起始地址
我们定义一个变量来存放这个地址,那这个变量就是结构体指针变量

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

struct stu{
    int id;
    char name[32];
    char sex;
    int age;
};

int main()
{
    // 定义一个结构体指针变量
    struct stu *s;
    // 在堆区开辟结构体空间并将其地址保存在结构体指针变量中
    s = (struct stu *) malloc(sizeof(struct stu));

    s->id = 1001;
    strcpy(s->name, "zhangsan555");
    s->sex = 'B';
    s->age = 20;

    printf("%d - %s - %c - %d\n", s->id, s->name, s->sex, s->age);
    // 1001 - zhangsan555 - B - 20

    return 0;
}


结构体内存分配问题

为什么要有字节对齐?
用空间来换时间,提高cpu读取数据的效率

#include <stdio.h>

struct stu{
    char a;
    short b;
    int c;
}temp;

struct stu1{
    char a;
    short b;
    short b1;
    int c;
}temp1;

int main()
{
    printf("%d\n", sizeof(temp));      // 8个字节
    printf("%p\n", &(temp.a));         // 00406430
    printf("%p\n", &(temp.b));         // 00406432
    printf("%p\n", &(temp.c));         // 00406434


    printf("%d\n", sizeof(temp1));      // 12个字节
    printf("%p\n", &(temp1.a));         // 00406424
    printf("%p\n", &(temp1.b));         // 00406426
    printf("%p\n", &(temp1.b1));         // 00406428
    printf("%p\n", &(temp1.c));         // 0040642C

    return 0;
}


#include <stdio.h>


// 注意看: 两个结构体short和int的位置不同
struct stu{
    char a;
    short b;
    int c;
}temp;

struct stu1{
    char a;
    int c;
    short b;
}temp1;

int main()
{
    printf("%d\n", sizeof(temp));      // 8
    printf("%p\n", &(temp.a));         // 00406430
    printf("%p\n", &(temp.b));         // 00406432
    printf("%p\n", &(temp.c));         // 00406434

    printf("%d\n", sizeof(temp1));      // 12
    printf("%p\n", &(temp1.a));         // 00406424
    printf("%p\n", &(temp1.c));         // 00406428
    printf("%p\n", &(temp1.b));         // 0040642C



    return 0;
}


结构体内存分配 特例: double

#include <stdio.h>

// 结构体内存分配 特例: double
// 在gcc中占 12 字节 , a和b的地址差4个字节
// 在vc 中占 16 字节 , a和b的地址差8个字节
struct stu{
    char a;
    double b;
}temp;

int main()
{
    printf("%d\n", sizeof(temp));
    printf("%p\n", &(temp.a));
    printf("%p\n", &(temp.b));

    return 0;
}


  • 位段
  • 共用体
  • 枚举
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值