C语言编程中的结构体原来这么简单
Posted 一口Linux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言编程中的结构体原来这么简单相关的知识,希望对你有一定的参考价值。
曾经有一个很好的知识点摆在我面前,但是我没有学会,等到经历了许久之后才明白结构体原来这么好用。
结构体在C语言基础教程中都有讲到,只不过讲完之后大部分的人应该都会有这样的疑问。结构体到底是什么?在这里先引用比较官方的说明文字:
"结构体(struct)是指由一系列具有相同类型或不同类型的数据构成的数据集合。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。"
与其用文字说明,不如直接实例说明。下面就以结构体的使用实例来说明结构体的好用之处。
结构体声明
要使用结构体当然少不了结构体的定义规则,声明结构体变量的一般规则如下:
方式一:
typedef struct 结构体名
{
类型1 变量名1;
类型2 变量名2;
...
类型n 变量名n;
}结构体名 结构体变量名1,变量名2,...,变量名n;
方式二:
typedef struct
{
类型1 变量名1;
类型2 变量名2;
...
类型n 变量名n;
}结构体名;
struct 结构体名 结构体变量名1,结构体变量名2,...,结构体变量名n;
两种声明方法基本上一样,不过我喜欢用方式二的声明规则。
定义结构体时前面添加typedef 关键字有什么好处?
typedef 的作用其实跟宏定义#define 差不多,也是用一个新的名字代表旧的名字,比如下面的使用方法对比:
#define P 3.1415 //主要作用是使用P代表3.1415
typedef unsigned char uint8_t; //主要作用是可以使用 uint8_t代表unsigned char去定义变量
在定义结构体前面添加typedef 关键句,其实就是定义结构体的同时使用你新建的结构体名代表了结构体struct 的关键句,使用结构体名定义变量时就不再需要增加struct 关键字了。
知道了结构体是如何定义,下面就看看结构体的一些使用方法吧。
使用结构体封装一组数据
在这先借用《手把手教你学51单片机C语言版》书中的一个例子。
使用过DS1302的应该都知道DS1302的数据有"年月日时分秒星期几"。保存从DS1302读取到的数据的方法有:
把DS1302的七个字节的时间放在一个缓存数组中,然后把数组中的数据稍作转换显示到液晶屏上,这里就存在一个小问题,DS1302时间寄存器并不是常用的"年月日时分秒"的顺序,而是在中间加了一个字节的"星期几",而且每当要用这个时间的时候都要清楚地记得数组的第几个元素表示的是什么,这样一来,一是很容易出错,二是程序的可读性不强。
把每一个元素都定一个明确的变量名字,这样就不容易出错也易读了,但结构上却却显得很零散了。什么方式可以解决上面两种方式出现的问题呢?没错,那就是结构体,可以用结构体来将这一组彼此相关的数据做成一个封装,它们既组成了一个整体,易读不易错,而且可以单独定义其中每一个成员的数据类型。
使用实例如下:
Typedef struct //日期时间结构体定义
{
unsigned int yuar; //年
unsigned int mon;//月
unsigned int day;//日
unsigned int hour;//时
unsigned int min;//分
unsigned int sec;//秒
unsigned int week;//星期
}sTime;
sTime bufTime; //使用结构体名定义一个结构体变量
写法跟一般的变量定义差不多,区别就在于所定义的变量所包含元素不一样。突然想到一个很好的比喻,int、float、char等等关键字代表的是个人,那么结构体声明的变量就代表的是一个团队。如何需要找某个队员只需要找到团队的名字就很容易找到其中的队员。也就是结构体变量的成员的赋值或者取值的问题,写法是
bufTime.yuar=2021;
bufTime.mon=50;
好点的编译器一般写到bufTime.就会显示出结构体变量的所有成员,只需要通过选择就可以。
结构体不仅仅可以声明为变量还可以声明为指针,比如:
sTime *pstime; //声明结构体指针
使用上不一样的就是结构体成员的访问,需要写成
bufTime->yuar=2021;
bufTime->mon=50;
结构体声明数组是一个什么样的玩法
直接上例实例:
//先声明结构体
Typedef struct //结构体定义
{
char name[10]; //姓名
char Stid[10]; //学号
unsigned char clal; //语文成绩
unsigned char math;//数学成绩
unsigned char english; //英语成绩
}Leaguetables;//结构体名
Leaguetables st_lt[20]; //声明一个结构体数组
突然觉得定义一个结构体就像是设计了一张空白的表格,而结构体成员变量就像是表格的列名。
而声明结构体数组就像是表格的行。第一行赋值:
st_lt[0].name="zhangsan";
st_lt[0].Stid="2511254";
st_lt[0].clal=60;
st_lt[0].math=30;
st_lt[0].english=20;
第二,第三行以此类推。这就完成了使用结构体数组保存一张表格的数据。
结构体用在函数的传递参数又是一种什么样的体验
函数,不知现在的你对C语言中的函数是否了解和会用。在刚刚学C语言的时候对于函数还是不太理解,因为不清楚什么时候去声明一个函数来用,直到后来才知道函数的作用和使用函数的好处。
什么是函数,可以这样说,函数就是一段自定义的执行某个功能的代码片段。而这段代码也许其他地方也会用到。就如C语言标准库中的printf()在实际调试的时候很多地方都会使用到,只要把参数传进去就能打印出相应的结果。但是功能实现的过程就只有一处,这就是函数的主要作用。可以很大限度地优化了相同实现功能的过程代码量。
在C语言中,函数分为有参函数,无参函数,有返回值函数和无返回值函数。
有返回值的函数,C语言中的一般数据类型和指针都可以用作函数的返回数据类型,还有自定义的结构体也可以用做函数的返回数据类型。这样函数的返回结果不是一个值,而是一个集合。而无返回值的函数一般用void关键字代替。
有无参函数跟有无返回值函数规则基本上一样。而使用结构体做一个函数的参数的好处之一就是可以缩短单行代码的长度,这个怎么理解看下面这个例子:
一个拟合5次的多项式计算公式封装成函数,计算时需要传入7个参数,不使用结构体时的函数
float calc_adc_flow_5x(float x, float a, float b, float c, float d, float e, float f)
{
return a * x*x*x*x*x + b * x*x*x*x + c * x*x*x + d * x*x + e * x + f;
}
使用结构体时的函数:
//声明一个结构体
typedef struct
{
float coeff_a;
float coeff_b;
float coeff_c;
float coeff_d;
float coeff_e;
float coeff_f;
float coeff_am;//系数适配倍数
}blow_cali_info_t;
float Polynomialfitting(blow_cali_info_t *blow_cin, float x)
{
x=x/blow_cin->coeff_am; //系数匹配
float ftemp=blow_cin->coeff_a * x*x*x*x*x
+ blow_cin->coeff_b * x*x*x*x
+ blow_cin->coeff_c * x*x*x
+ blow_cin->coeff_d * x*x
+ blow_cin->coeff_e * x
+ blow_cin->coeff_f;
return ftemp;
}
对比两个函数可以发现,使用结构体时由七个参数变成了两个,在调用时是不是就缩短了单行的代码长度。
结构体的使用方法还有很多,但基本的就那几种。你还知道结构体的其他使用方法和技巧吗?欢迎留言交流。
以上是关于C语言编程中的结构体原来这么简单的主要内容,如果未能解决你的问题,请参考以下文章
C语言中有个img变量是这么定义的:IMAGE img。IMAGE是啥类型的变量?怎么用能不能详细说一下?