一、结构体是C和C++用户自己来定义的一种数据类型。

1、结构体变量的定义方法由三种:

(1)先声明结构体类型再定义结构体变量;

在C语言中,定义结构体变量要在结构体类型名前加关键字struct,而C++也保留了这一用法,例:

struct Student student1, student2;

但C++语言也提出了新的方法,即在定义结构体变量时,不需要加关键词struct。

(2)在声明类型的同时定义结构体变量;例:

struct student
{int num;char name[20];char sex;int age;float score;
}student1,student2;

(3)直接定义结构体变量,这种方法虽然合法,但不建议使用。

还是提倡第一种用法。

2、结构体变量的初始化:在定义结构体变量时进行初始化。例:

struct Student
{int num;char name[20];int age;char sex;float score[6];
}student{ 20, "liming", 20, { 10, 22, 15, 35, 66, 58 } };

3、struct 和 typedef  struct.

(1) 在C语言中定义结构体如果使用 typedef  struct:

typedef struct Student
{int num;char name[20];int age;char sex;float score[6];
};

在定义结构体变量中就可以直接使用:

int main()
{Student student1;return 0;
}

如果没有 typedef,在定义结构体变量时,类型前面就要加上关键字 struct。而在C++中,定义结构体时可以直接进行定义,不需要关键字 struct。

(2)然而在C++中使用 typedef 会有不同的意义,例:

typedef struct Student
{int num;char name[20];int age;char sex;float score[6];
}student1;
struct Student
{int num;char name[20];int age;char sex;float score[6];
}student2;

其中,student1又是一个结构体类型,student2是一个结构体变量,在对其对象访问时有一定的区别。
4、结构体的内存存储
(1)内存对齐规则:

a)结构体的第一个成员永远都放在结构的0偏移处;

b)从第二个成员开始,都要对齐到某个对齐数的整数倍;(对齐数为结构体成员自身的大小和系统默认对齐数的较小值,Vs中默认的值为8,linux中默认的值为4)

c)结构体的总大小必须是最大对齐数的整数倍。

d)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍。

#include<stdio.h>
#include<iostream>
struct Student//Vs系统的默认对齐数为8,该结构体成员类型最大所占字节为4,所以对齐数为4
{int num;            //4个字节       0-3偏移处//从0偏移处开始存放,存放4个字节char name[20];      //20个字节      4-23偏移处//存放了4个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的4偏移处开始存放20个字节int age;            //4个字节       24-27偏移处//存放了24个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的24偏移处开始存放4个字节char sex;           //1个字节       28偏移处//存放了28个字节刚好为结构体对齐数的整数倍,则紧挨着从接下来的28偏移处开始存放1个字节float score[6];     //24个字节      32-55偏移处//存放了29个字节,不是4的整数倍,则要浪费掉3个字节,从接下来的4的倍数的偏移处开始存放,即从32偏移处开始存放24个字节
}student2;//结构体内存存放到了55偏移处,则存放了56个字节,则结构体的大小为56
int main()
{Student student1;printf("%d\n", sizeof(student2));system("pause");return 0;
}

(2)内存对齐的原因:

a)平台原因:不是所有硬件平台都能够访问任意地址上任意数据的;某些硬件平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常;

b)性能原因:数据结构应该尽可能地在自然边界上对齐。原因是为了访问未对齐的内存,处理器需要作两次内存访问,二对齐的内存访问仅需一次访问。

#include<stdio.h>
struct Student
{char name;int age;
};
int main()
{Student student;return 0;
}

二、结构体与位段

1、位段:有些信息的存储并不需要占用一个字节,只需要几个或一个比特位,为了节省空间,C语言提供了一种数据结构----位段。其成员类型可为:int、char、signed int、unsigned int 。

2、结构体实现位段:

#include<stdio.h>
#include<iostream>
struct Student
{int a : 5;signed int b : 1;unsigned int c : 3;
};
int main()
{Student student1{ 5, 1, 2 };printf("%d\n", sizeof(student1));    //占4个字节的空间printf("%d\n", sizeof(Student));     //占4个字节的空间system("pause");return 0;
}

3、位段的大小计算

a)1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。(在VC中位段存储单元的大小是4字节);

b)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小。

