【黄色手套22】6话:构造数据类型

news2024/11/25 21:36:10

目录 

序言:

结构体:

结构体数组:

结构体数组的定义和引用 :

使用关键字typedef自定义类型名:

使用typedef语句为数组类型取别名:

结构体所占内存的大小:

结构体的嵌套:

共用体类型:

        共用体类型的声明:

        共用体变量的定义:

        共用体类型所占内存:

枚举类型:

        枚举类型的声明:

        枚举类型的使用:


序言:

构造数据类型:用户自己建立的数据类型(自定义数据类型)。

C语言中的构造数据类型有:数组类型、结构体类型、共用体类型和枚举类型。

结构体:

用户根据自己的需求建立的由不同类型数据组成的数据类型。

即,

结构体这种数据类型它能根据用户需要,方便的存储各种各样的信息。

■.  结构体类型的声明

(1)声明时定义结构体变量

struct 结构体类型名
{

        成员列表;

}结构体变量名;          // 可以在声明时定义结构体变量名
                       // 声明时未定义变量的话,分号(;)勿漏                    

(2)先声明后定义结构体变量

          基本格式:结构体类型名 变量名;

struct student s1;

//s1.id=12345;

■.  结构体成员的使用

     基本格式:结构体变量名.成员名

     结构体成员引用符:.

     例如:

#include<stdio.h>
struct pananzhongxue              //构造结构体,名为“pananzhongxue”
{
	int id;
	int age;
	float zongscore;
	int gender;
	char name[10];
}s1 = {085422103,19,536,1,"chenchen"}, s2;   //声明时定义结构体变量s1,s2,
                                             //并对s1初始化赋值
int main()                        
{                                   //输出“pananzhongxue”结构体类型中的s1的各个数据	                                    
	printf("%d\t%d\t%d\t%f\t%s\n", s1.id, s1.age, s1.gender, s1.zongscore, s1.name);                                           
	return 0;
}

说明:

(1) struct 为结构体关键字

(2)struct pananzhongxue 为结构体类型名

(3)idage... 为结构体成员名

(4)s1s2 为结构体变量

  区分清楚:结构体类型名、结构体成员名以及结构体变量

■.  结构体变量的定义:

  (1)可以在声明时直接定义结构体变量;

  (2)也可以先声明后定义结构体变量(用数据类型名定义结构体变量);

#include<stdio.h>
struct pananzhongxue
{
	int id;
	int age;
	float zongscore;
	int gender;
	char name[10];
}s1, s2;                                 //声明时定义结构体变量s1,s2

int main()
{                                        //声明后定义结构体变量s3
	struct pananzhongxue s3 = {085422103,19,536,1,"xiaohei"};
	printf("%d\t%d\t%d\t%f\t%s\n", s3.id, s3.age, s3.gender, s3.zongscore, s3.name);
	return 0;
}

结构体数组:

结构体类型的数组

■.  结构体数组元素的使用:

结构体数组名[数组下标].成员变量名

  例如:

#include<stdio.h>
struct student
{
	int id;
	int age;
	int height;
	int weight;
	float score;
}arr1[3];                  // 声明一个结构体数组arr1[3]

int main()
{
	arr1[0].id = 085422103;
	printf("%d\n", arr1[0].id);	
	return 0;
}

■.  注意数组类型的成员

  1. 数组类型int的成员,单个数据元素可以直接进行赋值:

#include<stdio.h>
struct pananzhongxue
{
	int id;
	int age;
	float score[3];
	int gender;
	char name[10];
}s1, s2;

int main()
{	
	s2.age[0] = 15;             //数组类型单个数据元素赋值
	s2.age[1] = 11;
	s2.age[2] = 10;
	printf("%f\t%f\t%f\n", s2.age[0], s2.age[1], s2.age[2]);
	return 0;
}

2. 数组类型(如char)的成员不能直接赋值,

    可以用字符串拷贝函数strcpy来完成字符数组的赋值:

#include<stdio.h>
#include<string.h>               //输入字符串处理函数头文件
struct pananzhongxue
{
	int id;
	int age;
	float score;
	int gender;
	char name[10];
}s1,s2;

