全局变量在其它文件调用,打印出来为零的问题

全局变量管理

本人因为使用了硬件多通道,所以想设置一个全局变量来对多通道的资源进行一个分配。但是!我实际操作的时候发现,全局变量在公共c文件中更新后,其它c文件的全局变量值全是零!经过排查发现,我在使用公共c文件中更新这个全局变量的函数时,把全局变量作为传参传入了,所以导致全局变量被局部变量遮盖,值为零。

修改方法很简单,把全局变量更新函数中全局变量的传参删掉,让它从全局调用,这样在其它地方extern的全局变量读取出来就有数据了。

<think> 我们正在讨论C语言中局部变量和全局变量同名时的调用方法。根据引用内容,我们可以总结如下: 1. 在声明了同名局部变量的作用域内,局部变量会覆盖(隐藏)同名的全局变量。此时,直接使用变量名访问的是局部变量。 2. 在没有声明同名局部变量的作用域内,可以直接使用变量名访问全局变量。 3. 如果在一个作用域内已经声明了局部变量,但是又想访问同名的全局变量,可以通过以下方法: a. 在一个函数内部,可以通过创建一个新的作用域(如使用花括号{}),并在该作用域内使用`extern`声明该变量为外部变量(即全局变量),然后在这个新作用域内访问它(引用[4]和[引用[5])。 b. 通过函数返回全局变量引用[4]中的get_global函数)。 引用[3]提到,全局变量的作用域是从其定义位置开始到文件结束。因此,如果全局变量定义在函数之后,那么该函数内部无法直接访问这个全局变量(除非使用extern前置声明)。 现在,我们将通过示例来详细说明这些方法。 ### 一、基本规则:局部变量覆盖全局变量 ```c #include <stdio.h> int a = 10; // 全局变量 int main() { int a = 20; // 局部变量 printf("局部变量a的: %d\n", a); // 输出20,访问的是局部变量 return 0; } ``` ### 二、在无同名局部变量的函数中访问全局变量 ```c #include <stdio.h> int a = 10; // 全局变量 void func() { // 此函数内部没有定义局部变量a,所以直接使用a就是全局变量 printf("全局变量a的: %d\n", a); // 输出10 } int main() { int a = 20; // 局部变量 func(); // 调用func,打印全局变量a的 return 0; } ``` ### 三、在存在同名局部变量的作用域内访问全局变量的方法 #### 方法1:使用extern关键字创建新作用域 ```c #include <stdio.h> int a = 10; // 全局变量 int main() { int a = 20; // 局部变量 printf("局部变量a: %d\n", a); // 20 // 创建一个新的块作用域 { // 使用extern声明这个a是外部链接的,即全局变量 extern int a; printf("全局变量a: %d\n", a); // 10 } return 0; } ``` #### 方法2:通过函数返回全局变量 ```c #include <stdio.h> int a = 10; // 全局变量 // 定义一个函数返回全局变量 int get_global_a() { return a; } int main() { int a = 20; // 局部变量 printf("局部变量a: %d\n", a); // 20 printf("全局变量a: %d\n", get_global_a()); // 10 return 0; } ``` #### 方法3:使用指针(不推荐,仅作了解) 如果知道全局变量的地址,也可以通过指针来访问,但这种方法需要谨慎,因为全局变量的地址在编译时确定,但在有多个同名全局变量(如不同文件)时,可能会出错。 ### 注意事项 1. 使用`extern`声明时,必须在全局变量的作用域内(即该全局变量已经定义,或者前置声明)。如果全局变量定义在使用位置之后,则需要先有前置声明(在外部作用域)。例如: ```c #include <stdio.h> int main() { // 这里使用extern声明一个后面定义全局变量 extern int a; printf("a = %d\n", a); // 可以访问,因为有了前置声明 return 0; } int a = 10; // 全局变量定义在main函数之后 ``` 但是,如果全局变量定义在其他文件中,则需要在当前文件使用`extern`声明(注意:此时不能初始化,初始化会导致定义)。 2. 在同一个作用域内,不能既声明一个局部变量又用`extern`声明同一个变量,因为`extern`声明不会分配存储空间,而局部变量定义会。例如,以下代码是错误的: ```c int main() { int a = 20; extern int a; // 错误:冲突的声明 return 0; } ``` 3. 引用[5]展示了在局部变量作用域内如何调用同名的全局函数(注意:函数和变量是不同的,但原理类似,即通过`extern`声明来引用外部函数)。 ### 总结 当局部变量与全局变量同名时: - 默认情况下,局部变量会隐藏全局变量。 - 若需要在局部变量的作用域内访问全局变量,可以通过: - 创建一个新的块作用域,并在其中使用`extern`声明该变量(推荐)。 - 编写一个返回该全局变量的函数。 - 使用全局变量的指针(需谨慎)。 ```mermaid graph TD A[同名变量访问] --> B[局部作用域内] A --> C[全局作用域内] B --> D[默认局部变量] B --> E[使用 extern 在新块中访问全局变量] B --> F[通过函数访问全局变量] C --> G[直接访问全局变量] ``` §§相关问题§§ 1. 在C语言中,如何避免全局变量和局部变量同名? 2. 全局变量在不同文件中如何共享?extern关键字的使用方法有哪些? 3. 在C语言中,静态全局变量和普通全局变量有什么区别? </think> 在C语言中,当局部变量与全局变量同名时,局部变量会在其作用域内**遮蔽(hide)**同名的全局变量。以下是详细的调用方法和访问技巧: ### 一、基本规则(优先级) 1. **同名局部变量的作用域内**优先使用局部变量 ```c int num = 100; // 全局变量 void func() { int num = 50; // 局部变量(遮蔽全局变量) printf("%d", num); // 输出50(局部变量)[^2] } int main() { func(); printf("%d", num); // 输出100全局变量) return 0; } ``` 2. **无同名局部变量的作用域内**使用全局变量 ```c int num = 100; // 全局变量 void print_global() { // 此作用域无局部变量num printf("%d", num); // 输出100全局变量)[^3] } ``` ### 二、访问被遮蔽的全局变量的方法 #### 方法1:使用`extern`创建临时作用域(推荐) ```c int num = 100; // 全局变量 int main() { int num = 200; // 局部变量 { // 新建作用域块 extern int num; // 声明引用全局变量 printf("全局num = %d\n", num); // 输出100 [^4][^5] } printf("局部num = %d\n", num); // 输出200 return 0; } ``` #### 方法2:通过函数间接访问 ```c int num = 100; // 全局变量 int get_global() { return num; // 始终访问全局变量 [^4] } int main() { int num = 200; printf("全局=%d, 局部=%d\n", get_global(), num); // 输出:全局=100, 局部=200 return 0; } ``` #### 方法3:使用指针(不推荐,仅作演示) ```c int num = 100; // 全局变量 int main() { int num = 200; int* p_global = &num - 1; // 危险操作!依赖内存布局 printf("全局num ≈ %d\n", *p_global); // 可能输出100 return 0; } ``` > ️ 警告:方法3依赖编译器内存布局,移植性差,实际禁用 ### 三、关键原理图解 ```mermaid graph LR A[变量访问请求] --> B{当前作用域<br>有同名局部变量?} B -->|是| C[使用局部变量] B -->|否| D[使用全局变量] E[强制访问全局变量] --> F[方法1: extern作用域块] E --> G[方法2: 辅助函数] ``` ### 四、注意事项 1. **作用域边界** 全局变量作用域从其**定义位置开始到文件结束**,定义前的函数无法直接访问(需用`extern`前置声明)[^3] 2. **函数参数视为局部变量** 函数参数与全局变量同名时,同样会遮蔽全局变量: ```c int x = 10; void foo(int x) { // 参数x遮蔽全局x printf("%d", x); // 输出参数 } ``` 3. **代码可读性** 避免在工程代码中使用同名变量,优先采用`g_`前缀(如`g_count`)明确标识全局变量[^2] > 通过`extern`创建临时作用域是最安全可控的全局变量访问方式,既避免了命名冲突,又保持了代码可读性[^4][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值