我正在使用C语言编写固件。
我有一个标题文件:extern.h
:
extern int x;
我有file1.c
:
#include"extern.h"
//----------foo1 gives value to x------------------------
foo1(void)
{
int x=200;
}
现在foo2
file2.c
#include"extern.h"
foo2(void)
{
int x;
printf("%d",x);
}
最后在main.c
#include"extern.h"
void main()
{
foo1();
foo2();
}
如果在执行中获取垃圾值,可能会出现什么问题? 我相信变量的值必须是200。
我通过mplab c18
做了类似的事情而不是printf
中的foo2.c
,我在foo2.c
中对GUI函数进行了传输,它显示了随机的int值成千上万......完全与我给的200不相关。
当我把'x'初始化为
时 foo2(void)
{
int x;
}
它再次显示数千个随机值。
我相信这不是我所做的编码问题,因为它必须传输200。
注意:
但是如果在foo2.c中进行初始化和传输那么就可以了 值正确显示。
我应该在哪里查找错误:在GUI中还是在固件中?
答案 0 :(得分:1)
当你说extern int x
时,它意味着它是一个全局变量,将在其他.c文件中定义。您在foo1和foo2中定义的局部变量优先于全局外部变量。在foo1中,x的值将为200,并且在foo2中,x的值可以是任何值,具体取决于堆栈上的内容。另外,我没有看到你实际上将x定义为全局变量。那也是缺失的。
答案 1 :(得分:1)
foo1() - >什么都不做
foo2() - >声明一个变量x,它是UNDEFINED(没有设置任何值),所以它可以是任何东西。
声明为int x;
的变量只有它们所在范围的生命周期,即你不能在任何地方使用相同的名称,并期望它将映射到同一个变量。
如果您的变量是全局外部变量,请不要在您拥有的本地foo
函数中重新声明它。
另见 How do I use extern to share variables between source files?
答案 2 :(得分:1)
当您将extern int x;
行放在extern.h
文件中时,您所说的是某个地方存在x
但不(井)除非你在同一范围内也有int x;
,否则不在这里。
换句话说,它是一个声明存在的东西而不是定义创造了某些东西。因此,如果没有定义,则永远不会创建特定的x
。
在您的foo1()
和foo2()
函数中,您执行创建名为x
的内容,但不相同{ {1}}在x
中声明的那个:它有不同的范围。
extern.h
和x
中的foo1()
(和不同的变量,不是同一个变量)都是它们定义的函数的本地变量因此,foo2()
创建了foo1()
,将其值设置为x
,然后在退出时将其抛出。
200
使用任意值创建其foo2()
,然后打印它(因此您的“垃圾值”评论)。
这解释了你所看到的行为,现在如何解决这个问题。通常这样做的方法是在某处定义变量(仅一次),在任何地方声明,如:
x
所以extern.h:
extern int x; // declare it
void foo1(void);
void foo2(void);
foo1.c:
#include "extern.h" // declare x via the header
void foo1(void) {
x = 200; // set x, note: no int at start of line
// since that would create a NEW x.
}
foo2.c:
#include <stdio.h>
#include "extern.h" // declare x via the header
void foo2(void) {
printf "%d\n", x); // again, no "int x;" since that would
// create a NEW x.
}
main.c:
#include "extern.h" // declare in the header
int x; // and define it.
int main (void) {
foo1();
foo2();
return 0;
}
中存在“全局”x
(虽然你可以把它放在任何一个C文件中,只要它只在一个中) 。 main.c
和foo1.c
都包含声明foo2.c
存在的extern.h
标头,这意味着他们将能够找到它。
确保x
和foo1()
都未在本地范围内定义另一个foo2()
(使用x
或int x;
) ,他们将在下一个外部范围使用int x = something;
(即x
中的那个)。
当您定义与外部作用域1同名的内部作用域变量时,前者“隐藏”(或“阴影”)后者。例如,代码:
main.c
将输出:
#include <stdio.h>
int main (void) {
int x = 42;
printf ("A: %8d\n", x);
{
int x = 314159;
printf ("B: %8d\n", x);
}
printf ("C: %8d\n", x);
return 0;
}
因为内部大括号在该范围内创建新的A: 42
B: 314159
C: 42
。并且,当范围结束时,您看到的x
是原始。