今日在写SysTcik_Handler()这个中止函数时,总是报错,分明在最初界说的大局变量extern u16 nTIme,(nTIme–写在stm32f10x_it.c的sysTIck中止函数中)可是编译时总是报错,百度之后才有了处理办法,
之前也留意到过extern变量,可是没有细心思考过它的运用办法,今日碰到了,必定要把它弄理解,把这个关键字的一般效果弄清楚(仅仅是一般效果,C的博学多才不敢妄谈);
当你树立一个头文件库时,经常会遇到一个问题,就是在A文件中界说一个temple变量,想把它的值传递给B文件运用,可是A文件操作中函数又不能够带回来参数,比方说中止服务函数,那该怎么办?假设你把temple界说在A中,然后让A.h和B.h包括在includes.h中,然后把includes.h放在A.c和B.c中单个编译是没有问题的,可是链接的时分会呈现问题,
“Symbol temple mulTIply defined(by A.o and B.o)”
意思是这个变量被屡次界说了!!!
处理的办法是:
在A中界说temple变量后,在B顶用extern 声明一下就能够了,例如:
1.在A中界说temple并且赋值:u16 temp2=0;
2.在B中声明extern u16 temp2;
这儿仅仅声明,不再赋值,不然会报错!
Symbol temp2 multiply defined (by catch_pwm.o and app.o)
这儿要留意变量界说和变量声明的差异:
变量界说运用“数据类型+变量称号”的方法,编译器需求给它分配内存单元的;
而变量声明运用“extern 变量类型+变量称号”的方法,是告知编译器我这个变量将在其他外部C文件中界说,我这儿仅仅在外部用它。编译器就不会给它分配内存空间,而比及真实遇到变量界说时再给它分配内存空间。
//////////////////以下是“聚海”de帖子///////////////////////////////////
1、一般变量界说成大局变量
假设是一般类型,完全能够不必*.h文件,直接在*.c文件中界说,在调用文件处用extern 声明,由于关于一般类型,编译器是能够辨认的。比方在一个 my.c文件中,我界说了char name[10];那么在其他文件中只需用extern char name[](由所以声明,一位数组能够省掉巨细,但不主张用指针,比较指针和数组是两回事)外部声明就能够了,告知编译器这个变量我现已界说过了,详细怎样,你渐渐找吧。这契合常理,由于char是编译器能自主辨认的类型。
2、自界说结构体类型界说成大局变量
不同于一般类型,假设不预先告诉编译器,编译器是不会辨认你自界说的类型的。这个时分,*.h文件便呈现了。不是界说结构类型不占内存吗?那好,我大结构体的界说放在*.h文件中,这样一来,不管你incude无数次,内存都不会被占用的。并且这样还有个优点,在其他文件中能够include这个*.h文件,这样,在这个文件中,编译器就能够辨认你的自界说类型了,意图不就达到了?假设我在global.h中界说了
typedef struct _POSITION
{
int x;
int y;
}POSITION;
那么我能够在一个global.c文件中完成大局变量的界说,不过要include那个*.h文件,比方
include “global.h”
POSITION current,;
这样就界说了cunrrent这个变量,在其他文件中引证这个变量时,只需extern POSITION current;进行声明,然后就能够用了,不过这个文件也还得include “global.h” 由于假设不包括,在这个文件中是不辨认POSITION类型的。
1.怎么引证一个现已界说过的大局变量?
答:extern 能够用引证头文件的方法,也能够用extern关键字,假设用引证头文件方法来引证某个在头文件中声明的大局变理,假定你将那个编写错了,那么在编译期间会报错,假设你用extern方法引证时,假定你犯了相同的过错,那么在编译期间不会报错,而在衔接期间报错。
2.大局变量可不能够界说在可被多个.C文件中?为什么?
答:能够,在不同的C文件中以static方法来声明同名大局变量。 能够在不同的C文件中声明同名的大局变量,条件是其间只能有一个C文件中对此变量赋初值,此刻衔接不会犯错。
OVER!