验证:两个文件同时引用同一.h头文件时,若头文件中仅包含static函数与变量,则在两个文件中的内存区域中独立存在

2 篇文章 0 订阅

特性与问题验证

static函数的作用域为当前文件,如果仅将static函数/变量定义到头文件中,而该头文件被不同的文件引用
这并不会发生multiple define的错误,其原因在于对于两个文件而言,在引用头文件后存在独立的static函数,只是名字一样而已。

测试:

  1. 使用两个文件引用相同头文件(只有static&&不加预编译指令)
  2. 使用两个文件引用相同头文件(有其他变量&&不加预编译指令)
  3. 使用两个文件引用相同头文件(有其他变量&&加预编译指令)
  4. 两种修正方法与相关知识点
  5. 问题

1. 使用两个文件引用相同头文件(只有static&&不加预编译指令)

头文件:fun_static.h

// #ifndef FUN_STATIC_H
// #define FUN_STATIC_H
#include <iostream>

using namespace std;
static int count1 = 0;          

static void func(int count){
    static int count2 = 0;      

    cout << "this is a static function 第" << count << "次调用" <<endl;

    cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;

    cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
    count1++;count2++;
}
// #endif

两个.cpp文件:b.cpp 与 c.cpp

/*文件b.cpp*/
#include "fun_static.h"
static int a = 5;
static int count = 1;

void b_fun(void){
    func(count);
}
/*文件c.cpp*/
#include "fun_static.h"

static int count = 0;

extern void b_fun(void);

int main(void)
{
    func(count);
    b_fun();
    return 0;
}

运行结果与说明:
在这里插入图片描述

main调用头文件中的func函数 、调用外部引用的b.cpp文件中的b_fun函数。
func函数头文件中定义的static函数
b_ fun函数b.cpp中定义的static函数
count1头文件中定义的静态变量
count2头文件中静态函数func中定义的静态变量
count两个cpp文件中分别定义的静态变量

主要分析
在这里插入图片描述
count1说明头文件中的静态变量count1在两个函数中被调用时,并非指向同一变量地址,静态变量没有变化
count2进一步说明,函数地址也不同。

2.使用两个文件引用相同头文件(有其他变量&&不加预编译指令)

只需将.h文件中的count1修改为非静态变量、func修改为非静态函数

// #ifndef FUN_STATIC_H
// #define FUN_STATIC_H
#include <iostream>

using namespace std;
int count1 = 0;          
void func(int count){
    static int count2 = 0;      

    cout << "this is a static function 第" << count << "次调用" <<endl;

    cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;

    cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
    count1++;count2++;
}

// #endif

执行结果:这俩东西都multiple define了。
在这里插入图片描述

3.使用两个文件引用相同头文件(有其他变量&&加预编译指令)

将上面的.h文件中的预编译注释删除,还是会报错

在这里插入图片描述
其原因在于,对于C++来说,编译过程是独立进行的,生成.o文件后进行链接时,变量和函数已经发生了重定义。

4. 两种修正方法与相关知识点

4.1 使用Inline内联函数

内联函数可以被重定义,这是编译器允许的,因为其本质是在对函数代码进行替换,而不是单独编译通过链接器把地址连上。

头文件fun_static.h

#ifndef FUN_STATIC_H
#define FUN_STATIC_H
#include <iostream>

using namespace std;
static int count1 = 0;          
inline void func(int count){
    static int count2 = 0;      
    cout << "this is a static function 第" << count << "次调用" <<endl;
    cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
    cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
    count1++;count2++;
}

#endif

而变量若不增加文件只能是使用static。
在这里插入图片描述
可以看出,count2发生变化,这是由于从最初的static变成inline后,不会单独分配空间了。
相关知识点如果不清楚可以看这个:头文件相关

4.2 使用单独的文件进行定义

fun_static.h

#ifndef FUN_STATIC_H
#define FUN_STATIC_H
#include <iostream>

using namespace std;
extern int count1;           
void func(int count);

#endif

fun_static.cpp

#include "fun_static.h"
int count1 = 0;          
void func(int count){
	static int count2 = 0;      
	cout << "this is a static function 第" << count << "次调用" <<endl;
	cout << "count1为在fun_static.h文件中定义的静态变量 "<< count1 << endl;
	cout << "count2为在fun_static.h文件定义的静态函数func中定义的静态局部变量 "<< count2 << endl;
	count1++;count2++;
}

在这里插入图片描述
关于外部引用extern的使用可以看extern相关文

问题

为什么使用inline和使用两个文件时,count1作为头文件中的静态变量,没有生成两个副本,而是被改变了数值。(期望大神解答)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: static关键字可以用于限制变量函数的作用域,使其只在当前文件可见,不能被其他文件访问。在.c文件static可以用于定义静态变量和静态函数。静态变量只能在定义它的函数使用,不会对其他函数产生影响。静态函数只能在定义它的文件调用,不能被其他文件调用。在.h文件static通常用于定义静态函数的声明,以避免与其他文件的同名函数发生冲突。如果在.h文件定义静态变量,由于每个包含头文件的.c文件都会拥有该变量的一个副本,容易造成重复定义错误。因此,通常不建议在.h文件定义静态变量。 ### 回答2: 在C语言,可以使用static来限制变量函数的作用域。在.h文件和.c文件static的使用方式有所不同。 在.h文件,如果我们将函数变量声明为static,那么它们的作用域将被限制在当前文件。这意味着在其他文件无法直接访问这些变量函数,可以避免命名冲突。通常,在.h文件不使用static来声明变量,因为.h文件是用于定义接口和声明函数头文件。 在.c文件,可以使用static来定义全局或局部变量。当在函数内部使用static关键字声明变量,该变量的作用域仅限于当前函数。它被称为局部静态变量,每次函数运行后,变量的值都会被保留下来,不会被销毁。这对于需要在函数调用之间保持状态的情况非常有用。 当在函数外部使用static声明变量,该变量将具有文件作用域,只能在当前.c文件访问。这对于希望隐藏变量函数的实现细节的情况非常有用。文件作用域的静态变量在程序的整个运行期间都存在,且在程序开始运行初始化。 另外,在.c文件,如果将函数声明为static,则该函数将具有文件作用域,只能在当前.c文件使用。这意味着其他文件无法直接调用或访问该函数。通过将函数声明为static,可以隐藏函数的实现细节,提高代码的封装性。 综上所述,static关键字可以用于控制变量函数的作用域,通常在.h文件避免使用static来声明变量,在.c文件可以使用static来定义全局或局部变量,并且可以将函数声明为static来隐藏函数的实现细节。 ### 回答3: 在.c和.h文件static关键字可以用于函数变量的声明和定义上。 对于函数,在.c文件使用static关键字声明一个局部函数,该函数仅在当前文件可见,不能被其他文件调用。这种方法也称为“静态函数”。在.h文件不需要使用static关键字声明函数,因为.h文件是用来声明和定义公共函数的。 对于变量,在.c文件使用static关键字声明一个静态变量,该变量只能在当前文件访问,其他文件无法访问。这样可以避免命名冲突并增加变量的安全性。在.h文件一般不会使用static关键字声明变量,因为.h文件是用来声明公共变量的。 总结来说,static关键字在.c文件用于声明和定义局部函数和局部变量,这些函数变量只在当前文件可见。而在.h文件,不需要使用static关键字声明函数变量,因为.h文件是用来声明和定义公共函数变量的,可以被其他文件调用和访问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值