结构体+联合体 详解

简介: p1,p2,p3都是结构体变量但由于p1,p2在main外部定义 是全局变量 p3是局部变量 ## 2.特殊声明 声明的时候 不完全声明 为匿名结构体类型注意匿名结构体类型只能使用一次

@TOC

一、结构体

1.结构体变量

struct s
{
  char name[20];
  int age;
}p1,p2;
int main()
{
  struct s p3;
  return 0;
}

p1,p2,p3都是结构体变量

但由于p1,p2在main外部定义 是全局变量

p3是局部变量

##  2.特殊声明

声明的时候 不完全声明 为匿名结构体类型

注意匿名结构体类型只能使用一次

#include<stdio.h>
struct 
{
  char name[20];
  int age;
};

3.结构体的引用

1.嵌套调用

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

#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)无法做到自己调用自己 会无限套娃

#include<stdio.h>
 struct S
 {
   char name[20];
   int age;
   struct S pa;//err
 };
 int main()
 {
  struct S s;
  return 0;
 }

(2)若是想做到用本身类型访问下一个同类型结构体

  使用指针指向下一个要访问的结构体

#include<stdio.h>
struct s
{
 int age;
 struct s*nest;
};

三、结构体的初始化

这里的初始化很简单

就举一个嵌套调用的例子

#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

后面的结构体成员 用其字节与默认对齐数比较 取小的为该结构体成员的对齐数   结构体成员放在对齐数整数倍的地址处

  1. 结构体的大小 是所有成员最大对齐数的整数倍

2.练习题

1.

#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    

在这里插入图片描述

2.

#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.修改对齐数

#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.练习题

#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.用法

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
#include<stdio.h>
 union un
 {
   int a;
   char b;
 }
 int main()
 {
  union un pa;
  printf("%d\n",sizeof(pa));//4
  return 0;
 }

在这里插入图片描述

### 2.用联合体判断大小端

#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;
 }
目录
相关文章
|
前端开发 Java 数据库连接
Spring模块与应用场景
Spring框架是一个Java平台,它为Java应用程序提供全面的基础框架支持。它也是现在非常流行的开源框架,只要是做Java开发,肯定接触过Spring的使用,不管我们对它的了解如何,多或者少,我们还是要尽力挖掘出Spring的功能价值。
584 1
Spring模块与应用场景
|
安全 网络安全 云计算
全国公安机关互联网站安全服务平台(公安局、公安局备案、接入方式)
全国公安机关互联网站安全服务平台(公安局、公安局备案、接入方式)【云·速成美站】
|
SQL 数据库
MySQL8的数据库备份导入MySQL5版本中
MySQL8的数据库备份导入MySQL5版本中
1007 1
MySQL8的数据库备份导入MySQL5版本中
|
数据采集 数据挖掘 数据安全/隐私保护
数据分析实战——EXCEL实现复购率计算
复购率指消费者对该品牌产品或者服务的重复购买次数,重复购买率越多,则反应出消费者对品牌的忠诚度就越高,反之则越低。
3900 1
数据分析实战——EXCEL实现复购率计算
|
机器学习/深度学习 人工智能 运维
【Kaggle/天池/DF/biendata】比赛信息汇总(NLP、CV,ML)
【Kaggle/天池/DF/biendata】比赛信息汇总(NLP、CV,ML)
1175 0
【Kaggle/天池/DF/biendata】比赛信息汇总(NLP、CV,ML)
|
Java 程序员 网络安全
java版gRPC实战之四:客户端流
客户端流式RPC,适用于客户端提交大量数据到服务端的场景,一起来体验一下
1821 1
java版gRPC实战之四:客户端流
|
自然语言处理 JavaScript 前端开发
深度了解js闭包形成及其原理
一说到这个问题,很多人第一印象就是函数里返回一个函数,就是闭包。闭包也是被大家广泛讨论的一个问题,但是很多人都是只知其然,不知其所以然。 那么闭包到底是什么?我们放到后面来回答。
475 0
深度了解js闭包形成及其原理
|
安全 API Android开发
Android 13 将限制应用侧载权限,从而提高用户隐私安全
Android 13 将限制应用侧载权限,从而提高用户隐私安全
595 0
|
云安全 机器学习/深度学习 存储
200多项分类+5级标准,金融行业数据分类分级最全模板来了
数据打标是整个数据安全治理工作中的“脏活”“累活”“难活”,同时又是数据价值挖掘和数据保护的必要基础。
2351 0
200多项分类+5级标准,金融行业数据分类分级最全模板来了
|
存储 安全 小程序
如何使用 FlowUs 、Notion 等笔记软件中进行文件管理?
文件管理中常见的问题 缺少秩序 相信很多人从学生时代,便开始被文件管理所苦恼。这一状态甚至延伸到了进入职场以后。在我们的笔记本桌面文件夹或者下载文件夹,经常可以看到各种堆积如山的文件十分混乱摆放在一起。我们看到的是一座文件堆积的垃圾山。在我们需要的时候,却经常找不到自己所需要的文件。我们的文件缺少秩序,是文件管理所遇到的第一个问题。究其原因,是因为我们懒,没有及时整理文件吗?或许是,但这不是全部原因,也不是主要原因。
816 0
如何使用 FlowUs 、Notion 等笔记软件中进行文件管理?

热门文章

最新文章