0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言-结构体与位域

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2022-08-14 10:06 次阅读

1. 结构体介绍

C语言里的结构体是可以包含不同数据类型和相同数据类型的一个有序集合,属于构造类型,可以自己任意组合,并且结构体里也可以使用结构体类型作为成员。

结构体在项目开发中使用非常多,无处不在,有了结构体类型就可以设计很多框架,模型,方便数据传输,存储等等。

结构体定义语法

struct 结构体名称
{
    数据类型1 成员名1;
    数据类型2 成员名2;
    数据类型3 成员名3;
    .....
};

结构体的名称命名规则: 和普通变量命名规则一样—遵循C语言变量命名标准。
                       ‘A’~‘Z’ ‘a’~ ’z’  ‘0’~’9’  _

示例代码:

struct app
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
};

上面这一块代码表示定义(声明)一个新的结构体类型。  数据类型名称:struct app

2. 如何使用结构体定义变量?

结构体定义变量有3种形式:

#include 

//第一种形式:在定义结构体类型的时候同时定义变量
struct app1
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}a1,a2,a3;   //a1 a2 a3就是定义的结构体变量

//第二种形式
struct app2
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
};

//第三种形式: 匿名方式定义结构体
struct
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}c1,c2,c3;  //c1 c2 c3就是定义的结构体变量

int main()
{
    //使用结构体类型定义变量
    struct app2 b1;
    struct app2 b2;
    struct app2 b3;

    return 0;
}

3. 结构体的赋值

结构体变量的赋值语法:

 结构体变量名.成员名=xxx;

结构体初始化赋值说明:

结构体只能在(定义结构体变量的时候)初始化的时候支持整体赋值,之后就只能按照成员单个赋值。

注意:结构体变量之间支持直接赋值。

#include 
#include 

//第一种形式:在定义结构体类型的时候同时定义变量
struct app1
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}a1={23,"小白",5678},a2,a3={12,"小明",1234};   //a1 a2 a3就是定义的结构体变量

//第二种形式
struct app2
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
};

int main()
{
    //使用结构体类型定义变量
    struct app2 b1={15,"小李",6878};
    struct app2 b2;
    struct app2 b3;

    //单个修改结构体成员变量的值
    b1.age=18;
    //b1.name="555";
    strcpy(b1.name,"小丽");
   
    printf("b1:%d\n",b1.age);
    printf("b1:%s\n",b1.name);

    printf("a1:%d\n",a1.age);
    printf("a1:%s\n",a1.name);

    //结构体变量之间支持直接赋值 (要保证变量的类型要一致)。
   //int a=100;
   //int b;
   //b=a;
   b2=b1;  //将b1结构体变量赋值给b2结构体变量
   printf("b2:%d\n",b2.age);
   printf("b2:%s\n",b2.name);
    return 0;
}

4. 结构体指针定义与使用

示例代码:

#include 
#include 
#include 

struct app
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}; 

int main()
{
    struct app a1;   //定义一个结构体变量
    struct app *p1;  //定义一个结构体指针
    struct app *p2;  //定义一个结构体指针
    p1=&a1;  //地址赋值  p1指向a1的空间

    //申请堆空间
    p2=malloc(sizeof(struct app));

    //通过指针访问成员
    p1->age=20;
    strcpy(p1->name,"小红");
    p1->number=1234;
    //输出数据
    printf("姓名:%s\n",p1->name);
    printf("学号:%d\n",p1->number);
    printf("年龄:%d\n",p1->age);

     //通过指针访问成员
    p2->age=13;
    strcpy(p2->name,"小李");
    p2->number=5678;
    //输出数据
    printf("姓名:%s\n",p2->name);
    printf("学号:%d\n",p2->number);
    printf("年龄:%d\n",p2->age);

    //释放空间
    free(p2);
    return 0;
}

5. 结构体数组定义与使用

示例代码:

#include 
#include 
#include 

struct app
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}; 

int main()
{
    
    //定义一个结构体数组
    struct app buff[10];  //一次定义了10个结构体变量
    struct app *p=buff;  //定义一个结构体指针

    //访问成员
    buff[0].age=10;
    strcpy(buff[0].name,"小米");
    buff[0].number=1234;

    //打印数据
    printf("姓名:%s\n",buff[0].name);
    printf("学号:%d\n",buff[0].number);
    printf("年龄:%d\n",buff[0].age);

    printf("姓名:%s\n",p[0].name);
    printf("学号:%d\n",p[0].number);
    printf("年龄:%d\n",p[0].age);
    return 0;
}

6. 结构体当做函数的形参和返回值

示例代码:

#include 
#include 
#include 

struct app
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}; 

struct app *func_stu(struct app *p);

