c语言struct的作用和用法,c语言struct用法详解-程序员宅基地

技术标签: c语言struct的作用和用法  

3fc9f0174464b230abceb74e36859a48.png

c语言struct用法详解

在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据。结构体的定义形式为:struct 结构体名{

结构体所包含的变量或数组

};

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)。

请看下面的一个例子:struct stu{

char *name; //姓名

int num; //学号

int age; //年龄

char group; //所在学习小组

float score; //成绩

};

stu 为结构体名,它包含了 5 个成员,分别是 name、num、age、group、score。结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化。

注意大括号后面的分号;不能少,这是一条完整的语句。

结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。

像 int、float、char 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

结构体变量

既然结构体是一种数据类型,那么就可以用它来定义变量。例如:

struct stu stu1, stu2;

定义了两个变量 stu1 和 stu2,它们都是 stu 类型,都由 5 个成员组成。注意关键字struct不能少。

stu 就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。

你也可以在定义结构体的同时定义结构体变量:

struct stu{

char *name; //姓名

int num; //学号

int age; //年龄

char group; //所在学习小组

float score; //成绩

} stu1, stu2;

将变量放在结构体定义的最后即可。

如果只需要 stu1、stu2 两个变量,后面不需要再使用结构体名定义其他变量,那么在定义时也可以不给出结构体名,如下所示:

struct{ //没有写 stu

char *name; //姓名

int num; //学号

int age; //年龄

char group; //所在学习小组

float score; //成绩

} stu1, stu2;

这样做书写简单,但是因为没有结构体名,后面就没法用该结构体定义新的变量。

理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似,例如上面的结构体变量 stu1、stu2 的内存分布如下图所示,共占用 4+4+4+1+4 = 17 个字节。

但是在编译器的具体实现中,各个成员之间可能会存在缝隙,对于 stu1、stu2,成员变量 group 和 score 之间就存在 3 个字节的空白填充(见下图)。这样算来,stu1、stu2 其实占用了 17 + 3 = 20 个字节。

关于成员变量之间存在“裂缝”的原因,我们将在《C语言内存精讲》专题中的《C语言内存对齐,提高寻址效率》一节中详细讲解。

成员的获取和赋值

结构体和数组类似,也是一组数据的集合,整体使用没有太大的意义。数组使用下标[ ]获取单个元素,结构体使用点号.获取单个成员。获取结构体成员的一般格式为:结构体变量名.成员名;

通过这种方式可以获取成员的值,也可以给成员赋值:#include

int main(){

struct{

char *name; //姓名

int num; //学号

int age; //年龄

char group; //所在小组

float score; //成绩

} stu1;

//给结构体成员赋值

stu1.name = "Tom";

stu1.num = 12;

stu1.age = 18;

stu1.group = 'A';

stu1.score = 136.5;

//读取结构体成员的值

printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);

return 0;

}

运行结果:

Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

除了可以对成员进行逐一赋值,也可以在定义时整体赋值,例如:struct{

char *name; //姓名

int num; //学号

int age; //年龄

char group; //所在小组

float score; //成绩

} stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

不过整体赋值仅限于定义结构体变量的时候,在使用过程中只能对成员逐一赋值,这和数组的赋值非常类似。

需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。

更多编程相关内容,请关注php中文网编程入门栏目!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_35788791/article/details/116994143

智能推荐

51-无名管道_51博客allen-程序员宅基地

