struct 结构体

对于复杂的数据类型(例如学生、汽车等),C 语言允许我们将多种数据封装到一起,构成新类型。

跟面向对象语言中的对象相比,结构体只能包含成员变量,不支持操作。

#include <stdio.h>
#include <string.h> struct People
{
int age;
char name[100]; // 这里如果用指针,下面用 strcpy 赋值时会报段错误
}; // 分号必须有 int main()
{
struct People p = {20, "lisi"}; // 使用时,struct People 是一个整体
printf("%d, %s\n", p.age, p.name); // 用点访问结构体成员
struct People *pp = &p;
pp->age = 88;
strcpy(pp->name, "jack"); // C 语言需要用 strcpy 函数实现字符串拷贝
printf("%d, %s\n", p.age, p.name); return 0;
}

结构体成员变量的两种访问方式

用句点形式访问(结构体变量)

结构体变量声明后,可以直接用句点形式访问。

struct People p = {20, "lisi"};
p.age = 88;

用箭头访问(结构体指针变量)

定义指向结构体的指针后,可以通过箭头来访问成员变量。

struct People p = {20, "lisi"};
struct People * pp = &p;
pp->age = 88; // 等价于 (*pp).age

内存对齐

对于 32 位数据总线的机器(例如 80386),虽然对内存仍然是按照字节寻址,但每次内存操作都固定传输 32 位数据。如果每次数据传输都连续且不重叠,效率是最高的。所以操作系统把内存按照数据总线的位数划分为独立单元,对于 32 位数据总线的机器每个单元是 4 个字节。每个单元都完整的分配给一个程序。

C 语言的 struct 结构体中,可以放各种类型、不同长度的数据,可以看做一个数据包。为了在程序内部提高内存访问效率,也需要对齐内存。

下面的示例,struct People 中的第一个变量 sex 会对齐内存,第二个变量 age 紧随其后,总共占了三个字节,空余一个字节。之后的 no 占用 4 个字节,如果直接放在 sex 后面保存,则访问 no 时需要两次对内存的操作。为了提高时间效率,C 编译器会把 no 变量对齐内存,这样 no 跟 sex 之间会有一个字节的空白。

#include <stdio.h>

struct People {
char sex; // 1 字节
short age; // 2 字节,此时两字节对齐,前面空一个字节
int no; // 4 字节,此时4字节对齐,前面空一个字节
}; int main()
{
struct People p = {'m', 66, 1234567};
printf("%d\n", sizeof(p)); // 8 个字节
}

下面的例子中,少了一个变量,但因为字节对齐的原因,存储空间并没有减少:

#include <stdio.h>

struct People {
char sex; // 1 个字节
int no; // 4 个字节,前面空 3 个字节
}; int main()
{
struct People p = {'M', 1234567};
printf("%d\n", sizeof(p)); // 还是 8 个字节
}

而这个例子中,因为结构体中变量的顺序发生改变,导致空间膨胀:

#include <stdio.h>

struct People {
char sex; // 1 个字节
int no; // 4 个字节,前面空 3 个字节
short age; // 2 个字节,后面空 2 个字节
}; int main()
{
struct People p = {'m', 1234567, 66};
printf("%d\n", sizeof(p)); // 这里是 12 个字节
}