int main()
{
    
    //定义一个结构体数组
    struct app buff[10];  //一次定义了10个结构体变量
   
    //调用函数
    func_stu(&buff[0]);

    //打印数据
    printf("姓名:%s\n",buff[0].name);
    printf("学号:%d\n",buff[0].number);
    printf("年龄:%d\n",buff[0].age);
    return 0;
}

//定义函数
struct app *func_stu(struct app *p)
{
   //访问成员
    p->age=10;
    strcpy(p->name,"小米");
    p->number=1234;
    return p;
}

7. typedef关键字在结构体里使用方法

#include 
#include 
#include 

typedef struct app
{
    int age; //年龄
    char name[100]; //姓名
    int number; //学号
}STU;  //STU叫结构体类型,相当于struct app的别名。  struct app == STU

STU *func_stu(STU *p);

int main()
{
    //定义一个结构体数组
    STU buff[10];  //一次定义了10个结构体变量
   
    //调用函数
    func_stu(&buff[0]);

    //打印数据
    printf("姓名:%s\n",buff[0].name);
    printf("学号:%d\n",buff[0].number);
    printf("年龄:%d\n",buff[0].age);
    return 0;
}

//定义函数
STU *func_stu(STU *p)
{
   //访问成员
    p->age=10;
    strcpy(p->name,"小米");
    p->number=1234;
    return p;
}

8. 结构体位域

位域用的不多,但是也有地方使用,主要是节省空间。

#include 
struct app
{
    unsigned int a:12;  //定义位域,指定位宽   12的单位是位
    unsigned int b:16;
    unsigned char c:1; //定义空间存储1位的数据。  1和0
    unsigned int :5;   //位域的名称可以省略掉,为了空间内存对齐而存在的
};
/*
1. 位域的大小不能超出本来数据类型大小。
2. 位域的名称可以省略掉,为了空间内存对齐而存在的
3. 位域的成员无法取地址操作
*/

int main()
{
    struct app data;
    //data.c=2;  错误 超出范围   只能存放0~1
    //data.b=65535;   错误 超出范围   只能存放0~65535
    // data.a=4096; 错误 超出范围   只能存放0~65535
    //printf("%d\n",data.c);
   // printf("%d\n",data.b);
    //printf("%d\n",data.a);

    //printf("%d\n",&data.a);   //错误 位域的成员无法取地址操作

    data.c=1;
    data.b=555; //只能存放0~65535
    data.a=888; //只能存放0~65535
    printf("%d\n",data.c);
    printf("%d\n",data.b);
    printf("%d\n",data.a);
    return 0;
}

9. 结构体的内存对齐

9.1 示例1: 计算结构体内存对齐

#include 
struct app
{
   int a1;
   char a2;
   char a3;
   char a4;
   char a5;
   char a6;
   char a7;
};
/*
目前32位系统里,使用的是gcc编译器。
开空间的对齐原理:以结构体里出现的最大数据类型的倍数开空间,最大是4个字节。
*/
int main()
{
    struct app data;
    printf("空间大小:%d 字节\n",sizeof(struct app)); //8
    return 0;
}

//func("1",1123,45,"45",123.45,'A');
void func(char *p,...)
{

}

9.2 示例2: 计算结构体内存对齐

#include 
#if 0
struct app
{
   char a1;  //1
   short a2; //2
};
最终占用空间大小4个字节
#endif

#if 0
struct app
{
   int a1[10];   //4*10=40
   char a2[10];  //12
   int a3;      //4
   float a4;   //4
   char a5;   //4
};
//最终占用空间大小64个字节
#endif

#if 1
struct app
{
   int a1;
   double a2;
};
//最终占用空间大小64个字节
#endif

/*
目前32位系统里,使用的是gcc编译器。
开空间的对齐原理:以结构体里出现的最大数据类型的倍数开空间,最大是4个字节。
*/
int main()
{
    struct app data;
    printf("空间大小:%d 字节\n",sizeof(struct app)); //8
    return 0;
}

//func("1",1123,45,"45",123.45,'A');
void func(char *p,...)
{

}

9.3 输出结构体变量成员的地址,查看空间对齐情况

#include 

struct app
{
   int a1[10];   //4*10=40
   char a2[10];  //12
   int a3;      //4
   float a4;   //4
   char a5;   //4
};
//最终占用空间大小64个字节

int main()
{
    struct app data;

    //输出地址   查看空间对齐原理
    printf("%#x\n",data.a1);
    printf("%#x\n",data.a2);
    printf("%#x\n",&data.a3);
    printf("%#x\n",&data.a4);
    printf("%#x\n",&data.a5);
    return 0;
}

9.4 对齐结构体进行强制对齐

#include 