文章浏览阅读1.9k次,点赞6次,收藏4次。这恐怕是最古老的 linux 进程间通信的方式了。这种方式简单而又强大,尤其适合有亲缘关系的进程(通常是父子进程)间通信了。实际上,你或多或少的都用过管道这种通信方式,比如你在使用的 linux 命令中的管道连接符 |。所以,对于管道来说,你应该有一种亲切感。1. 管道为何物?如果你实践过前面我们讲过的使用本地文件进行进程间通信的方式,那么你就可以把管道理解成位于进程内核空间(如果你不记得这个概念,_51博客allen

虚拟化架构种类、特点及优势-程序员宅基地

文章浏览阅读2.1k次。云计算离不开底层的虚拟化技术支持,目前虚拟化技术很多种,云吞铺子分享常见的虚拟化架构种类、特点及优势:虚拟化架构根据在整个系统中的位置不同,虚拟化架构分为以下几种:寄居虚拟化架构裸金属虚拟化架构操作系统虚拟化架构混合虚拟化架构寄居虚拟化架构寄居虚拟化架构指在宿主操作系统之上安装和运行虚拟化程序,依赖于宿主操作系统对设备的支持和物理资源..._虚拟化架构分为哪几种有啥特点

JMeter---BeanShell实现接口前置和后置操作_beanshell后置处理器获取参数-程序员宅基地

文章浏览阅读1.4k次。在JMeter中,可以使用BeanShell脚本来实现接口的前置和后置操作。下面是使用BeanShell脚本实现接口前置和后置操作的步骤:_beanshell后置处理器获取参数

把你的 VS Code 打造成 C++ 开发利器-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏9次。作者:denniszhu ,腾讯 CDG 开发工程师面对大量代码,在开发任务繁重场景下,VSCode 绝对是一把利器。本文虽以 C++为引,但在 python、php、java 等中后台..._vs code c++大纲

c++ 开发工具推荐_c++开发工具-程序员宅基地

文章浏览阅读8k次。CLion 也不错,不过要收费在过去的几年中,要从头开始创建应用程序,开发人员必须付出很多努力。因为要创建软件应用程序,所以从编码,编译,测试,调试,构建和部署开始将需要很多步骤。所有这些不同的阶段将需要安装不同的软件包,并且开发人员难以维护。因此,为了提高生产率并加快软件开发过程,所有对开发必不可少的软件包都集成或组合到称为IDE(集成开发环境)的单个环境中,这使现代软件开发变得更加轻松快捷。典型的IDE必须具有一些功能,例如语法突出显示,自动代码完成,自动保存代码,代码搜索,编译器,重构.._c++开发工具

Java语言实现的有趣问题:你的斗地主能拿多少炸?-程序员宅基地

文章浏览阅读136次。  最近无聊,想知道一下玩斗地主的话我能有多大的概率拿到炸弹(4张同点数牌 或 集齐大小王)。但是我概率学学得不好,于是想到用统计学来试试,随手写了一个程序模拟一下斗地主的发牌过程  面向对象Card  首先依据OOP思想,我把牌看作是一个对象,点数与花色是其属性,为了处理大小王加入了Type属性  public class Card {  Suit suit;  Size s...

随便推点

白话“卡方检验”_期望频数-程序员宅基地

文章浏览阅读1.2w次,点赞20次,收藏38次。白话“卡方检验”“卡方检验”是“假设检验”的一种,用于分析两个“类别”变量之间相关关系,是一种非参数“假设检验”,得出的结论是“两个变量相关”或者“两个变量不相关”,因此又叫“独立性检验”。关于假设检验的先验知识有:总体、样本、点估计、区间估计、显著性水平、置信区间、统计量、枢轴量、分位点、三大分布、中心极限定理(明确正态分布的重要地位)、抽样分布定理。这些知识在《概率论与数理统计》教材的“数..._期望频数

SAP转储订单(STO)_在r3中,你可以在不同的公司代码或同一公司代码下的工厂之间进行货物转储-程序员宅基地

文章浏览阅读7k次,点赞3次,收藏17次。在R3中,你可以在不同的公司代码或同一公司代码下的工厂之间进行货物转储。也就是我们平常所说的库存转储订单(STO),你也可以使用采购和分销功能,那在R3中提供了多少种方式的转储订单呢?SAP官方给出了五种方式:从业务上来讲,还有一种方式是正常的开采购订单、销售订单完成脱离转储订单。虽说这种方式比较麻烦,但实际业务过程中也是不忽视的,在这就不介绍了。 _在r3中,你可以在不同的公司代码或同一公司代码下的工厂之间进行货物转储

linux内存日志在什么位置,Linux操作环境:日志文件内存过大的解决方法-程序员宅基地

文章浏览阅读627次。很多Linux服务器里的应用程序都是无间断的输出日志,这对于服务器的硬盘是一个很大的考验。良许之前也分享过一篇文章,介绍如何让应用程序在后台执行:linux后台执行命令:&与nohup的用法通过以上方法,应用程序的日志会一直输出到日志文件myout.txt里,这个文件也会不断的增大,一直蚕食服务器硬盘。但是,我们都知道,日志对于我们而言是非常重要的,一量应用程序出现bug,或者服务器宕机,..._linux内存日志

【系统架构设计】架构核心知识: 5 系统安全性与保密性设计-程序员宅基地

文章浏览阅读671次。信息摘要是由单向散列函数加密成的固定长度的散列值不可逆的。作用:确保信息的完整性,防篡改。哈希算法生成的哈希值的长度必须是固定的,而输入数据是任意长度,效率高。MD5、SHA属于哈希算法。MD5的散列值为128位,SHA算法的散列值为160位,因此SHA的安全性高一些。

unity3D中射线与模型交点坐标显示_unity显示射线焦点坐标-程序员宅基地

文章浏览阅读3k次,点赞2次,收藏4次。鼠标随意点在模型上射线会射在所点击处,并显示点击处的坐标。代码:using UnityEngine;using System.Collections;public class Test : MonoBehaviour{ void Update() { if (Input.GetMouseButton(0)) { ..._unity显示射线焦点坐标

springboot整合mybatis-plus_文字描述springboot整合mybatis-plus过程-程序员宅基地

文章浏览阅读546次。正如官方所说,mybatis-plus在mybatis的基础上只做增强不做改变,因此其与spring的整合亦非常简单。只需把mybatis的依赖换成mybatis-plus的依赖,再把sqlSessionFactory换成mybatis-plus的即可。_文字描述springboot整合mybatis-plus过程

推荐文章

热门文章

相关标签