当前位置: 首页 > news >正文

C语言从头学35——struct结构

       C语言内置的数据类型,如char、int、float、double等类型只能包含一个值;虽然数组可以包含多个值,但也只能包含相同类型的数据。现实中,描述一个事物往往需要多种数据类型,如描述一个人需要有姓名 (char*)、身高 (int)、年龄 (int)、住址 (char*) 等,怎样将这些不同基础类型组合到一起呢?由此引出struct结构。
       struct 是自定义数据类型的命令,它的使用大致分三个步骤:a.定义结构体;b.声明结构体变量;c.为结构体变量赋值。
 一、定义结构体
        方法:struct 结构体名 { 属性1;属性2; ...; };  //属性也可以称为成员,或成员属性(两个概念不做区分)
       注意事项:
       1. struct关键字不能缺少,包括声明、使用等各场合,struct 这个关键字都不能省略(使用别名时有些例外);
       2. 结构体名的命名规则和变量名一样;
       3. 属性可以是C语言中的基础数据类型声明的变量,也可以是自定义已经声明的结构体变量;也就是说结构体可以套着另一个结构体使用。
      4. 定义结构体时,所有属性需要用一对{ }括起来,括号内属性后边加分号,大括号后边也加分号,这一点不同于函数。
二、声明结构体变量
     (一)一般声明结构体变量的方式
       格式:struct 结构体名 结构体变量名;
     (二)声明结构体变量也可以在定义结构体时同时进行
       格式:struct 结构体名 { 属性1;属性2; ...; } 结构体变量名;
     (三)还可以用匿名方式声明结构体变量,即无结构体名直接用属性声明出结构体变量
       格式:struct {属性1,属性2,...} 结构体变量名;
     注意事项:
       1.结构体变量名的命名规则也和普通变量名一样,结构体名和结构体变量名不能相同;
       2.声明结构体变量时struct这个关键字不能落下;
       3.结构体变量可以一次声明多个,中间用逗号隔开;结构体变量还可以声明成指针型,也可声明成数组。
       4.结构体变量一经声明,系统就会为其分派内存空间,这个结构体变量就可以使用了,如进行赋值、遍历、修改等;若声明的是指针型变量则情况有些不同(见后)。
三、结构体变量的赋值
     (一)结构体变量通过"."来表示其属性;指针型结构体变量通过"->"来表示其属性,我们可以通过这些方式为其赋值。
       格式:结构体变量名.属性=值; 结构体指针变量名->属性=值;
       注意事项:    
       1. 给字符数组属性赋值时,直接使用 "=" 会报 "不能修改左值" 错误,可以使用strcpy函数(也适用于修改char[]情况 )。
       2.对于指针型结构体变量,变量声明后并没有完全初始化内存空间,所以付值之前要先用malloc函数为其申请空间。
     (二)在声明结构体变量时,通过{ }方式一次性为其赋值。
       格式:struct 结构体名 结构体变量名={值1,值2,...}
       注意事项:
       1.大括号里面的值的顺序,必须与 struct 类型声明时属性的顺序一致。
       2.初始化的属性少于声明时的属性,这时剩下的那些属性都会初始化为0,仅限于{ }方式赋初值。
四、结构体的别名
       我们经常在C或C++的底层代码中看见 "typedef" 这样的命令,这个命令可以为结构体起别名,结构体起了别名后就不用总想着"struct"这个关键字了;也就是说给结构体起别名是省略struct关键字的途径。
       格式:typedef struct 结构体名 {属性1,属性2, ...}  结构体别名;
       使用方式:结构体别名 结构体变量; //声明以后再使用结构体就可省略struct关键字
五、结构体的内存空间占用
       struct结构体占用的内存空间,不一定是各个属性占用内存空间的简单相加,所以为了获得结构体(变量)的内存占用,可以直接使用sizeof计算。
六、举例程序:

#define _CRT_SECURE_NO_WARNINGS //VS中使用strcpy需要
#include <stdio.h>
#include<stdlib.h>
#include<string.h> //VS中使用strcpy需要
int main()
{
//一、定义结构体struct Person //定义了包含四个属性的结构体 Person{char name[64]; //姓名int height; //身高int age; //年龄char addr[256]; //住址};
//二、声明结构体变量struct Person myPerson; //利用结构体Person声明结构体变量myPersonstruct Chair //定义结构体Chair同时声明结构体变量 pChair{char material[64]; //材质int price; //价格} *pChair; //注意:由于pChair是指针,故此时系统并未给其分派内存空间struct //匿名方式声明结构体变量myComputer{char cpu[64]; //cpu型号char mainboard[64]; //主板char GrapCard[64];//显卡} myComputer = {"xxxx","yyyy","zzzz"};
//三、结构体变量的赋值//1、为结构体变量赋值(修改值同理)strcpy(myPerson.name,"WangEr"); //数组名表示常量,不允许出现在“=”的左边(当做左值)myPerson.height = 177;myPerson.age = 35;strcpy(myPerson.addr, "x街x排xxx号");//访问printf("结构体变量myPerson数据:name %s height %i age %i addr %s\n", myPerson.name, myPerson.height, myPerson.age, myPerson.addr);//2、为指针型结构体变量赋值pChair = (struct Chair*)malloc(sizeof(struct Chair)); //需要增加的步骤申请空间if (pChair == NULL)return 0; //判断空间是否申请成功strcpy(pChair->material, "松木");pChair->price = 500;//访问printf("结构体变量pChair数据:material %s price %i\n", pChair->material, pChair->price);//3、声明结构体变量时使用{ }同时赋值struct Chair yourChair = {"金属",300 };//访问printf("结构体变量yourChair数据:material %s price %i\n", yourChair.material, yourChair.price);
//四、结构体别名typedef struct Car //为结构体起了别名 MyCar{char* brand;char* color;float length;float weight;} MyCar;//用MyCar声明结构体变量并附初值MyCar myCar = { "Toyota","gray",4.3,1.8 };//访问printf("结构体变量myCar数据:brand %s, Color %s, length %f, weihgt %f\n", myCar.brand,myCar.color,myCar.length,myCar.weight);
//五、结构体占用内存空间printf("Person占用内存空间%d\n", (int)sizeof(struct Person)); //使用结构体printf("myCar占用内存空间%d\n", (int)sizeof(myCar)); //使用结构体变量getchar();return 0;
}

运行结果:
结构体变量myPerson数据:name WangEr height 177 age 35 addr x街x排xxx号
结构体变量pChair数据:material 松木 price 500
结构体变量yourChair数据:material 金属 price 300
结构体变量myCar数据:brand Toyota, Color gray, length 4.300000, weihgt 1.800000
Person占用内存空间328
myCar占用内存空间24

相关文章:

  • Web开发:卡片翻转效果(HTML、CSS)
  • 文心一言:如何备考软考架构师
  • MySQL第一次作业
  • 数据库day2
  • 伪元素::before :: after的用法?
  • 微软GraphRAG +本地模型+Gradio 简单测试笔记
  • 【C#】Array和List
  • 深入解析公有IP与私有IP:地址分配与使用限制
  • 智慧农业新纪元:解锁新质生产力,加速产业数字化转型
  • liosam复现
  • 测试面试宝典(六)—— 请回答集成测试和系统测试的区别,以及它们的应用场景主要是什么?
  • 索引堆及其优化
  • Qt模型/视图架构——委托(delegate)
  • 【日常记录】【CSS】display:inline 的样式截断
  • Java基础笔记(面试题)
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【5+】跨webview多页面 触发事件(二)
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Android 架构优化~MVP 架构改造
  • ES6 学习笔记(一)let,const和解构赋值
  • ESLint简单操作
  • JS实现简单的MVC模式开发小游戏
  • MQ框架的比较
  • python 装饰器(一)
  • Sublime Text 2/3 绑定Eclipse快捷键
  • 复习Javascript专题(四):js中的深浅拷贝
  • 开源地图数据可视化库——mapnik
  • UI设计初学者应该如何入门?
  • ​一些不规范的GTID使用场景
  • #VERDI# 关于如何查看FSM状态机的方法
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (1)SpringCloud 整合Python
  • (2015)JS ES6 必知的十个 特性
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (zt)最盛行的警世狂言(爆笑)
  • (翻译)terry crowley: 写给程序员
  • (附源码)ssm码农论坛 毕业设计 231126
  • (黑马C++)L06 重载与继承
  • (蓝桥杯每日一题)love
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (南京观海微电子)——I3C协议介绍
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三)uboot源码分析
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)visual stdio 书签功能介绍
  • (转)四层和七层负载均衡的区别
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • 、写入Shellcode到注册表上线
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .bat文件调用java类的main方法
  • .naturalWidth 和naturalHeight属性,