C 语言结构体 struct 及内存对齐的更多相关文章

  1. 漫谈C语言结构体struct、公用体union空间占用

    先用代码说话: #include<stdio.h> union union_data0{ int a ;//本身占用4个字节 char b ;//本身占用1个字节 int c ; }; u ...

  2. C语言结构体-struct

    知识点: 1)结构体的定义. 2)结构体的sizeof. 3)  结构体的指针. 1) 结构体的定义: 在逻辑上有一定关联的多个数据类型做为一整体进行操作的数据结构,它的关键字是struct.下面我将 ...

  3. Go语言结构体(struct)

    Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型. 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 结构体表示一项记录,比如保存图 ...

  4. C语言 - 结构体(struct)比特字段(:) 详细解释

    结构体(struct)比特字段(:) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26722511 结构体(struc ...

  5. C++ 自定义结构体和类 内存对齐

    为什么要提出内存对齐? 比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个doubl ...

  6. [c/c++] programming之路(28)、结构体存储和内存对齐+枚举类型+typedef+深拷贝和浅拷贝

    一.结构体存储 #include<stdio.h> #include<stdlib.h> struct info{ char c; //1 2 4 8 double num; ...

  7. c 语言结构体struct的三种定义方式 及 typedef

    struct 结构体名{ 成员列表: ..... }结构体变量: 结构体类型变量的定义 结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对问题事先自行定义,所以结构体类型变量 ...

  8. 漫谈C语言结构体

    相信大家对于结构体都不陌生.在此,分享出本人对C语言结构体的学习心得.如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了.当然,水平有限,若发现不足之处恳请指出.代码文件test.c我放在 ...

  9. 漫谈C语言结构体【转】

    相信大家对于结构体都不陌生.在此,分享出本人对C语言结构体的学习心得.如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了.当然,水平有限,若发现不足之处恳请指出.代码文件test.c我放在 ...

随机推荐

  1. SQL Server 2005还原数据库时出现“不能选择文件或文件组XXX_log用于此操作的解决办法

    SQL2005 还原数据库失败,提示如下: SQL Server 2005还原数据库时出现“不能选择文件或文件组XXX_log用于此操作的解决办法 出现错误时操作步骤为:右击数据库--->任务- ...

  2. mongodb,robomongo 数据查询

    可视化管理工具:Robomongo 是开源,免费的MongoDB管理工具,下载地址:Robomongo下载 1.  基本查询:    构造查询数据.    > db.test.findOne() ...

  3. cve-2019-1609,Harbor任意管理员注册漏洞复现

    一.Harbor介绍 以Docker为代表的容器技术的出现,改变了传统的交付方式.通过把业务及其依赖的环境打包进Docker镜像,解决了开发环境和生产环境的差异问题,提升了业务交付的效率.如何高效地管 ...

  4. javascript的垃圾回收机制和内存管理

    垃圾回收 javascript不同于c.c++的一个特点是:具有自动的垃圾回收机制,这就意味着,开发人员可以专注于业务,而不必把过多精力放在内存的管理上,提高开发效率. 所谓的垃圾回收就是找出那些不再 ...

  5. 【java&c++】父子类中同名函数的覆盖问题

    java和c++两门语言对于父子类中同名函数具有不同的处理方式. 先上两段代码: C++: class Basic { public: void test(string i){ cout <&l ...

  6. profile 配置文件修改后如何生效?

    1.profile生效命令 . /etc/profile 或 source /etc/profile 说明:source命令也称为“点命令”,也就是一个点符号(.)

  7. 可持久化Trie模板

    如果你了解过 01 Trie 和 可持久化线段树(例如 : 主席树 ).那么就比较好去可持久化 Trie 可持久化 Trie 当 01 Trie 用的时候能很方便解决一些原本 01 Trie 不能解决 ...

  8. 杨辉三角 x

    杨辉三角是美丽的数学结晶,其结论往往多蕴含自然之美. ——以下内容均摘抄自题解. 例题: 洛谷P1762  偶数 正如这题所示,数据在n<=10^15的范围内则引导我们去寻找空间更节省,速率更高 ...

  9. 【Python】学习笔记十四:循环进阶

    range() 在Python中,for循环后的in跟随一个序列的话,循环每次使用的序列元素,而不是序列的下标. 我们继续开发range的功能,以实现下标对循环的控制: s = 'abcdefghj' ...

  10. 二分类算法的评价指标:准确率、精准率、召回率、混淆矩阵、AUC

    评价指标是针对同样的数据,输入不同的算法,或者输入相同的算法但参数不同而给出这个算法或者参数好坏的定量指标. 以下为了方便讲解,都以二分类问题为前提进行介绍,其实多分类问题下这些概念都可以得到推广. ...