黑马程序员——C语言日志——static和extern

本文详细解释了C语言中static和extern关键字的用法,包括它们如何应用于局部变量、全局变量和函数,以及这些应用带来的作用域和生命周期变化。

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、static和extern修饰局部变量
1、static对局部变量的作用
1)延长局部变量的生命周期,从程序启动退出,但是并没有改变变量的作用域。
2)定义变量的代码在整个程序运行期间仅仅会执行一次。看下面的两段代码,分别用static修饰一个局部变量count和不用static修饰局部变量的情况对比一下


#include "stdlib.h"
void fun()
{
	static int count=0;           //使用static修饰局部变量count
	printf("count=%d\n",count);  //打印count值
	count++;
}
int main(){

        fun();                        //第一次调用fun(),打印count=0,之后count++
	fun();                        //第二次调用fun(),打印count=1,之后count++
	fun();                        //第二次调用fun(),打印count=2,之后count++
    system("pause");                  //DOS窗口停留  
}

打印结果:count=0
          count=1
          count=2

#include"stdio.h"
#include "stdlib.h"
void fun()
{
	int count=0;           //不使用static修饰局部变量count
	printf("count=%d\n",count);  //打印count值
	count++;
}
int main(){

    fun();                            //第一次调用fun(),打印count=0,之后count++
	fun();                        //第二次调用fun(),打印count=1,之后count++
	fun();                        //第二次调用fun(),打印count=2,之后count++
    system("pause");                  //DOS窗口停留  
}
打印结果:count=0
          count=0
          count=0
通过以上两段代码,就能很清楚的说明static的作用了。使用static修饰过的count在第二次fun()被调用的时候,并不是初始化的值0,而是++之后的值1,即说明了上述static在修饰局部变量中的两点


作用。还有一点需要说明的是,static修饰的变量和全局变量一样,如果没有初始化,其值默认为0,即程序中:
static int count=0;  //等价于static int count;
2、extern对局部变量的作用
extern并不能修饰局部变量。
二、static和extern修饰全局变量
全局变量分为:1)内部变量:只能在本文件中访问的变量。
               2)外部变量:可以在其他文件中访问的变量,默认所有全局变量都是外部变量。
1、static修饰全局变量的作用
1)声明一个内部变量和定义一个内部变量,由于静态局部变量的作用于限于一个源文件内,只能为该源文件使用,因此可以避免在其他文件中引起错误。
2)static修饰过的全局变量在其他文件中可以同名。
我们建立一个工程,分别创建main.c、test.c和test.h三个文件,代码如下:

/****main.c******/
#include"stdio.h"
#include "stdlib.h"
#include"test.h"
int count=7;                       //在main.c源文件中定义全局变量count
void main(){
   
     printf("count=%d\n",count);  //打印count值 
     test();                     
    system("pause");              //DOS窗口停留  
}

/****test.c******/
#include"test.h"
static int count=5;       //在test.c源文件中定义一个静态全局变量count
void test()
{
	printf("count=%d",count);
}

/****test.h******/
#include"stdio.h"
void test();                 //声明函数test()
程序运行结果:count=7
              count=5
所以,static修饰的count只能在自己所在文件内使用,和main中的count互不影响。如果test.c中的count没有static修饰,那么程序编译会报错为:count重复定义,即有两个同名的全局变量。
  
2、extern修饰全局变量的作用
extern修饰的全局变量,表示当前变量不仅可以在本文件中使用,也可以在其他文件中使用。
注意:extern修饰的全局变量在不同的文件中不能同名(两个文件必须有包含关系)。如果头文件中没有声明该变量,也可以在当前文件中声明。
我们举例仍然使用上面的工程:

/****main.c******/
#include"stdio.h"
#include "stdlib.h"
#include"test.h"
extern int count;                       //在main.c源文件中声明全局变量count,引用其他文件中定义的变量
void main(){
  // extern int count;                 //此处也可以声明全局变量
     printf("count=%d\n",count);  //打印count值 
     test();                     
    system("pause");              //DOS窗口停留  
}

/****test.c******/
#include"test.h"
 int count=5;       //在test.c源文件中定义一个全局变量count
void test()
{
	printf("count=%d",count);
}

/****test.h******/
#include"stdio.h" 
//extern int count;               //在test.h头文件中也可以声明全局变量count
void test();                 //声明函数test()
程序打印结果:
count=5
count=5
就是说,我们在test.c中定义了一个变量count,而在main,c中使用这个变量,那么就用extern修饰这个变量,即声明变量,就可以在main.c文件中使用这个在其他文件中的变量了。
三、static和extern修饰函数
先看两个概念:内部函数和外部函数。假设有A,B两个文件,内部函数:在A文件中定义的函数,在A文件中访问。外部函数:在B文件中访问在A文件中定义的函数,该函数在B文件中称为外部函数。
1、static修饰的函数是内部函数,只能在定义的那个文件中使用
比如,我们在test.c中定义一个内部函数:

/****test.c******/
#include"test.h"
 int count=5;       //在test.c源文件中定义一个全局变量count
static void test()
{
	printf("count=%d",count);
}
在test.h中声明

/****test.h******/
#include"stdio.h" 
//extern int count;               //在test.h头文件中也可以声明全局变量count
static void test();                 //声明函数test()
那么我们在主函数中去调用这个test()函数
/****main.c******/
#include"stdio.h"
#include "stdlib.h"
#include"test.h"
extern int count;                       //在main.c源文件中声明全局变量count,引用其他文件中定义的变量
void main(){
  
     printf("count=%d\n",count);  //打印count值 
     test();                     
    system("pause");              //DOS窗口停留  
}

程序报错,说没有定义test()函数,所以用static修饰过的函数,不能被其他文件中函数调用。
如果我们在test.c文件中再定义另一个函数fun():

/****test.c******/
#include"test.h"
 int count=5;       //在test.c源文件中定义一个全局变量count
static void test()
{
	printf("count=%d",count);
}
void fun()                              //用这个函数调用test()
{ 
  printf("fun调用test()内部函数\n"); 
  test();

}

/**在test.h中声明***/
/****test.h******/
#include"stdio.h" 
static void test();                 //声明函数test()
void fun();                        //声明函数fun()

我们在主函数中去调用这个fun()函数

/****main.c******/
#include"stdio.h"
#include "stdlib.h"
#include"test.h"
extern int count;                       //在main.c源文件中声明全局变量count,引用其他文件中定义的变量
void main(){
     printf("count=%d\n",count);  //打印count值 
     fun();                     
    system("pause");              //DOS窗口停留  
}

这样调用运行成功,说明static修饰的函数只能被本文件中函数调用。
2、extern声明的函数,可以在本文件中使用,也可以在其他文件中使用。(有没有使用extern都可以在其他文件中使用)
同样是上面的工程,我们将函数test.c中的函数test()用extern修饰:

/****test.c******/
#include"test.h"
 int count=5;       //在test.c源文件中定义一个全局变量count
extern void test()      //用extern修饰函数
{
	printf("count=%d",count);
}

我们在主函数中仍然能够成功调用,所以,extern在修饰函数上不起什么作用。





内容概要:本文提出一种基于融合鱼鹰搜索行为与柯西变异策略的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的关键参数(如模态分量数K惩罚因子α),以实现对滚动轴承振动信号的高效自适应分解,有效抑制模态混叠问题。经过OCSSA优化的VMD对原始信号进行预处理后,将分解得到的本征模态函数(IMF)重构为时频特征矩阵,作为卷积神经网络(CNN)的输入,以自动提取深层次的空间特征;随后,双向长短期记忆网络(BiLSTM)进一步挖掘特征序列中的前后向时序依赖关系,最终实现高精度的故障分类识别。该OCSSA-VMD-CNN-BiLSTM模型在西储大学公开轴承数据集上进行了充分验证,结果表明其在复杂噪声环境下对轴承不同故障类型与程度的诊断准确率显著优于传统方法,充分体现了智能优化算法与深度学习相结合在故障诊断领域的优越性能。; 适合人群:具备信号处理、机器学习及智能优化算法基础知识,从事机械装备状态监测、故障诊断、工业大数据分析等相关领域的科研人员、工程技术人员及高校研究生。; 使用场景及目标:①解决传统VMD参数依赖经验设定导致信号分解效果不稳定的问题;②提升强背景噪声工况变化下滚动轴承早期微弱故障的检测灵敏度与分类准确率;③为智能制造工业互联网背景下的关键设备智能运维与预测性维护提供一套可复现、高性能的技术解决方案。; 阅读建议:此资源以Matlab代码实现为核心,建议读者深入研读算法代码,重点理解OCSSA的寻优机制、VMD参数自适应选择过程以及CNN-BiLSTM的网络构建细节,通过复现完整实验流程,掌握从信号预处理、特征提取到智能分类的全流程关键技术,并尝试在自有数据集上进行迁移应用与性能对比。
源码链接: https://pan.quark.cn/s/a4b39357ea24 接口测试框架(基于json格式、http请求,python3,不兼容python2.x版本) 注:现在基于Excel文件管理测试用例基本实现,) 备注:大家在运行的时候,如果参数不需要key,只需要字典,可以在ddt_case.pycase.py改造parame,注释掉现在的parem,启用新的即可 依赖用例支持用例执行,在testCase的ddt_case.py有实现,逻辑在代码中有写,参数的格式{"name":"$case1=data"}即代表name的值是case1的data字段,简单的实现。 依赖用例是简单的实现,具体在业务上面还有很多复杂的要处理,知识实现了,部分的思路。 (目前在部分window上会出现FileNotFoundError [Errno 2] No such file or directory,这个bug是路径过长,解决方案为吧log日志放在当前目录,或者修改动态生成的文件的名字,给了第一种方式,测试日志放在当前目录) qq交流群:194704520 Alt text 使用的库 requests,绝大部分是基于Python原有的库进行的,这样简单方便, 使用脚本参数分离等思想,尽可能降低代码的耦合度。 如果你不配置钉钉机器人,注释到机器人相关的代码 首先我们来看下我们的目录 Alt text ### 1.Case文件夹用来存放我们的测试用例相关的, test_case用来存储我们的测试数据,Excel管理测试用例,yaml文件管理测试用例,后续要把yaml管理测试用例的也封装出来。 Interface对测试接口相关的封装,包括requests库,发送...
内容概要:本文档围绕“配电网两阶段鲁棒故障恢复研究”展开,提供了完整的Matlab代码实现方案,属于高水平期刊论文的复现资料。研究针对配电网在发生故障后的恢复问题,提出了一种两阶段鲁棒优化方法,有效应对系统中诸如负荷波动、分布式电源出力不确定性等多重不确定因素。第一阶段进行预决策,包括网络重构、关键设备投切等操作;第二阶段则根据实际发生的故障场景进行动态调整与恢复控制,确保系统在故障后仍能安全、稳定、可靠运行。该资源不仅包含可运行的Matlab代码,还隶属于一个涵盖电力系统优化、智能算法、路径规划、机器学习等多个技术方向的综合性科研服务体系。; 适合人群:具备电力系统分析基础、优化理论知识及Matlab编程能力的研究生、科研人员工程技术人员,特别适用于从事智能电网、配电自动化、故障恢复策略、鲁棒优化等领域研究的专业人士。; 使用场景及目标:① 学习并复现顶刊关于配电网故障恢复的先进优化模型;② 掌握两阶段鲁棒优化在电力系统中的建模思路、求解流程与技术细节;③ 利用所提供的Matlab代码进行算法验证、仿真测试,并在此基础上开展扩展性科研工作,如改进模型、引入新约束或应用于其他系统。; 阅读建议:建议结合经典电力系统优化与鲁棒调度相关文献,深入理解两阶段鲁棒优化的数学建模原理与物理背景,通过实际运行调试代码,观察不同参数设置对优化结果的影响,进而掌握算法的核心机制。同时可参考文档中提及的其他相关研究主题,拓展研究视野,推动科研创新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值