解析C语言结构体及位段相关推荐

  1. c语言结构体反射解析,C语言结构体解析

    我们知道定义一个数组就等于定义了多个相同类型的变量,它们的类型是一样的.有时有这样的需求,如果我想保存一些信息,但每个信息类型不一定相同,这时该怎么办?我们就可以自己定义一类型,而这个类型,就是结构体 ...

  2. c语言结构体和联合体,C语言结构体和联合体

    1.单链表插入 #include #include #define FALSE 0 #define TRUE 1 typedef struct NODE{ STRUCT NODE *link; int ...

  3. C语言结构体——位段概念的讲解

    前言 之前我对结构体内存分配的方式.对默认对齐数的指令修改做了详细的博客讲解,(C语言结构体详解 (2) 结构体内存对齐,默认对齐数,大家有兴趣的话可以去了解了解这方面的知识. 一. 什么是位段? 位 ...

  4. C语言结构体中的位段

    C语言结构体中的位段 位段的内存分配 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型 位段的空间上是按照需要以4个字节( int )或 ...

  5. 深入解析JNA—模拟C语言结构体

    原帖:http://blog.csdn.net/shendl/article/details/3599849 深入解析JNA-模拟C语言结构体 前言 前几天写<JNA--JNI终结者>一文 ...

  6. 详解C语言自定义类型(结构体,位段,枚举,联合)

    C语言中有许多类型,比如整形int,字符型char,双精度浮点型double等等.这些类型可以存放一些值或者字符.但是如果我想要一种类型存放一本书,显然是没有的,那么这时候就需要自定义类型了,也就是结 ...

  7. 自定义类型:结构体、位段、枚举、联合 ------- C语言

    C语言中,7可以存放再整型变量中,'c' 可以存放在字符型变量中,3.14可以存放在浮点型变量中,一个学生有:姓名.年龄.性别.学号等.C语言中是否有这样一个可以存放学生的类型呢?答案是肯定的,这一种 ...

  8. golang常用库之mapstructure包 | 多json格式情况解析、GO json 如何转化为 map 和 struct、Go语言结构体标签(Struct Tag)

    文章目录 golang常用库之mitchellh/mapstructure包 | go将map转换为struct 一.msgpack 二.背景 三.多json格式情况解析使用思路 四.mapstruc ...

  9. C语言结构体字节对齐规则

    C语言结构体字节对齐规则 基本规则 规则1 :结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在 ...

最新文章

  1. AJAX技术其实就是多年前我就使用过的XMLHTTP
  2. ios 设计模式 MVC ,MVVM
  3. mvp的全称_现役最强外援,总决赛MVP,来到CBA之后赚了多少钱?
  4. 由于超出容量限制_限制特高压系统中的过电压措施
  5. docker中启动关闭删除所有的容器命令
  6. 从一个视图控制器切换到另一个视图控制器的几种方式
  7. 吴恩达深度学习 ——深层神经网络(选择题)
  8. Matplotlib:直方图示例(2):正态分布。
  9. Windows11怎么配置Maven环境变量
  10. HW2021攻防演练经历碎碎念-见解
  11. 动画云渲染【渲染101】渲染小提示
  12. 你不屑于大器晚成,就只能平庸一生
  13. 恢复win7 exe文件打开方式?
  14. AMD显卡性能测试软件,谁更适合Win7?AMD与NVIDIA显卡性能对比
  15. 淘宝标题优化词根优化方法技巧 什么是淘宝标题词根
  16. 【Git】git did not exit cleanly (exit code 1) 异常处理
  17. 19.Oracle数据库SQL开发之 笛卡尔积
  18. C语言 冒泡法排序,选择法排序和插入排序
  19. python文件名排序按windowsp_在SQLServer中如果实现Windows文件夹中按名称排序?算法是什么怎么Order By...
  20. 基于Netty的RPC架构实战演练

热门文章

  1. 剑网3哪5区人哪个服务器最多,剑网3哪个区服人最多?只有选对了游戏区才能体会到多人的乐趣...
  2. ie调用java闪退_win7系统位数不兼容导致Ie浏览器频繁出现闪退的解决方法
  3. 由于不能验证所收到的数据是否可信,无法显示您想要查看的页面。建议向此网站的管理员反馈这个问题。
  4. 12 款做Java后台管理系统的项目,超级无敌好用!
  5. 吃豆人 html5 倒计时,ChinaJoy开展倒计时,回忆杀吃豆人ip摩擦康迪克水杯溅火花...
  6. java字符串是日期yyxx_Mysql 优化方案
  7. 如何在html中引入一个仪表盘,仪表盘.html · 一头大水牛/前端每日总结,积累点滴! - Gitee.com...
  8. the kth number第几大数问题
  9. 鞍点计算 C语言 SDUT
  10. leecode:977. 有序数组的平方