基于上述定义的频率动态轨迹的特征指标,建立误差模型函数。依据所研究的频率动态问题,分别在每组确定的系统参数下,首先选取若干个有实际参考意义的频率实测轨迹;其次利用电力系统仿真软件仿真得到频率仿真轨迹;然后通过上述已建立的单功率脱落事件下的误差模型计算误差值,并对这些样本进行两两比较,形成判断矩阵;最后通过对判断矩阵进行求解,得到各个样本的权重系数。......
2023-06-29
静态数组比较常见,数组长度预先定义好,在整个程序中,一旦给定大小后就无法再改变长度,静态数组自己自动负责释放占用的内存。而动态数组长度可以随程序的需要而重新指定大小。动态数组由内存分配函数(malloc)从堆(heap)上分配存储空间,只有当程序执行了分配函数后,才为其分配内存,同时由程序员自己负责释放分配的内存(free)。
在实际的编程中,往往会发生这种情况:即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用静态数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,从而构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。
对于静态数组,其创建和引用都非常方便,使用完也无需释放内存空间,但是创建后无法改变其大小是其致命弱点。对于动态数组,其创建麻烦,使用完必须由程序员自己释放内存空间,否则会引起内存泄露。但动态数组使用非常灵活,能根据程序需要动态分配大小。构建动态数组时,我们本遵循下面的原则:
(1)申请的时候从外层往里层,逐层申请;
(2)释放的时候从里层往外层,逐层释放;
在构建动态数组所需指针的时候,对于构建一维动态数组,需要一维指针;对于二维,则需要一维、二维指针;对于三维,需要一、二、三维指针;依此类推。
1.动态内存分配与释放函数
/*动态内存分配与释放函数*/
void*malloc(unsigned int size);
void*calloc(unsigned int num,unsigned int size);
void*realloc(void*p,unsigned int size);
void free(void*p);
说明:
(1)malloc()函数成功则返回所开辟空间首地址,失败则返回空指针,其功能是向系统申请size字节堆的空间;
calloc()成功则返回所开辟空间首地址,失败则返回空指针,其功能是按类型向系统申请num个size字节堆的空间;
realloc()成功则返回所开辟空间首地址,失败则返回空指针,其功能是将p指向的空间变为个size字节堆的空间;
free()没有返回值,其功能是释放p指向的堆空间;
(2)规定为void*类型,并不是说该函数调用后无返回值,而是返回一个结点的地址,该地址指向的类型为void(无类型或类型不确定),即一段存储区的首址,其具体类型无法确定,只有使用时根据各个域值数据再确定。可以用强制转换的方法将其转换为别的类型。例如:
double*pd=NULL;
pd=(double*)calloc(10,sizeof(double));
上述语句表示将向系统申请10个连续的double类型的存储空间,并用指针pd指向这个连续的空间的首地址。接着用(double)对calloc()函数的返回类型进行转换,以便把double类型数据的地址赋值给指针pd。
(3)使用sizeof的目的是用来计算一种类型占有的字节数,以便适合不同的编译器。
(4)检查动态内存是否分配成功。由于动态分配不一定成功,为此要附加一段异常处理程序,不致程序运行停止,使用户不知所措。通常采用这样的异常处理程序段:
(5)以上四个函数头文件均包含在<stdlib.h>中。
(6)分配的堆空间是没有名字的,只能通过返回的指针找到它。
(7)绝不能对非动态分配存储块使用free()函数,也不能对同一块内存区同时用free()函数释放两次。例如:(www.chuimin.cn)
free(p);
free(p);
(8)调用free()函数时,传入指针指向的内存被释放,但调用函数的指针值可能保持不变,因为p是作为形参传递给了函数。严格来讲,被释放的指针值是无效的,因为它已不再指向所申请的内存区,这时对它的任何使用便可能会可带来问题。所以在释放一个指针指向的内存后,将该指针赋值为0,避免该指针成为野指针。例如:
int*p=(int*)malloc(sizeof(int));
free(p); /*释放p指向内存*/
p=0; /*或者p=NULL,释放p指向的内存后,将p指针赋值为0,避免p指针成为野指针*/
(9)malloc()与calloc()的区别。对于用malloc()分配的内存区间,如果原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会出现问题,因此在使用它之前必须先进行初始化(可用memset()函数将其初始化为0)。但是用calloc()函数分配到的空间在分配时就已经被初始化为0了。当你在calloc()函数和malloc()函数之间作选择时,你需考虑是否要初始化所分配的内存空间,从而来选择相应的函数。
2.动态数组构建过程
以三维整型数组为例“int array[x][y][z];”,先遵循从外到里,逐层申请的原则:
(1)最外层的指针就是数组名array,它是一个三维指针,指向的是array[]。array[]是二维指针,所以给array申请内存空间需要一个三维指针。例如:
int***p=(int***)malloc(x*sizeof(int**)); /*给三维数组array[x][y][z]动态分配内存*/
也可以使用以下语句:
array=(int***)malloc(x*sizeof(int**))/*指针p指向的是array三维数组的第一维,有x个元素,所以要sizeof(x* (int**))*/
(2)次层指针是array[],它是一个二维指针,指向的是array[][]。array[][]是一维指针。例如:
(3)最内层指针是array[][],它是个一维指针,所指向的是array[][][]。array[][][]是个整型常量。所以给array[][]申请内存,程序段如下:
3.动态构建三维数组的内存分配函数
说明如下:
*pArr:指向三维数组首地址;
*x:三维数组第一维元素个数;
*y:三维数组第二维元素个数;
*z:三维数组第三维元素个数。
程序段如下:
4.内存释放函数
程序段如下:
例7.20 多维数组的构建和释放。
有关C语言程序设计 第2版的文章
基于上述定义的频率动态轨迹的特征指标,建立误差模型函数。依据所研究的频率动态问题,分别在每组确定的系统参数下,首先选取若干个有实际参考意义的频率实测轨迹;其次利用电力系统仿真软件仿真得到频率仿真轨迹;然后通过上述已建立的单功率脱落事件下的误差模型计算误差值,并对这些样本进行两两比较,形成判断矩阵;最后通过对判断矩阵进行求解,得到各个样本的权重系数。......
2023-06-29
实现一维动态数组的基本步骤为:①定义合适数据类型的一级指针变量。③将动态分配存储区域的首地址转换为所需要的指针形式赋值给对应的指针变量。④将指针变量名作为一维数组名操作。为了模拟数据,程序中仍然要求被排序数组用随机函数生成。例8.18的程序除了被处理的数组是动态创建的之外,程序的功能和结构在第4章中已经进行了讨论,请读者参照第4章的知识自行分析。使用动态一维数组时,需要注意和直接定义一维数组之间的差异。......
2023-11-20
动态刀具轨迹显示的图形参数设定的内容及操作和图形显示稍有不同,说明如下。4)用MDI面板输入需要进行动态刀具轨迹显示的加工程序号后,按软功能键〖绘图选择〗,选定加工程序。6)按软功能键〖执行〗,LCD显示图10.4-8所示的刀具轨迹初始显示页面。刀具位置显示的操作步骤如下:1)完成上述的刀具轨迹绘制。3)自动执行已生成刀具轨迹的加工程序。......
2023-06-25
下面通过制作物体平抛课件,如图7-29所示,使读者进一步了解利用动画功能制作动态演示课件的方法。本例最终效果可参考本书配套素材“素材与实例”→“第七章”文件夹中的“平抛线.pptx”课件。图7-32为正圆图形添加“向下阶梯”动画效果步骤6拖动幻灯片中正弦波曲线的调节点,调整其大小,并将其移动至幻灯片中的适当位置,如图7-33所示。图7-33调整向下阶梯的大小和位置......
2023-11-16
1976年,Thompson教授首次在主动悬挂系统的研究中采用全状态反馈最优控制理论。随后,D.Hrovat和P.Barak通过某种途径探究了主动悬挂系统的优越性,结果显示安装了半主动和主动悬挂系统的车辆,其各项性能指标提高了很多。1990年,尼桑公司在Infinite Q45车型上装置了液压主动悬挂。此外,所设计的控制系统相对复杂、费用高昂,对主动悬挂系统控制策略的研究与结构设计有待进一步努力探究。......
2023-06-24
1916 年《科学》上有文称概率为“或然率”。1935 年由国立编译馆出版的《数学名词》将“probability”定为“几率”或“概率”。至1956 年中国科学院编写的《数学名词》仍是“几率”和“概率”并用,1958 年中国科学院编写的《俄中数学名词》也未改变。直到1964 年中国科学院编写的《数学名词补编》才开始确定用“概率”一词,至1974 年中国科学院编写的《英汉数学词汇》正式将“probability”译为“概率”。......
2023-11-23
只有第4个问题是专门针对两个程序而言的,在LabVIEW中这种不同程序之间的相互调用称之为“程序的动态调用”。因此,LabVIEW不允许具有相同名字的VI同时载入内存中,即使这些VI存储在不同的路径中。LabVIEW本身就是一种多线程设计的语言。LabVIEW提供了多种动态调用的方式,从底层而言是通过VI服务器技术实现的。图5-42所示为LabVIEW中函数选板的“编程”→“应用程序控制”选板,动态调用所使用的节点都位于这个选板。......
2023-07-02
在第1章里介绍JavaScript特点时,有一项动态性,表示可以在脚本运行过程中创建代码,由浏览器继续执行。图2.3.6使用eval()动态执行JavaScript代码打开Chrome开发者工具,在Elements面板查看网页元素,看到调用eval()函数并没有生成新的