C语言结构体

一、结构体的定义:

结构体(Struct)是C语言中的一个重要数据类型,它可以用来存储多个不同类型的变量。结构体类似于一个自定义的数据类型,可以包含多个不同类型的成员变量,每个成员变量可以有自己的数据类型和值。

二、结构体存储数据方式

结构体存储数据遵循两个原则:

 原则一:结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算)。

原则二:在经过第一原则分析后,检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。

三、结构体定义变量的方式

1、在struct{}之后直接定义变量名

struct Books
{char  title[50];char  author[50];char  subject[100];int   book_id;
} book;

2、在main函数当中定义变量名

struct Books
{char  title[50];char  author[50];char  subject[100];int   book_id;
};int main()
{struct Books
}

四、结构体赋值方式以及注意事项

在定义结构体时是不能在结构体里给变量初始化, 因为定义结构体时,并未给其分配内存,所以初值是无法存储的。

就如下面:

struct A{int age =18;char name[10] = "zs";
}

这个是不允许的!!!

结构体中赋初值有如下方式:

      1、

struct A{int age;char name[10];char sex[4]; 
}int main()
{struct A a = {18,"zs","男"};
}

2、 注意字符数组不能直接a.name = "zs",因为这相当于char name[10];name[10] = "zs",这是不允许的,要用strcpy()函数给字符串数组赋值,但是,如果结构体里定义的是char *name,那么就可以直接a.name = "zs";

struct A{int age;char name[10];char sex[4]; 
}int main()
{struct A a;a.age = 4;strcpy(a.name,"zs");strcpy(a.sex,"男"); 
}

 3、结构体中不能在定义完变量后整体赋初值,如:

struct A{int age;char name[10];char sex[4]; 
}int main()
{struct A a;a = {18,"zs","nan"}
}

 4、在定义结构体类型的同时进行结构体变量初始化,这个是可以的

struct student{char name[32];int age;char gender;double score;}Phoebe = {“Phoebe”,17,'F', 92.5};

5、 结构体变量部分初始化:

 struct student{char name[32];int age;char gender;double score;}Phoebe = {“Phoebe”, 17};

6、 结构体变量指定部分初始化:

 struct student{char name[32];int age;char gender;double score;}Phoebe = {.name = “Phoebe”, .score = 17.0};

3、结构体中偏移量问题

1、整个结构体的大小会是结构体中所占字节数最大的那个数据类型的整数倍

2、每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的(以结构体变量首地址为0计算

如:

#include<stdio.h>
struct A{char a;char b;int c;double d;
};
int main()
{struct A a;printf("%ld\n",sizeof(a));
}

其中各数据所占图为:

 (1-8表示字节数)其中double类型在该结构体中所占字节数最大,所以结构体的整体大小应该是double类型的整数倍,也就是8的整数倍

①先存放a,因为a是char类型,占一个字节

②再放b,b也是char类型,占一个字节,a占1个字节,刚好是b类型的1倍,所以b直接放在a后面

③再放c,c是int型变量,占4个字节,因为每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,所以前面空两格,这样的话前面刚好4个字节,所以c放在5的位置

④最后放d,d是double型变量,占8个字节,前面的变量已经占了8个字节(包括空出来的)所以d直接放在下一行

如上,该结构体一共占2×8个字节数,打印结果:

 4、结构体中位域问题

 有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位为此,C 语言又提供了一种数据结构,称为"位域""位段",是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数,每个域有一个域名,位域在本质上就是一种结构类型,不过其成员是按二进位分配的,带有预定义宽度的变量被称为位域,在结构体中可以指定数据占多少位,如

struct A{char a:5;char b:3;
}int main(){struct A a;
}

在一个字节中,一共有八位,而上面a和b刚好能把一个字节占满,故在打印sizeof(a)时,显示出来a占1个字节。遵循的原则,相同的数据类型,在一行中能放的下就放,放不下就重新开一行

(1-8表示位数)

但如果时下面这种情况:

struct A{char a:5;char b:7;
}int main(){struct A a;
}

因为一个字节八位,a占5位,后面剩下3位,不足以存放b的位数,所以b会在新的一行存放7位,故a所占字节数位2。

还有一种,当里面数据类型不一样时,如:

struct A{char a:5;char b:7;int c:9;
}int main(){struct A a;
}

此时sizeof(a)的大小为4个字节,因为a占5位,但是因为b和a的数据类型一样,当一行里放不下b时,b会在下一行(下一个字节)存放,而c与b的数据类型不一样,所以c会在b的后面继续存放,现在已存放了三行,根据结构体中结构体所占字节大小为结构体中最大数据的字节数的整数倍,所以还会在下一行补充一行,故一共占4个字节。如图所示:

 打印结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/19909.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sqlite3交叉编译

1、交叉编译sqllite3可以先从官网下载最新最新的源码进行编译。sqlite3下载sqlite3有两种版本的源代码&#xff0c;sqlite-amalgamation-3420000.zip这种是将所有的操作放到sqlite3中进行使用的。虽然官方推荐使用这种方法。但是对于嵌入式移植还是使用sqlite-autoconf-3420000…

WebGPU实战3D电商

在过去的几年里&#xff0c;我们一直在为 WebGPU 编写新版本的 Babylon.js 引擎。 随着下一代 Web 3D 即将在Chrome 102~103版本上公开WebGPU 1.0 &#xff0c;人们的兴奋情绪与日俱增。 在这篇博文中&#xff0c;我将快速概述这个新的 Babylon.js WebGPU 引擎&#xff0c;并将…

go 爬虫速度控制

go 爬虫速度控制 使用go语言用原生net/http写爬虫如何优雅的控制并发和请求速度控制并发限流并发和限流的区别简单说明有了并发控制为什么还要限流 最总代码 使用go语言用原生net/http写爬虫如何优雅的控制并发和请求速度 go程序的执行效率相对python要快的多&#xff0c;且占…

今天实习第一天,用git

老板问了我是否用过gitee&#xff0c;并且是否用过git&#xff0c;在集成工具中&#xff0c;会git来提交代码。我说没有。 所以&#xff0c;先使用gitee。 01.登录gitee的官网&#xff0c;在此处登录。 02.绑定邮箱&#xff0c;我用的是QQ邮箱。 03.git的历史 git是分布式的…

用OpenCV进行图像分割--进阶篇

1. 引言 大家好&#xff0c;我的图像处理爱好者们&#xff01; 在上一篇幅中&#xff0c;我们简单介绍了图像分割领域中的基础知识&#xff0c;包含基于固定阈值的分割和基于OSTU的分割算法。这一次&#xff0c;我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。 闲…

Java实现站内信

假如后台某个任务比较耗时&#xff0c;这时就需要任务完成时&#xff0c;通知一下用户&#xff0c;如下图&#xff0c;实现站内信的效果 两张表即可实现 t_message_content内容表 CREATE TABLE t_message_content (c_id int(11) NOT NULL AUTO_INCREMENT COMMENT 消息的id,se…

flink-conf.yaml的参数

参数 ⚫jobmanager.memory.process.size&#xff1a;对 JobManager 进程可使用到的全部内存进行配置&#xff0c; 包括 JVM元空间和其他开销&#xff0c;默认为 1600M&#xff0c;可以根据集群规模进行适当调整。⚫ taskmanager.memory.process.size&#xff1a;对 TaskManage…

【全栈开发指南】OAuth2授权获取token调试接口的方式

在我们实际应用接口的调用调试过程中&#xff0c;需要用到token或者刷新token&#xff0c;GitEgg支持OAuth2.0协议进行认证授权&#xff0c;这里介绍说明如何通过Postman获取token和refresh_token并进行接口调试。 1、使用密码模式获取token 根据spring-security-oauth2的实现…

怎么使用文件高速传输,推荐镭速高速文件传输解决方案

​​随着互联网的发展&#xff0c;文件传输越来越频繁&#xff0c;如何实现文件高速传输已经越来越成为企业发展过程中需要解决的问题&#xff0c;在当今的业务中&#xff0c;随着与客户和供应商以及内部系统的所有通信的数据量不断增加&#xff0c;对 高速文件传输解决方案的需…

[静态库和动态库][VS2022]

静态库和动态库 前言&#xff1a;一、静态库二、动态库三、静态库和动态库的使用 前言&#xff1a; 我们写代码&#xff0c;可以分模块去写&#xff0c;最后可以协作&#xff0c;能整合起来&#xff1b; 可以吧代码的实现和声明分离。 比如&#xff1a;我的这篇博客C语言猜拳小…

JavaScript ES6实现继承

1 对象的方法补充 2 原型继承关系图 3 class方式定义类 4 extends实现继承 5 extends实现继承 6 多态概念的理 function 创建的名称如果开头是大写的&#xff0c;那这个创建的不是函数&#xff0c;是创建了类。 ES6-class类中的内容 <!DOCTYPE html> <html lang&…

CUDA编程实战(使用Sobel算子对rgb图片进行边缘检测)

写在前面&#xff0c;本篇文章为一个CUDA实例&#xff0c;使用GPU并行计算对程序进行加速。如果不需要看环境如何配置&#xff0c;可以直接到看代码部分:点击直达 关于如何更改代码和理解代码写在这个地方:点击直达 运行环境&#xff1a; 系统:windows10专业版 显卡:NVIDIA …