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

C 语言程序设计---结构体、共用体、动态存储分配、defi

gowuye 2024-04-25 04:41 3 浏览 0 评论

本篇文章是 C 语言入门级别的最后一篇文章,到此为止,写了整整十篇 C 语言入门文章,均原创,之后会写 C 语言进阶之旅,在基础上进行拔高。

结构体与共用体

1、

结构体

1学生成绩,对于每一个学生,需要考察的一些信息,这就是现实问题

2char Id[9]; //学号

3char Name[15]; //姓名

4int Age; //年龄

5double Score; //成绩

要管理学生,每个学生要考虑的维度比较多,没有哪一种数据类型可以很好的刻画这种关系,此时就需要多个类型来共同定义,形成新的数据类型,也就是结构体!

1struct STUDENT_INFO { //结构体定义

2 char Id[9];

3 char Name[15];

4 int Age;

5 double Score;

6};

7

8struct STUDENT_INFO a; //这个 a 就是结构体数据类型的一个实例,里面是包含那么几个变量的。

9//结构体的长度是所有成员的长度之和

结构体是 C 语言具有“自我扩充能力”的重要机制。

C 语言的基本数据类型有七大类型,这些类型都是由 C 系统提前确定的;而结构体类型是由用户根据自身需要而定义的,是 C 系统本身不具备的,这是 C 语言革命性的一步。

结构体是对 C 语言数据类型的强力扩充!

注意:结构体的定义本身仅仅是“设计、蓝图”,并不占内存空间,当将其实例化后,这个实例才真正的占用存储空间。

. 运算符,结构体实例取其成员的运算符;

-> 运算符,指向结构体实例的指针取其成员的运算符;

定义结构体时,赋初值的初值顺序,必须保证与结构体中成员数据类型是一致的;两个完全一模一样的结构体实例,之间是可以进行赋值操作的。

2、

共用体

1union TEST {

2 int a;

3 char b;

4 double c;

5}

6

7union TEST a, *p = &a;

8a.a <==> p->a

9a.b <==> p->b

10a.c <==> p->c

11//两边表达的是一个意思,就是取共用体成员的值

共用体的诸成员共同使用同一起始地址空间。

共用体内存映像图

共用体空间大小取决于共用体中,长度最长的成员的长度。

1sizeof(union TEST) -> 8B

宏定义与用户自定义类型

1、

宏定义

#define 标识符,被替换的信息(这里不能随便出现分号 ;)

1#define PI 3.1415926

2...

3 a = PI * r * r; <=> a = 3.1415926 * r * r;

4

5#define NUM 3+4

6...

7 a = NUM * 3 / NUM; <=> a = 3+4 * 3 / 3+4

8

9//深入理解:只替换,不计算

宏替换不能改变运算量,就是简简单单的完全替换就好。

宏替换被广泛使用的关键在于以下两点:

(1)、提高程序的可维护性

就是针对同一个数字,可能在代码中多次出现,为了方便修改,上面用个宏替换,可以达到只修改一处,其他的地方都被修改的好处。

(2)、提高程序的可读性

1#define TRUE 1

2#define FALSE 0

3#define MAX_COUNT 5

4...

5

6while (ok != TRUE && num < MAX_COUNT) {

7

8}

用宏替换,便于理解每一个数字所代表的人文化含义,可以知道代表的是什么意思。

神仙数字:是指在程序中出现的常量数值,尤其是整型常量数值(一看根本不知道是啥意思)

2、

用户自定义类型

typedef 是关键字

格式:typedef 已有类型 新类型;

1typedef int a, b, c;

2//上述语句将产生 3 个新的数据类型,分别为:a, b, c

3int n; <=> a n; //此时 a 就代表 int 数据类型

1#define DI int *

2typedef int * TI; //这条语句所产生的新类型是 TI,其对应的数据类型是 int *

其实用define、typedef 声明新的数据类型,两者在碰到指针、数组、以及结构体时,所体现的情况均不一样,一定要小心分析这些情况,尽量用 typedef 声明你想要的新数据类型,具体的在 C 语言进阶中写。

动态存储分配

1、

静态存储分配:以前所定义的变量,数组统统属于静态存储分配方式。

1int a, b[50];

在源程序级别,用静态存储分配定义的变量和数组,其空间大小一经定义,终生不变!所以说是“静态”的,这使得程序的适应性受到了极大的限制。

我此时希望代码在运行的过程中,根据我们临时需要,“动态”地申请存储空间。

2、

动态存储分配是通过两个函数完成的:

malloc() 和 free()

前者用来申请空间,后者用来释放空间

1#include <malloc.h>

2

3int *p;

4p = (int *)malloc(1000); //申请了 1000B 空间,也就是 250 个 int 元素的数组

5//到了这里,C 语言的数组彻底失去它存在的意义!

free(首地址); //释放以 p 的值为首地址的空间。

举 2 个例子:

(1)、

1#include <malloc.h>

2

3int *p; i;

4for (i = 0; i < 3; i++) {

5 p = (int *)malloc(sizeof(int) * 30);

6}

7...

8

9for (i = 0; i < 3; i++) {

10 free(p); //释放以 p 的值为首地址的空间

11}

分析:

A、多次申请空间,将所得到的空间的首地址赋值给 p 变量;由于赋值的特点是覆盖,因此,最终 p 变量中仅保持了最后一次申请得到的空间的首地址,以前所申请空间的首地址被覆盖了(遗失了);使得那些空间不但不能再使用,甚至还不能释放!这称为“内存泄露”!

B、free(p) 进行了多次对同一首地址空间的释放操作,这是致命的运行时错误!

(2)、

1#include <malloc.h>

2#include <stdio.h>

3

4int *fun() {

5 int a[20]; //动态存储分配将不会出现以下的问题

6

7 return a;

8}

9

10int main (void) {

11 int *p1;

12

13 p1 = fun();

14 free(p1);

15}

分析:

A、在 fun() 函数中定义的数组 a,是 fun() 函数的“私有”数组,只有 fun() 函数对其能进行操作;而且数组 a 随着 fun() 函数运行结束,而被 C 自动地释放空间。

B、fun() 函数将一个已经释放了空间的首地址,以函数返回值方式回传给主函数中的指针变量 p1,使得 p1 指向了一个已经释放了(不能对其进行任何操作)的空间;如果出现了 *p1 或者 p1[1]、p1[2] 这样的操作,将会出现“内存非法访问”的错误。

C、程序执行到 free(p1); 将彻底失败,因为,OS 根本无法找到以 p1 的值为首地址的空间进行释放操作!

对于以上的 2 个例子,多琢磨,自己多想一下,理解清楚了,也就没那么难了,对于问题,不要总觉得简单,沉下心来好好学习才是王道!

C 语言程序设计---入门篇,我算是写完了,一共写了 10 篇文章,希望各位有时间了,好好看看,仔细研究;我写的比较基础,比较简单,也好理解,不管我写的怎么样,我愿意把这些基础分享出来,这些都是我的原创,希望在你学 C 的路上能帮到你!

C 入门写完了,C 进阶要来了,这才仅仅是开始。。。

相关推荐

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

取消回复欢迎 发表评论: