编程技术是改变世界的力量。
本站
当前位置:网站首页 > 后端语言 > 正文

嵌入式C语言之----结构体初探(嵌入式c语言100例)

gowuye 2024-04-25 04:40 10 浏览 0 评论

引言

不管什么样的编程语言,数据类型的不断衍生都是为了不同场合对其进行不同处理或管理。 比如单一的变量,我们可以定义成char, short,,int,float, double等;而如果需要管理多个同一类型的数据就可以使用数组来统一管理;那么如果是不同的数据类型,但是彼此是相关联的呢? 此时就可以使用结构体来统一管理,这也是面对对象的基本思想。比如一个学生,他有如下信息: 名字(char *), 年龄(uint8), 成绩(float)等。今天我们就来说说结构体的基本使用,后续再深入研究。

结构体的定义

  1. 使用struct关键字定义原生结构体类型
struct people{
  
	char name[20];
	int age;
};
  1. 使用typedef类型自定义结构体类型
typedef struct people1{
	
	char name[20];
	int age;
	
}people1_t;

两种方式的有何不同呢? 第一种属于原生结构体类型,在定义变量之前,都需要加上struct people

struct people p1;

而第二种使用typedef关键字自定义了people_t类型(people1_t等同于struct people1), 即在定义变量时,只需要在变量之前写上people_t即刻。

people1_t p2;

这两种方式都可,用户根据自己的习惯选择其中一种即刻,个人推荐第二种,定义比较方便~

定义结构体变量和初始化

  • 如上所述,使用第一种struct people定义结构体变量时,有如下方式:
struct people{
	
	char name[20];
	int age;
};

int main(void)
{
	struct people p1;  //使用struct people定义变量p1
	
	return 0;
}

或:

//定义类型的同时定义变量
struct student{
	
	char name[20];
	int age;
}std;

int main(void)
{
	std.age =23;	//直接使用std结构体变量	
	
	return 0;
}
  • 使用typedef方式定义结构体变量
typedef struct people1{
	
	char name[20];
	int age;
	
}people1_t;


int main(void)
{
	people1_t p2;
	

	return 0;
}

接下来我们再介绍结构体的两种方式初始化:

#include <stdio.h>
#include <string.h>

struct people{
	
	char name[20];
	int age;
};

typedef struct people1{
	
	char name[20];
	int age;
	
}people1_t;

int main(void)
{
	//方式一:在定义的变量的同时初始化
	struct people p1 ={			
		.name = "xiaoming",
		.age = 23
	};
	
	people1_t p2;
	//方式二: 定义变量后,再对其初始化
	strcpy(&p2.name[0], "xiaohong");
	p2.age = 45;
	
	printf("p1.name = %s, age = %d.\n", p1.name, p1.age);
	printf("p2.name = %s, age = %d.\n", p2.name, p2.age);
	
	return 0;
}

编译运行:

结构体的元素访问

在C语言中有两种方式访问,分别是"."和"->", 具体参考如下代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct people{
	
	char name[20];
	int age;
};

typedef struct people1{
	
	char name[20];
	int age;
	
}people1_t;

int main(void)
{
	//定义结构体变量,并初始化
	struct people p1 ={			
		.name = "xiaoming",
		.age = 18
	};
	//定义结构体指针变量
	people1_t *p2 = NULL;
	
	//申请people1_t结构体大小的堆内存空间,并将得到的起始地址赋予p2
	p2 = (people1_t *)malloc(sizeof(people1_t));
	if(NULL != p2)
	{
		//初始化
		strcpy(&p2->name[0], "xiaohong");
		p2->age = 26;
	}
	
	
	//结构体变量通过'.'来访问其元素
	printf("p1.name = %s, age = %d.\n", p1.name, p1.age);
	
	//结构体变量通过'->'来访问其元素
	printf("p2.name = %s, age = %d.\n", p2->name, p2->age);
}

编译运行结果:

以上两种方式都是使用下标式访问结构体元素, 那么如何使用指针方式访问呢?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


struct my_test{
	int a;			//4
	double b;		//8
	char c;			//1
};

int main(void)
{
	struct my_test s1;
	
	s1.a = 12;
	s1.b = 3.4;
	s1.c = 'a';
	
	int *p1  =  (int *)&s1;
	double *p2 = (double *)((long unsigned int)&s1 + 8);
	char *p3 = (char *)((long unsigned int)&s1 + 8 + 8);
	
	printf("s1.a = %d.\n", s1.a);
	printf("s1.b = %.1f.\n", s1.b);
	printf("s1.c = %c.\n", s1.c);
	
	printf("=====================\n");
	
	printf("*p1 = %d.\n", *p1);
	printf("*p2 = %.1f.\n", *p2);
	printf("*p3 = %c.\n", *p3);
}

分析:

  • int *p1 = (int *)&s1,其中&s1为结构体的起始地址,也是首元素a的地址,因此可以通过类型转化后赋值给p1(int *类型,指向int类型的变量a)
  • double *p2 = (double *)((long unsigned int)&s1 + 8); 其中因为&s1是作为结构体地址,本身是带有数据类型的,我们通过(long unsigned int)将其转化成普通的长整型数值,然后再加上a(8字节)的长度,之后的地址就是结构体第二个元素b的地址了,于是乎将得到的地址转化成double *类型赋值给p2,通过p2来访问。
  • char *p3 = (char *)((long unsigned int)&s1 + 8 + 8); 与上步骤分析一致, 首先将&s1转化成普通的普通的长整型数值,然后加上元素a 和 元素b的数据类型长度,就得到了元素c的地址,再赋值给p3,通过p3来访问结构体元素c。

编译运行结果:

总结

从数组到结构体的进步之处:数组有2个明显的缺陷:第一个是定义时必须明确给出大小,且这个大小在以后不能再更改(这里不考虑可变数组);第二个是数组要求所有的元素的类型必须一致。

结构体就完美解决了数组的第二个缺陷的,可以将结构体理解为一个其中元素类型可以不相同的数组。结构体完全可以取代数组,只是在数组可用的范围内数组比结构体更简单,使用更方便。


相关推荐

R语言数据挖掘实践——支持向量机的常用函数
R语言数据挖掘实践——支持向量机的常用函数

e1071包是R语言中用于支持向量机建模与分析的软件包,其主要用于支持向量机的模型构建,提供核心函数svm()来建立支持向量机的基础模型,并且可辅助使用pred...

2024-05-18 12:15 gowuye

R数据分析:如何做聚类分析,实操解析
R数据分析:如何做聚类分析,实操解析

Clusteringisabroadsetoftechniquesforfindingsubgroupsofobservationswi...

2024-05-18 12:14 gowuye

用R语言做数据分析——马赛克图
用R语言做数据分析——马赛克图

到目前为止,我们已经学习了许多可视化定量或连续型变量间关系的方法。但如果变量是类别型的呢?若只观察单个类别型变量,可以使用柱状图或者饼图;若存在两个类别型变量,...

2024-05-18 12:14 gowuye

用R语言做数据分析——方差分析基本概论
用R语言做数据分析——方差分析基本概论

在实际工作中,影响一件事的因素是很多的,我们总是希望通过各种试验来观察各种因素对试验结果的影响。例如,不同的生产厂家、不同的原材料、不同的操作规程,以及不同的技...

2024-05-18 12:14 gowuye

R语言数据分析实战:数据清洗与可视化
R语言数据分析实战:数据清洗与可视化

《R语言数据分析实战:数据清洗与可视化》是一本深入浅出的实践指南,专为对数据分析感兴趣的读者精心编撰。本书旨在帮助读者掌握R语言这一强大的统计分析工具,通过实例...

2024-05-18 12:13 gowuye

用R语言做数据分析——双因素方差分析
用R语言做数据分析——双因素方差分析

在双因素方差分析中,受试者被分配到两因子的交叉类别组中。以基础安装中的Tooth-Growth数据集为例,随机分配60只豚鼠,分别采用两种喂食方法(橙汁或维生素...

2024-05-18 12:13 gowuye

用R语言做数据分析——独立两样本和K样本检验
用R语言做数据分析——独立两样本和K样本检验

coin包简介对于独立性问题,coin包提供了一个进行置换检验的一般性框架,通过这个包,我们可以回答如下问题:响应值与组的分配独立吗?两个数值变量独立吗?两个类...

2024-05-18 12:13 gowuye

用R语言做数据分析——用回归做方差分析
用R语言做数据分析——用回归做方差分析

之前提到方差分析和回归都是广义线性模型的特例,之前文章的所有设计都可以用lm()函数来分析。为了更好地理解输出结果,需要弄明白在拟合模型时,R语言是如何处理类别...

2024-05-18 12:13 gowuye

数据分析R语言——数据结构
数据分析R语言——数据结构

数据分析R语言——数据结构数组数组(array)与矩阵类似,但是维度可以大于2.数组通过array()函数创建。形式如;myarray<-array(v...

2024-05-18 12:13 gowuye

R语言数据挖掘实践——关联分析的常用函数
R语言数据挖掘实践——关联分析的常用函数

arules和arulesViz是R语言中两个专用于关联分析的软件包。其中arules用于关联规则的数字化生成,提供Apriori和Eclat这两种快速挖掘频繁...

2024-05-18 12:12 gowuye

R语言数据挖掘实践——判别分析的常用函数
R语言数据挖掘实践——判别分析的常用函数

判别算法在R语言中实现主要涉及4个软件包中的相关函数,它们依次为MASS、klaR、class和kknn。其中MASS包含有大量实用而先进的统计计数函数及适用数...

2024-05-18 12:12 gowuye

用R语言读取Excel、PDF和JSON文件,终于有人讲明白了
用R语言读取Excel、PDF和JSON文件,终于有人讲明白了

导读:本文将讨论Excel、PDF等文件的读取,以及相应函数的参数设置。作者:刘健邬书豪如需转载请联系华章科技下图总结了主要程序包,希望读者在日常练习和工作中...

2024-05-18 12:12 gowuye

R语言数据挖掘实践——聚类分析的常用函数
R语言数据挖掘实践——聚类分析的常用函数

使用R语言可以轻松实现聚类分析,stats、cluster、fpc和mclust是常用的四个聚类分析软件包。stats主要包含一些基本的统计函数,如用于统计计算...

2024-05-18 12:12 gowuye

用R语言做数据分析——时间序列分类
用R语言做数据分析——时间序列分类

时间序列分类是根据已标注的时间序列建立一个分类模型,然后使用分类模型预测未标记时间序列的类别。从时间序列中抽取出新特征肯呢个有助于提高分类模型的性能。特征提取技...

2024-05-18 12:11 gowuye

一文看懂用R语言读取Excel、PDF和JSON文件(附代码)
一文看懂用R语言读取Excel、PDF和JSON文件(附代码)

导读:本文将讨论Excel、PDF等文件的读取,以及相应函数的参数设置。作者:刘健邬书豪如需转载请联系华章科技下图总结了主要程序包,希望读者在日常练习和工作中...

2024-05-18 12:11 gowuye

取消回复欢迎 发表评论: