-
2021-05-25 05:57:40
如何在c语言中定义及引用全局变量?
答案:5 信息版本:手机版
解决时间 2019-10-03 10:30
已解决
2019-10-02 15:19
如何在c语言中定义及引用全局变量?
最佳答案
2019-10-02 16:05
1、全局变量也称为外部变量,它是在函数外部定义的变量。
它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。
只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。
但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。外部变量是在函数外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的
结尾。在此作用域内,全局变量可为各个函数所引用。编译时将外部变量分配在静态存储区。
有时需要在其他文件中使用extern来声明外部变量,以扩展外部变量的作用域。
也可用static声明外部变量,使该变量不能被其他文件引用。有时候他们是一样的,只有稍微一点的区别而已,不用太过于区分的。
2、定义及引用方法:
#ifdef xxx_GLOBALS
#define xxx_EXT#else#define xxx_EXT extern
#endif 上面位于.H 文件中,每个全局变量都加上了xxx_EXT的前缀,xxx代表模块的名字。该模块的.C文件中有以下定义:#define xxx_GLOBALS
当编译器处理.C文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,xxx_GLOBAL没有定义,xxx_EXT被定义为extern,这样用户就可以调用外部全局变量。进阶:在abc.H:#ifdef abc_GLOBALS
#define abc_EXT#else
#define abc_EXT extern#endif
abc_EXT unsigned int Ctr;
同时,abc.H有中以下定义:#define abc_GLOBALS
当编译器处理abc.C时,它使得头文件变成如下所示,因为abc_EXT被设置为空。unsigned int Ctr;
这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C文件时,头文件变成了如下的样子,因为abc_GLOBAL没有定义,所以abc_EXT被定义为extern。extern unsigned int Ctr;
在这种情况下,不产生内存分配,而任何 .C文件都可以使用这些变量。这样的就只需在 .H 文件中定义一次就可以了。
全部回答
1楼
2019-10-02 19:08
如果全局变量在同一个C文件中,则可以直接去使用这个全局变量,就像楼上(zsx10110)举的那个例子一样,但是在另外一个C 文件中还想继续使用这个变量的时候就需要使用extern来声明引用这个全局变量了,比如说你把全局变量定义声明在a.c文件中的,你在b.c文件中也想使用,则在里面加上这句extern int a;(int a是你在a.c中定义的,视实际情况而定)
2楼
2019-10-02 18:28
放置于主函数之前定义的变量。
3楼
2019-10-02 17:31
全局常量定义,在主函数体外部直接调用预处理命令#define 常量名 量值
引用时可以再任意函数体内直接调用该常量名
全局变量定义,变量不存在全局概念,只有相对概念。你可以通过声明作用域来进行声明。比如:
std::a。这就是一种。
4楼
2019-10-02 16:23
举个例子
#includeint a =0;//这里不就是定义了一个全局变量a了吗
int main()
{
printf("%d",a);
}
我要举报
如果感觉以上信息为低俗/不良/侵权的信息,可以点下面链接进行举报,我们会做出相应处理,感谢你的支持!
大家都在看
推荐资讯
更多相关内容 -
python 在一个py文件中调用另一个py文件中的变量以及一个有趣的问题
2021-04-09 17:08:28python 在一个py文件中调用另一个py文件中的变量以及一个有趣的问题 1、在一个py文件中调用另一个py文件中的变量 新建一个py文件,记为t1.py # t1.py m = 2 n = 1 a = m + n print("t1 a=", a) 新建一个py文件,记...python 在一个py文件中调用另一个py文件中的变量以及一个有趣的问题
1、在一个py文件中调用另一个py文件中的变量
新建一个py文件,记为t1.py
# t1.py m = 2 n = 1 a = m + n print("t1 a=", a)
新建一个py文件,记为t2.py
# t2.py m = 0 n = 1 b = m + n print("t2 b=", b)
现如今我在在另外一个文件t3.py中调用t1.py中的变量a和t2.py中的变量b(这3个py文件在同一文件夹下,具体代码如下:
# t3.py from t1 import a from t2 import b c = a + b print("t3 c=", c)
运行后结果如下
2、这里有个有趣的问题
运行t3.py文件后,它把t1.py、t2.py的结果都打印出来了(原因见文末)。如果咱们在t3.py中只是要调用这两个变量a和b,并不想输出前两个文件的结果,该怎么办呢?
简单啊,前两个py文件只需加一行代码即可:
# 修改后的t1.py m = 2 n = 1 a = m + n if __name__ == '__main__': # 这一句里的语句只在此文件中运行 print("t1 a=", a)
# 修改后的t2.py m = 0 n = 1 b = m + n if __name__ == '__main__': # 这一句里的语句只在此文件中运行 print("t2 b=", b)
t3.py不用修改,运行后结果如下
3、出现这个现象的原因是什么?
__name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。# Filename: using_name.py if __name__ == '__main__': print('程序自身在运行') else: print('我来自另一模块')
运行输出如下:
程序自身在运行
import using_name
我来自另一模块说明: 每个模块都有一个
__name__
属性,当其值是'__main__'
时,表明该模块自身在运行,否则是被引入。说明:
__name__
与__main__
底下是双下划线,_ _
是这样去掉中间的那个空格。 -
编写Java程序,创建一个 Person 类,该类中有一个类成员变量 country、一个实例变量 name 和另一个实例变量...
2020-05-09 14:37:44创建一个 Person 类,该类中有一个类成员变量 country、一个实例变量 name 和另一个实例变量 age。 country 表示地区,name 表示姓名,age 表示年龄。 创建 3 个 Person 对象,并分别给这3个对象的属性赋值。 ...返回本章节
返回作业目录
需求说明:
- 创建一个 Person 类,该类中有一个类成员变量 country、一个实例变量 name 和另一个实例变量 age。
- country 表示地区,name 表示姓名,age 表示年龄。
- 创建 3 个 Person 对象,并分别给这3个对象的属性赋值。
- 分别获取3个Person对象的属性。
实现思路:
定义Person类的实现思路如下:
- 创建人类(Person)。
- 定义 int 实例变量 age,String 实例变量 name,String 类变量 country。
- 创建 3 个 Person对象,给 3 个 Person 对象的姓名和年龄赋值,再通过类名给成员变量 country 赋值。
- 创建一个测试类 PersonTest,输出3个Person对象的属性信息。
实现代码:
Person 类
public class Person { static String country; String name; int age; }
test 类
public class test1 { public static void main(String[] args) { Person.country = "云南"; Person p1 = new Person(); p1.name = "小杨"; p1.age = 18; Person p2 = new Person(); p2.name = "小明"; p2.age = 19; Person p3 = new Person(); p3.name = "小金"; p3.age = 20; System.out.println("地区:"+Person.country+"\t姓名:"+p1.name+"\t年龄:"+p1.age); System.out.println("地区:"+Person.country+"\t姓名:"+p2.name+"\t年龄:"+p2.age); System.out.println("地区:"+Person.country+"\t姓名:"+p3.name+"\t年龄:"+p3.age); } }
-
多进程引用动态链接库中的全局变量问题
2019-05-23 16:37:09做法:在console中调用libvlan.so中的两个APIs,分别是设置和获取动态库中一个全局变量的值。 结果:在console中的操作没有问题,设置和获取都正常;但在动态库中打印该全局变量,其值并没有改变。 结论:动态库...多进程引用动态链接库中的全局变量问题
现象描述:
前提:存在一个动态库libvlan.so,存在一个应用console。
做法:在console中调用libvlan.so中的两个APIs,分别是设置和获取动态库中一个全局变量的值。
结果:在console中的操作没有问题,设置和获取都正常;但在动态库中打印该全局变量,其值并没有改变。
结论:动态库中的全局变量,在被其他进程使用时,会拷贝一份,所以多个进程使用同一个动态库中的全局变量也不会相互影响。也不会改变动态库中该变量的值。类似于fork的COW技术。
网络资料:
现有liba.so中定义一个全局变量char buf;
libb.so 中的函数print会将buf进行输出。
进程A和进程B使用-lb进行编译链接,并在进程A和B中分别对buf进行初始化,如strcpy(buf, "A"); strcpy(buf, "B");
进程A和进程B在初始化后分别通过dlopen的方式加载liba.so并调用其中的print函数。
输出结果是A中输出A,B中输出B(当然A在初始化buf后sleep一段时间再调用print函数的,而B初始化后直接调用print,这样保证如果只有一份buf则两者输出结果肯定是后初始化的那个值)。
这是否能确定不同进程加载的动态链接库中的全局变量分别有一份拷贝,即使共享库在内存中只有一份,但是全局变量还是会有多份的,共享库共享的只是代码部分?
对这种应用方式不太确定。不知是否是这样,测试程序看来是没问题。简单的说,你的结论是对的。
虽然我没有看过加载器的代码,但我看过内核动态加载module的代码,它们的原理是一样的,所以我推测加载器会是这样做的:
1. 将代码段以SHARED模式mmap代码段,于是所有application共享一份代码段
2.以PRIVATE模式mmap数据段,于是当有application试图修改数据段时,就会在它自己的地址空间内生成一份拷贝
LZ可以试验将这个全局变量初始化,然后A进程起来后先打印,然后修改,修改完毕后再起B进程,再打印。B进程打印的值应该任然是初始化的那个值。我想这个测试跟我A修改再sleep再启B测试的效果是一样的。
那就是动态库中的全局变量在不同的执行程序中是独立的。
还有一个问题是为什么libb.so中可以使用liba.so中的定义的全局变量但却不能使用a.c中定义的全局变量。a.c 直接编译成执行程序。动态库中使用的符号会去该应用加载的所有动态库中查找但却不会在可执行程序本身里面查找?进程间是相互独立的,其实完全可以看成A、B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一份的。
然后在这个基础上,由于代码段是不会被修改的,所以操作系统可以采用copy on write的优化技术,让两个进程共享同一份物理内存。这是属于在不改变系统行为的基础上,为了节省内存的优化技术。这是可以的,只不过在链接你的a.c的时候需要一些额外的选项。不同的操作系统是不同的,我记得Linux上是-Wl,--export-dynamic
为什么动态库中的全局变量是可以用的?
之前在linux下做过一个测试:
写一个so,该so中有一个全局变量。so中的代码在运行时会修改该全局变量的值。然后,有多个程序都需要该so,而且这些应用程序都启动了。此时,很显然so只被加载了一份,那么,当这么多程序在运行调用该so时,该so中的全局变量的值会被覆盖来覆盖去么?
答案是不会。这是测试的答案。
现在知道原理了,尽管这是windows via C/C++中解释的windows的做法,但是我想linux也是这么类似处理的。
windows 使用memory map来加载exe和dll。当一个exe/dll有多个instance要启动时,实际在windows paging file(包括RAM和swap文件)中,exe和牵涉到的dll,只有一份。这样可以节省内存使用,也可以提高性能。
也就是说,如果是exe,虽然每个instance都有自己独立的地址空间,但是地址空间映射到storage的时候,他们映射的都是同样的地方。这样就带来问题了:exe/dll中的全局变量和静态变量怎么办?每个instance都有可能会修改这些变量。
windows 的做法是,该存放全局变量和静态变量的page,设定copy on write protect attribute。所以,当任何一个线程尝试修改这些page中的内容时,windows负责分配一个新的page出来,然后修改该线程的地址空间,将这个新分配的page的地址设置上去,从此以后,该线程修改这个全局变量或是静态变量,操作的就是这个新分配的page了。这样,多个实例就不会出现全局变量或静态变量互相覆盖的问题了。
参考windows via C/C++ P593,有详细说明如果某动态库中有一个全局变量,程序a使用的这个动态库,程序b也使用了这个动态库,那么程序a和b中的全局变量是一个吗?也就是说,进程间使用动态库时,共享全局变量吗?答题是:是一个,共享,但写时拷贝,给程序员的感觉是:不共享。
写时复制的一个应用是:在调试器中实现断点支持。例如:在默认情况下,代码页面在起始时都是只能执行的(即:只读的),然而,如果一个程序员在调试一个程序时设置了一个断点,则调试器必须在代码中加入一条断点指令。它是这样做的:首先将该页面的保护模式改变为PAGE_EXECUTE_READWRITE,然后改变指令流。因为代码页面是所映射的内存区的一部分,所以内存管理器为设置了断点的那个进程创建一份私有拷贝,同时其它进程仍然使用原先未经修改的代码页面。
写时复制是“延迟计算(lazy evaluation)”这一计算技术(evaluation technique)的一个例子,内存管理器广泛地使用了延迟计算的技术。延迟计算使得只有当绝对需要时才执行一个昂贵的操作——如果该操作从来也不需要的话,则它不会浪费任何一点时间。
POSIX子系统利用写时复制来实现fork函数,当一个UNIX应用程序调用fork函数来创建另一个进程时,新进程所做的第一件事是调用exec函数,用一个可执行程序来重新初始化它的地址空间。 在fork中,新进程不是拷贝整个地址空间,而是通过将页面标记为写时复制的方式,与父进程共享这些页面。如果子进程在这些页面中写入数据了,则生成一份进程私有的拷贝。如果没有写操作,则2个进程继续共享页面,不会执行拷贝动作。不管怎么样,内存管理器只拷贝一个进程试图要写入数据的那些页面,而不是整个地址空间。 -
.在类体中,变量定义部分所定义的变量称为类的________。
2021-03-08 19:02:06在类体中,变量定义部分所定义的变量称为类的________。.成员变量在整个类内都有效,________变量只在定义它的方法内有效。.Java中成员变量又分为实例成员变量和________。.写类的目的是为了描述一类事物共有的_____... -
matlab中如何定义一个数组为全局变量?
2021-04-20 06:11:36在使用全局变量之前,要用关键字...还有一种方法可以讲变量放入句柄中hanldes在M文件中编入如下程序:global a; %matlab自动将a作为数组处理for i=1:5 a(i)=i;end这样就可以成功定义一个全局变量数组。测试:在comma... -
php中如何定义变量
2021-03-23 20:59:44变量是指在程序的运行过程中随时可以发生变化的量,在代码中可以只使用一个变量,也可以使用多个变量,变量中可以存放单词、数值、日期以及属性等。变量的值是临时的,当程序运行的时候,该值是存在的,如果程序结束... -
实例说明 Android 多线程、多进程与全局变量之间的关系
2022-02-15 14:41:121.线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。线程之间的通信更方便,同一进程下的线程共享全局变量、静. -
c++头文件的使用和多个文件中如何共用一个全局变量
2019-03-27 21:57:01头文件只是用来声明的,不参与编译,#include “1.h” 只是把1.h里的代码给复制到这个源文件里来,建议还是好好...1)不管变量还是函数先声明 或者直接定义才能使用,声明能声明n次,同一个作用域里面 定义只能定义... -
全局变量在整个源程序文件中都有效
2021-06-14 05:59:05在一个C程序中,若要定义一个只允许本源程序文件中在一个C程序中,若要定义一个只允许本源程序文件中所有函数使用的全局变在一个C程序中,若要定义一个只允许本源程序文件中所有函数使用的全局变量,则该变量需要... -
python中将一个变量值赋给另一个变量实现(A=B,且A和B地址不同)
2021-01-02 20:01:28在python中对矩阵等变量给另一个变量赋值时(A=B),A中保存的是B中的地址。那么在哪些情况下保存的是地址、怎么做才能做到不是同地址的赋值呢? 1、非数组变量 一般的在python中我们将变量a的值赋值给变量b,... -
c++多个文件中如何共用一个全局变量
2018-03-08 15:27:49例子: 头文件:state.h 源文件:state.cpp 其它源文件:t1.cpp t2.cpp t3.cpp, 这些源文件都包含头文件state.h。...需要定义一个全局变量供这些源文件中使用:方法如下 1、在 state.h声明全局变量: extern ... -
C语言中的变量(自动变量 静态变量 外部变量 寄存器变量)
2021-12-20 15:26:08register 寄存器变量 (用于在硬件寄存器中) 四大类所有变量必须先说明(定义),后使用。 自动(动态)变量: 函数中的局部变量不加static关键字修饰就是动态变量。每次调用该函数的时,系统会给它分配存储... -
java中的全局变量
2021-03-18 08:12:03正在使用NetBeans做一个稍大点的程序,刚刚学习使用,感觉程序中需要用到全局变量(其实java中是没有全局变量这个概念的)。在网上查了不少的资料,得到一点点体会:首先,java中是没有全局变量这个概念的,java程序中... -
c语言中变量的定义
2021-05-20 04:24:02任何一种编程语言都离不开变量,特别是数据处理型程序,变量的使用非常频繁,没有变量参与...变量是内存或寄存器中用一个标识符命名的 存储单元,可以用来存储一个特定类型的数据,并且数据的值在程序运行过程中可... -
Linux 添加环境变量和删除环境变量
2021-05-13 05:29:07环境变量是一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如PATH.在交叉编译中,会经常运用到环境变量的设置。在linux中,查看当前全部的环境变量的命令式env.当然也可使用 echo来查看... -
函数中的声明和变量的定义
2019-04-14 19:44:13 在某些编程语言里,函数声明和函数定义区分开的,一个函数声明包括提供对函数名,参数的名字(传统上还有参数的类型),但不必给出函数的任何代码,具体的代码通常属于函数定义的范畴。 在声明和定义有区别的... -
c语言中的局部变量和全局变量
2021-08-05 22:52:14在一个函数内部定义的变量只在本函数范围内有效,也就是只有本函数内才能引用它们,在此函数外不能使用这些变量; 在复合语句内定义的变量只能在本复合语句范围内有效,只有本复合语句内才能引用他们,在该复合语句... -
微信小程序中变量与字符串拼接问题
2020-07-03 23:12:26 一直报错 不知道怎么把字符串中间加上变量, == -
安川变量说明表
2020-12-23 09:18:12R000至R099(100)允许值的范围为-3.4E+38至3.4E38精度1.18E-38<...机器人轴P000至P127(128)基座轴BP000至BP127(128)工装轴EX000至EX127(128)局部变量变量号功能LB000至LB????????????允许值的范围为0至255。可存... -
C语言中局部变量与全局变量在内存中的存放位置
2018-11-14 00:49:50C语言中局部变量与全局变量在内存中的存放位置 -
C++中交换两个变量的值的方法
2019-11-05 18:21:03首先,需要说明的是,在C++语言中,不能使用下面的方式传值: template<class T> void swap(T a,T b){ T temp=b; b=a; a=temp; } 即不能通过将变量名传入函数的方式进行交换,因为这种方式是将值进行拷贝... -
java中什么叫静态成员变量
2021-02-26 08:24:08静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,...由此看来, 一个变量可由static进行再... -
C语言中【变量】的存储类型共有4种类型
2021-05-19 11:49:29在C语言中,对变量的存储类型说明有以下四种:auto 自动变量 (动态存储)register 寄存器变量(动态存储)extern 外部变量(静态存储)static 静态变量(静态存储)所谓存储类型是指变量占用内存空间的方式,也称为存储方式... -
C语言:全局变量在多个文件中的使用方法
2017-11-03 15:32:25外部变量 Extern -
MATLAB中的变量
2021-03-10 17:18:30在MATLAB中,变量不需要预先声明就可进行赋值 变量的命名规则: 变量名和函数名对字母的大小写敏感 变量名必须以字母开头,其后可以是任意字母或下划线,但不能由空格 不能使用MATLAB中的关键字作为变量名 变量名... -
在中断程序里修改全局变量的童鞋注意啦~(C中的volatile作用 转载~)
2018-03-19 21:39:17一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须... 一个中断服务子程序中会访问到的非自动变量(Non-automatic v...