专栏首页编程珠玑C语言结构体用法很多,坑也很多

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

作者:strongerHuang

C语言可谓是编程界的传奇语言,历经几十年,依然排名前列。

本文主要说的是C语言中的结构体,结构体是C语言中重要的一部分内容,也是C语言中常用的一种数据结构。

一、关于结构体

在C语言中,结构体(struct)指的是一种数据结构,是C语言中复合数据类型(aggregate data type)的一类。

结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

结构体的定义如下所示:

 struct tag { member-list } variable-list; 

其中:

  • struct为结构体关键字;
  • tag为结构体的标志;
  • member-list为结构体成员列表,其必须列出其所有成员;
  • variable-list为此结构体声明的变量。

在一般情况下:tag、member-list、variable-list这3部分至少要出现2个。

二、结构体常规定义

不同的定义,应用在不同场景,所以,我们编程时需要结合实际情况来定义结构体。

方法1:

定义结构体stu,此时结构体相当于一个类型,比如int,如需使用此结构体,方法同int.

struct stu{    char  aa;    short bb;    int   cc;};
struct stu stu1, stu2;

方法2:

定义结构体stu同时定义需要使用的结构体变量stu1, stu2。如后面再需要定义结构体变量,方法同1.

struct stu{    char  aa;    short bb;    int   cc;}stu1, stu2;
struct stu stu3;

方法3:

定义结构体时,结构体名称缺省,同时定义结构体变量stu1,stu2。但后面不可再定义结构体变量。

struct{    char  aa;    short bb;    int   cc;}stu1, stu2;

提示:

这里不能像上面再定义结构体变量:(以下错误)

struct stu3; struct stu stu3;

三、使用typedef定义结构体

这里先简单说下typedef.

在C和C++编程语言中,typedef是一个关键字。它用来对一个数据类型取一个别名,目的是为了使源代码更易于阅读和理解。它通常用于简化声明复杂的类型组成的结构 ,但它也常常在各种长度的整数数据类型中看到,例如size_t和time_t。 维基百科

方法4:

使用typedef定义结构体同时,给stu结构体别名STU,后续定义可不用使用struct stu,直接使用STU即可。

typedef struct stu{    char  aa;    short bb;    int   cc;}STU;
STU stu1;

你会发现,其实就是通过关键字typedef,将STU取代了struct stu。

当然,也可以这么用:

struct stu stu1;

上面这种定义就失去了typedef的意思,所以不推荐。

方法5:

使用typedef定义结构体时,省掉结构体第一个别名stu,直接在后面加STU,使用方法同上。

typedef struct{    char  aa;    short bb;    int   cc;}STU;
STU stu1;

方法6:

还有一种符合语法规则,但意义不大的定义方式。

typedef struct stu{    char  aa;    short bb;    int   cc;};
struct stu stu1;

以上这些定义方式算是语法的知识,如果还不懂,请再次复习一下。或者参考《一句话帮你理解typedef的用法》。

四、结构体大小计算

结构体的大小,我相信很多人都没搞明白。实际编程中也是很多地方都在应用,比如:存储、拷贝结构体时都会牵涉到结构体大小的问题。

1.对比两结构体大小,一样吗?

结构体1:

struct stu{    char  aa;    short bb;    char  cc;}stu1;

结构体2:

struct stu{    char  aa;    char  bb;    short cc;}stu2;

答案是不一样。程序测试得出sizeof(stu1)=6, sizeof(stu2)=4.

编辑注:这里需要考虑程序位数,或者说默认对齐字节数,因为以上答案不完全如此。

2.分析不一样原因

结构体计算要遵循字节对齐原则,一般满足三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节;

对于上面结构体stu1来说,最大字节:2字节,顺序是 char->short->char:

第一个char占一个字节

多的这一个补0,只是占位作用

short 刚好占2个字节

第二个char也占1个

多的这一个补0

对于上面结构体stu2来说,最大字节:2字节,顺序是 char->char->short:

第一个char占一个字节

第二个char占一个字节

short 刚好占2个字节

通过上面两个表格,相信你应该明白了,改成4字节的int,原理一样。

本文分享自微信公众号 - 编程珠玑(shouwangxiansheng)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何给一千万个整数快速排序

    输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。

    编程珠玑
  • 每周小题-字节对齐&Linux文本命令&存储期和链接属性

    linux下查看文本内容的命令有哪些? 答案可参考《Linux常用命令--文本查看篇》。

    编程珠玑
  • 如何对1千万个整数进行快速排序

    输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。

    编程珠玑
  • vue-cli脚手架npm相关文件解读(5)vue-loader.conf.js

    系列文章传送门: 1、build/webpack.base.conf.js 2、build/webpack.prod.conf.js 3、build/webp...

    SmileSmith
  • Eclipse插件之SQLExplorer EclipseBBS.netthread工作

    本文介绍如何利用Eclipse 插件SQLExplorer 在Eclipse 中连接各种数据库进行操作使用。 Eclipse 是目前非常流行的开发平台,开放扩展...

    阿敏总司令
  • 技术博客组件之Disqus中文化

    Bison
  • 现代Web开发系列教程_07

    jeremyxu
  • 介绍一种在ABAP内核态进行内表高效拷贝的方法

    看一个例子:有两个行结构不一样的内表,每个内表的行结构有三列,除了name这一列名字一致外,其他两列的名称都不同,下图用红色和蓝色标注出来。

    Jerry Wang
  • http cache笔记

    本文作者:IMWeb devinran 原文出处:IMWeb社区 未经同意,禁止转载 Last-Modified 与 If-Modified-Si...

    IMWeb前端团队
  • 隐马尔可夫模型及其相关算法详述

    −1​无关,即条件分布函数满足下列等式,此性质称为马尔可夫性质。如果随机过程满足马尔可夫性,则该过程称为马尔可夫过程。

    魏晓蕾

扫码关注云+社区

领取腾讯云代金券