前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >结构体+联合体 详解

结构体+联合体 详解

作者头像
lovevivi
发布2022-11-10 14:42:58
2780
发布2022-11-10 14:42:58
举报
文章被收录于专栏:萌新的日常

一、结构体

1.结构体变量

代码语言:javascript
复制
struct s
{
  char name[20];
  int age;
}p1,p2;
int main()
{
  struct s p3;
  return 0;
}

p1,p2,p3都是结构体变量 但由于p1,p2在main外部定义 是全局变量 p3是局部变量

2.特殊声明

声明的时候 不完全声明 为匿名结构体类型 注意匿名结构体类型只能使用一次

代码语言:javascript
复制
#include<stdio.h>
struct 
{
  char name[20];
  int age;
};

3.结构体的引用

1.嵌套调用

通过调用 pa变量 返回到stdent结构体中

代码语言:javascript
复制
#include<stdio.h>
struct student
{
  char name[20];
  int age;
  char sex[20];
};
struct teacher
{
  char name[20];
  int age;
   struct student pa;
   char sex[20];
};

2.自引用

(1)无法做到自己调用自己 会无限套娃

代码语言:javascript
复制
#include<stdio.h>
 struct S
 {
   char name[20];
   int age;
   struct S pa;//err
 };
 int main()
 {
  struct S s;
  return 0;
 }

(2)若是想做到用本身类型访问下一个同类型结构体 使用指针指向下一个要访问的结构体

代码语言:javascript
复制
#include<stdio.h>
struct s
{
 int age;
 struct s*nest;
};

三、结构体的初始化

这里的初始化很简单 就举一个嵌套调用的例子

代码语言:javascript
复制
#include<stdio.h>
struct student
{
 char name[20];
 int age;
 char sex[20];
};
struct teacher
{
 char name[20];
 int age;
 struct student s;
 char sex[20];
};
int main()
{
 struct teacher p={"张三","35",{"王五","16","男"},"男"};
 printf("%s %d %s %d %s %s\n",p.name,p.age,p.s.name,p.s.age,p.s.sex,
        p.sex};
  return 0;
 }

四、结构体的内存对齐

1.用法

1.第一个结构体成员放在 0偏移量处 2.若放在VS中 默认对齐数是8 后面的结构体成员 用其字节与默认对齐数比较 取小的为该结构体成员的对齐数 结构体成员放在对齐数整数倍的地址处 3. 结构体的大小 是所有成员最大对齐数的整数倍

2.练习题

代码语言:javascript
复制
#include<stdio.h>
 struct s
 {
char a;
int b;
char c;
 };
 int main()
 {
struct s pa;
printf("%d\n",sizeof(pa));
return 0;
 }

VS中默认对齐数是8 char a为1个字节 1<8 即a的对齐数是1 int b为4个字节 4<8 即b的对齐数是4 char c为1个字节 1<8 即c的对齐数是1 正常来说应取9个字节 9没有达到最大对齐数4的整数倍 故 要取 12

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
#include<stdio.h>
struct s2
{
 char c1;
 char c2;
 int i;
}
int main()
{
 strcut s2 S;
 printf("%d\n",sizeof(S));
 return 0;
}

char c1为1个字节 1<8 即c1的对齐数是1 char c2为1个字节 1<8 即c2的对齐数是1 int i为4个字节 4<8 即i的对齐数是4 最大对齐数为4 因为最后也是取 8 是4的整数倍 即 8

在这里插入图片描述
在这里插入图片描述

3.修改对齐数

代码语言:javascript
复制
#include<stdio.h>
#pragma pack(2) //将默认对齐数修改成2
struct s
{
 char a;
 int b;
 char c;
}
#pragma pack() //将修改的对齐数消除 即只在上面的结构体生效
int main()
{
 struct s pa={0};
 printf("%d\n",sizeof(pa));
 return 0;
}

需要注意的是 对齐数是结构体成员在哪里进行偏转 偏转的大小是字节数 修改后 默认对齐数为2 char a为1个字节 1<2 即a的对齐数为1 int b为4个字节 4>2 即b的对齐数为 2 char c为 1个字节 1<2 即c的对齐数为1 最大对齐数为 2 但是结构最后是 7 不是2的整数倍 最后为 8

在这里插入图片描述
在这里插入图片描述

五、位段

1.用法

位段的成员必须是 int , unsigned int, signed int 成员名后必须有 冒号和数字 位段的空间是按照 int或者 char来开辟的 我们通常将 位段成员 按照 低比特位到高比特位传递 如果一块空间剩下的内容不够下一个成员使用 这块空间就会被浪费掉

2.练习题

代码语言:javascript
复制
#include<stdio.h>
struct S
{
   char _a:3;//a占两个比特位
   char_b:4;//b占4个比特位
   char_c:5;//c占5个比特位
   char_d:4;//d占4个比特位
}
struct S s={0};
s.a=10;
s.b=12;
s.c=3;
s.d=4;

a为 10 -------- 1010--------->占3个比特位---010 b为 12 -------- 1100--------->占4个比特位---1100 c为 5 --------- 00101--------> 占5个比特位--00101 d为 4 ---------- 0010------------>占4个比特位---0010

在这里插入图片描述
在这里插入图片描述

六、联合体

1.用法

代码语言:javascript
复制
1. 一种特殊的自定义类型,主要表现为 成员共用一块空间

  1. 联合体的计算 联合体的大小至少是最大的成员的大小 当最大成员大小不是最大对齐数的整数时 就要对齐到最大对齐数的整数

2.练习题

1.正常算法题

VS默认对齐数为8 int a为4个字节, 4<8, a的对齐数为4 char b为1个字节 1<8 b的对齐数为1 a与b共用第一块空间 所以为4 又因为 4时是 最大对齐数4的整数倍 即 4

代码语言:javascript
复制
 #include<stdio.h>
 union un
 {
   int a;
   char b;
 }
 int main()
 {
  union un pa;
  printf("%d\n",sizeof(pa));//4
  return 0;
 }
在这里插入图片描述
在这里插入图片描述

2.用联合体判断大小端

代码语言:javascript
复制
#include<stdio.h>
 int move()
 {
   union un
   {
     int a;
     char b;
   }u;
   u.a=1;
    return u.b;
  int main()
  {
    int ret=move();
    if(ret==1)
    {
     printf("小端\n");
    }
    else
    {
     printf("大端\n");
    }
    return 0;
 }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、结构体
    • 1.结构体变量
      • 2.特殊声明
        • 3.结构体的引用
          • 1.嵌套调用
          • 2.自引用
      • 三、结构体的初始化
      • 四、结构体的内存对齐
        • 1.用法
          • 2.练习题
            • 3.修改对齐数
            • 五、位段
              • 1.用法
                • 2.练习题
                • 六、联合体
                  • 1.用法
                    • 2.练习题
                      • 1.正常算法题
                      • 2.用联合体判断大小端
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档