int main()
{
  strcpy(s1.name, "cc");      //用字符串拷贝函数strcpy来赋值
  printf("%s\n", s1.name);
  return 0;
}

■.  相同结构体类型的成员可以相互赋值:

#include<stdio.h>
#include<string.h>
struct pananzhongxue
{
	int id;
	int age;
	float score[3];
	int gender;
	char name[10];
}s1,s2;

int main()
{
	s2.score[0] = 105;
	s2.score[1] = 91;
	s2.score[2] = 110;
	
	s1.score[0] = s2.score[2];         //进行相互赋值
	s1.score[2] = s2.score[0];
	s1.score[1] = s2.score[1];

	printf("%f\t%f\t%f\n", s2.score[0], s2.score[1], s2.score[2]);
	printf("%f\t%f\t%f\n", s1.score[0], s1.score[1], s1.score[2]);
	return 0;
}

结构体数组的定义和引用 :

#include<stdio.h>
struct student
{
   int id;
   char name[10];
};

int main()
{
   struct student arr1[2]={854221,"chenchen",854222,"chenhnch"};
   printf("id\tname\n);
   for(int i=0;i<2;i++)
  {
      printf("%d\t%s\n",arr1[i].id,arr1[i].name);
  }
  return 0;
}

使用关键字typedef自定义类型名:

关键字typedef:用于给数据类型关键字取别名

typedef的基本格式:

typedef 数据类型名 别名;

        typedef取的别名也需要遵循标识符的命名规则。 

        typedef可以给一个数据类型取多个别名

        typedef一般使用在数据类型名比较长的情况下

例如:

#include<stdio.h>
typedef struct chenchenchenchenchen
{
	int height;
	int weight;
}xxx;

int main(void)
{ 
	xxx s1;                //取别名后需再定义结构体变量名
	s1.height = 172;
	printf("%d\n", s1.height);
	return 0;
}

使用typedef语句为数组类型取别名:

一维数组类型的定义格式:

typedef 数据类型 数组名[常量];

例如:

#include<stdio.h>
typedef struct chenchenchenchenhcne
{
	int id;           
	char name[20];    
	char gender[4];   
	int age;          
	float score[3];   
}CC;

typedef int I[10];      // 定义了一个数组类型I  
                        // 元素类型为int
                        // 元素个数为10
int main(void)
{                                                
	I a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };       // 相当于int a[10]={...};  
                                                  // I换成a即可
	for (int i = 0; i < 10; i++)                  // 可多次定义对象(数组名)
	{
		printf("%d\t", a[i]);
	}
	putchar('\n');
	return 0;
}

结构体所占内存的大小:

计算结构体内存大小时要考虑其内存布局。

系统为了提高计算机访问数据的效率,

在安排结构体中的每个成员时采用内存对齐的方法。

结构体在内存中按统一单元进行存放,
每个单元的大小取决于结构体成员中最大的基本数据类型大小。

即,在结构体中,对不同成员类型的大小,在内存中采取内存对齐的方法以提高运行效率

例如:

#include<stdio.h>
typedef struct student
{
	short id;      //2
	short age;     //2
	char name[5];  //5
	int height;    //4
	int weight;    //4 
	float score;   //4 
}xxx;

int main()
{
	printf("%d\n", sizeof(xxx));       //  24	
	return 0;
}

内存储存如下:

补充: 为什么要内存对齐?

1.为了提高代码的可移植性,和提升CPU访问内存的效率(本质:以空间换时间)。

2.不是所有的硬件平台都能访问任意地址上的数据,某些硬件平台只能在某些地址访问某些特定类型的数据,否则会抛出硬件异常,以及遇到未对齐的边界直接就不进行读取数据。 

结构体的嵌套:

把一个结构体的变量作为另一个结构体的成员。

例如:

#include<stdio.h>
struct student
{
	int id;              
	int height;              
	int weight;          
	char gender[3];        
	char name[10];       
	float score[3];         
}s1,s2,s3;

struct teacher
{
	int id;              
	int height;              
	int weight;          
	char gender[3];        
	char name[10];       
	struct student s1;      // 结构体嵌套
}t1,t2,t3;                  // 结构体类型student中的变量s1是结构体类型teacher中的成员 
                            // teacher中的成员
int main()
{
	t1.s1.id = 85422103;
	printf("%d\n",t1.s1.id);
	return 0;
}

■.  注意,一个结构体类型中可以有本身这种结构体类型的成员吗?

struct teacher
{
	int id;              
	int height;             
	int weight;         
	char gender[3];        
	char name[10];       
	struct teacher t2;     //可以吗?
};

-----会报错:不允许使用不完整的类型。

共用体类型:

用同一段内存单元存放不同类型的变量。

同一个内存单元中,它们在内存中所占字节数不同,但共用同一段内存地址。

共用体类型的声明:

一般格式:

union 共用体类型名
{
  成员列表;
}共用体变量;

共用体变量的定义:

(1)声明时定义;

(2)声明后定义;共用体类型名 变量名;

例如:

#include<stdio.h>
union student
{
	int id;
	float score;
	char a;
	double b;
}t1,t2;

int main()
{
	printf("%d\n", &(t1.id));         //所有输出结果相同
	printf("%d\n", &(t1.score));      //为共用内存的首地址 
	printf("%d\n", &(t1.a));
	printf("%d\n\n", &(t1.b));

	printf("%d\n", &(t1.b));          //下面也是一样的
	printf("%d\n", &t1.b);            //且每次运行会重新随机申请存储空间 
	printf("%d\n", &t1);
    return 0;
}

共用体类型所占内存:

整个共用体类型所占内存是最大成员所占的内存空间(或其整数倍)

例如:

#include<stdio.h>
union student
{
	int id;             //4
	float score[10];    //4*10
	char a;             //1
	double b;           //8 
}t1,t2;

int main()
{
	printf("%d\n", sizeof(union student));  //8*5
    return0;
}

#include<stdio.h>
union student
{
	int id;
	float score;
	char a;
	double b;
}t1,t2;

int main()
{
	printf("%d\n", sizeof(union student));  //8
    return 0;
}

注意:所占内存空间为最大基本数据类型的最小整数倍

例如:

#include<stdio.h>
union student
{
	int id;
	float score;
	char a[10];
	double b;
}t1,t2;

int main()
{
	printf("%d\n", sizeof(union student));  //16
    return0;
}

存储和读取数据时:

#include<stdio.h>
union student
{
	int id;
	float score;
	char a;
	double b;
}t1,t2;

int main()
{
    t1.id = 0x11223344;
	t1.a = 0x55;
	printf("%x\n",t1.id);      //11223355
    printf("%x\n",t1.a);       //55
	return 0;
}

大端模式:

                                                                       

共用体变量只能给一个成员初始化赋值,

共用体同一时刻只能保存一个成员的数据(数据相应位置覆盖)

枚举类型:

枚举类型enum:将类型中所有可能的取值一一列举出来,

             枚举值只能从列举出的范围内取值,

             否则没有意义。

枚举类型可以初步简单理解为取值受限的整型,其值被按照整型数据来处理和运算。 

如果一个变量只有几种可能的值,就可以定义为枚举类型。

枚举类型的声明:

enum 枚举类型名
{
   枚举元素列表;
}枚举类型变量名;

例如:

enum day{
    sun,mon,tue,wed,thu,fri,sat
}weekend,workday;

//声明了一个枚举类型,数据类型名day,
//其变量的取值范围为星期天至星期六,
//声明时定义了两个枚举类型变量weekend和workday。

注意:

声明的枚举类型也可以没有类型名,

但如果需要使用此枚举类型的话,就必须在声明时同时定义变量。

枚举类型的使用:

   C语言中的枚举元素是按照常量进行处理的,所以又称为枚举常量。

   不能因为它们是标识符而把它们当作变量来使用,在使用时是不能对它们赋值的。

sun=0;mon=1;//错误,不能给枚举常量赋值

   每一个枚举元素都代表一个整数,

   C语言编译器按照定义时的顺序默认它们的值为0,1,2,3,4,5,6......

workday=mon;//相当于workday=1;

   枚举常量的引用和输出:

   printf("%d",sun);   //输出整数0 

   枚举变量的引用和输出:

workday=mon;

printf("%d",workday);    // 输出整数1

  我们也可以人为的指定枚举元素的数值,在声明的枚举类型时指出即可。

  例如:

enum weekend{sun=7,mon=1,tue,wed,thu,fri,sat}weekend,workday;

// 星期二2,星期三3,......星期六6

  枚举类型可以用来进行比较和判断

if(workday==mon){......};

if(workday==sat){......};

  示例:

#include<stdio.h>
enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat};

int main()
{
	printf("%d %d %d %d %d %d %d\n", sun, mon, tue, wed, thu, fri, sat);
	return 0;
}
// 输出7 1 2 3 4 5 6

  简单的枚举类型应用示例:

  根据你输入的数字输出对应的星期数

#include<stdio.h>
enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}day;

int main()
{
	while (1)
	{
		scanf("%d", &day);
		switch (day)
		{
		case 7:
			printf("你输入了周日\n");
			break;
		case 6:
			printf("你输入了周六\n");
			break;
		case 5:
			printf("你输入了周五\n");
			break;
		case 4:
			printf("你输入了周四\n");
			break;
		case 3:
			printf("你输入了周三\n");
			break;
		case 2:
			printf("你输入了周二\n");
			break;
		case 1:
			printf("你输入了周一\n");
			break;
		default:
			printf("你输入了无效数字\n");
		}
	}
	return 0;
}

_____________# 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内网穿透——Windows搭建服务器

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

vant 按需导入 vue2

vant 按需导入 vue2 1、通过npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&#xff0c;安装 Vant 2&#xff1a; npm i vantlatest-v2 -S2、自动按需引入组件 babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中…

(Qt+Vs编译环境)报错:引发异常,写入访问权限冲突

起因&#xff1a;在一本Qt的书上看到使用这样的语句 &#xff0c;专门把原有的VS项目模板生成的代码做了修改&#xff0c;如下图所示&#xff1a; UI::MainWindow *ui; ui->setupUI(this); ui->lineEdit->Text(); 然后就开始引发异常&#xff0c;提示访问权限冲突。…

swaggo使用教程

安装与初始化 安装插件 go install github.com/swaggo/swag/cmd/swaglatest 安装依赖 go get -u github.com/swaggo/swag/cmd/swag 在包含main.go文件的项目根目录运行swag init。这将会解析注释并生成需要的文件&#xff08;docs文件夹和docs/docs.go&#xff09;。 swa…

如何快速构建你的AI开放平台?一步步教你!

目录 楔子成品展示后台页面面客端页面成品项目地址 项目源码地址one-apichatgpt-next-web 搭建步骤搭建one-api运行命令命令解释后台配置 搭建chatgpt-next-web运行命令命令解释面客端配置 总结 ✨这里是第七人格的博客✨小七&#xff0c;欢迎您的到来~✨ &#x1f345;系列专栏…

第22章_瑞萨MCU零基础入门系列教程之DMA控制器

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

nginx配置vue前端代理

背景&#xff1a;做一个前后端分离的项目&#xff0c;我这里是vue3 view ts创建的前端项目&#xff0c;在前端配置跨域请求。 一、开发阶段 在vue.config.js中配置devserver的proxy进行代理请求配置&#xff0c;然后将所有请求改为/api开头的即可。但是这样配置只在开发阶段…

数仓主题域和数据域、雪花模型,星型模型和星座模型

数仓模型和领域划分 一、主题域和数据域的差别二、雪花模型&#xff0c;星座模型和星型模型 一、主题域和数据域的差别 明确数据域作为数仓搭建的重要一环&#xff0c;能够让数仓的数据便于管理和应用。 数据域和主题域都是数据仓库中的重要概念&#xff0c;但含义略有不同&am…

【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs Transformers) 的介绍合集(四)

文章目录 一、ResNeSt二、ShuffleNet v2三、FBNet四、Inception-v4五、ResNet-D六、MetaFormer七、PyramidNet八、RevNet九、Convolutional Vision Transformer&#xff08;CVT&#xff09;十、Tokens-To-Token Vision Transformer十一、Self-Attention Network十二、MixNet十三…

高速电路设计笔记----第二章

本章主要讲解的是电阻、电容、电感的选型。 一、电阻&#xff1a;关键还是限流。 1、通常在电源滤波时除了LC外&#xff0c;还会串接一个R。目的是为了降低信号的Q值&#xff0c;防止信号失真。常用于失真电源滤波。&#xff08;例如时钟电源滤波&#xff09; 2、选型的电阻的…

眺望数据应用新态势|第八届腾讯云Techo TVP开发者峰会圆满落幕

引言 在数据驱动的时代&#xff0c;如何有效地利用大数据已经成为了各个行业的重要课题。而随着云计算、人工智能等新兴技术的蓬勃发展&#xff0c;数据技术也随之不断生长并呈现出新的趋势与特点&#xff0c;企业该如何把握数据技术的新脉络&#xff0c;从而洞察数据背后的价…

【动态规划刷题 14】最长递增子序列 摆动序列

673. 最长递增子序列的个数 链接: 673. 最长递增子序列的个数 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列&#xff0c;分别是 [1, 3, 4,…

【校招VIP】产品工作难点之如何平衡团队协作

考点介绍&#xff1a; 对于简历上有实习经验的同学&#xff0c;团队配合和项目推进是一个非常常见的提问点。产品经理经常会面临项目延期&#xff0c;无法上线的情况。基于此&#xff0c;产品经理应该做些什么来保障项目按时上线呢? 产品工作难点之如何平衡团队协作-相关题目…

Linux下创建普通用户遇到的问题及解决办法

在Linux下只有root一个超级用户&#xff0c;但是可以创建多个普通用户的&#xff0c;具体的创建方法如下。 先切换到root用户&#xff0c;使用下面的命令创建用户名为user1(本文均以此用户名为例&#xff0c;注意后续键入指令时不要弄错了)的普通用户。 su root useradd user1 …

interview4-集合篇

一、算法复杂度分析 为什么要进行复杂度分析&#xff1f;因为可以指导你编写出性能更优的代码和评判别人写的代码的好坏。 &#xff08;1&#xff09;时间复杂度分析 时间复杂度是用来评估代码的执行耗时的。 1.假如每行代码的执行耗时一样&#xff1a;1ms 2.分析这段代码总…

跟随算网超人,深度解析算力网络!

随着数字时代全面开启 算力网络已成为当下热点议题 作为信息社会两大基石 算力、网络为何如此重要&#xff1f; 又将如何影响社会发展脉动&#xff1f; 为帮助大家深入了解算力网络 我们特别推出“算网超人”系列科普 下面&#xff0c;请跟随算网超人的步伐 来到该系列的…

uni-app H5使用 tabbars切换,echartst图表变小 宽度只有100px问题解决

问题&#xff1a; 跳转到别tabbars页面之后&#xff0c;再回来&#xff0c;echarts图显示缩小小团子。 原因分析&#xff1a; 在tabs切换中有echarts的话&#xff0c;我们会发现初始化的那个echarts是有宽度的&#xff0c;当点击tabs切换之后&#xff0c;切换过来的echarts只…

Python+requests编写的自动化测试项目

框架产生目的&#xff1a;公司走的是敏捷开发模式&#xff0c;编写这种框架是为了能够满足当前这种发展模式&#xff0c;用于前后端联调之前&#xff08;后端开发完接口&#xff0c;前端还没有将业务处理完毕的时候&#xff09;以及日后回归阶段&#xff0c;方便为自己腾出学(m…

Biome-BGC生态系统模型与Python融合技术:揭秘未来生态预测新趋势

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天…

手机提词器有哪些?简单介绍这一款

手机提词器有哪些&#xff1f;手机提词器在现代社会中越来越受欢迎&#xff0c;原因是它可以帮助人们提高演讲和朗读的效果。使用手机提词器可以让人们更加自信地面对演讲和朗读&#xff0c;不至于出现口误或读错字的情况。此外&#xff0c;手机提词器还可以帮助人们节省时间和…