#pragma pack(1)  //1 2 4 8
struct app
{
   int a1[10];   //4*10=40
   char a2[10];  //1*10=10
   int a3;      //4
   float a4;   //4
   char a5;   //1
};

int main()
{
    struct app data;

    //输出地址   查看空间对齐原理
    printf("%#x\n",data.a1);
    printf("%#x\n",data.a2);
    printf("%#x\n",&data.a3);
    printf("%#x\n",&data.a4);
    printf("%#x\n",&data.a5);
    printf("%d\n",sizeof(struct app));
    return 0;
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7528

    浏览量

    128398
  • 结构体
    +关注

    关注

    1

    文章

    125

    浏览量

    10749
收藏 人收藏

    评论

    相关推荐

    关于C语言结构体内存对齐

    今天给大家带来一道经典、易错的关于C语言结构体内存对齐的题目:
    的头像 发表于 04-14 12:51 6665次阅读

    关于C语言结构体内存对齐

    今天给大家带来一道经典、易错的关于C语言结构体内存对齐的题目。
    发表于 09-08 11:54 372次阅读

    C语言结构体对齐介绍

    大家好,我是嵌入式老林,从事嵌入式软件开发多年,今天分享的内容是C语言结构体对齐介绍,希望能对你有所帮助
    发表于 07-11 11:50 606次阅读
    C<b class='flag-5'>语言</b><b class='flag-5'>结构</b>体对齐介绍

    C语言结构体讲解

    在C语言中有一块极容易被忽略,但是对于嵌入式编程来说用处特别大的内容——结构
    发表于 10-01 13:27 150次阅读
    C<b class='flag-5'>语言</b><b class='flag-5'>结构</b>体讲解

    MSP430单片机C语言的基本结构

    MSP430 C语言基本结构 基础知识有助于我的学习单片机MSP430
    发表于 01-11 14:10 27次下载

    c语言结构体使用

    C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言
    发表于 11-09 17:01 1309次阅读

    C语言结构体之位域位段

    所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
    的头像 发表于 11-08 08:38 7567次阅读

    C语言结构体用法很多,但是坑也很多

    C语言结构体用法很多,坑也很多
    的头像 发表于 01-13 16:06 1051次阅读

    解析C语言结构体字节如何对齐

    01 默认字节对齐 C语言结构体字节对齐是老生常谈的问题了,也是高频面试题,现在我们来深入研究这个问题,彻底弄懂到底是怎么回事,给你一个结构体定义和平台机器位数就能手动计算出结构体占用
    的头像 发表于 06-12 17:42 2821次阅读

    C语言结构体和共用体在单片机中的妙用

    【分享】C语言结构体和共用体在单片机中的妙用C语言结构体和共用体,往往在单片机应用开发中被忽视。如果能够用起来,不仅能够极大的提高单片机的运行效率,还可能解决一些看起来无法解决的问
    发表于 11-20 19:36 20次下载
    C<b class='flag-5'>语言</b>的<b class='flag-5'>结构</b>体和共用体在单片机中的妙用

    c语言结构体在单片机中的应用

    Struck看到单片机中有很多struck 的应用,但是呢我当初学C语言的时候又没有很认真的去学习,今天复习下,写一篇小小的交流,希望能够给大家带来帮助。1.struck的定义
    发表于 11-20 19:51 10次下载
    c<b class='flag-5'>语言</b><b class='flag-5'>结构</b>体在单片机中的应用

    C语言_结构体总结

    当前文章介绍动态堆空间内存分配与释放,C语言结构体定义、初始化、赋值、结构体数组、结构体指针的相关知识点,最后通过一个学生管理系统综合练习结构
    的头像 发表于 08-14 09:52 834次阅读

    C语言结构体知识科普

    定义一个结构体的方法有很多,这里我用一种常用的方式来定义结构体。
    发表于 06-23 17:51 264次阅读
    C<b class='flag-5'>语言</b><b class='flag-5'>结构</b>体知识科普

    C语言结构体完全笔记

    我们刚刚申请了一个名叫Info的结构体类型,那么理论上我们可以像声明其他变量的操作一样,去声明我们的结构体操作,但是C语言中规定,声明结构体变量的时候,struct关键字是不可少的。
    的头像 发表于 08-01 16:52 358次阅读
    C<b class='flag-5'>语言</b><b class='flag-5'>结构</b>体完全笔记

    嵌入式C语言结构特点

    过程中,不论是基于寄存器开发还是基于库开发,深入理解和掌握嵌入式C语言的函数、指针、结构体是学习STM32的关键。嵌入式C语言结构特点如下。 (1)程序总是从main函数开始执行,语
    的头像 发表于 11-24 16:16 320次阅读
    嵌入式C<b class='flag-5'>语言</b>的<b class='flag-5'>结构</b>特点