当前位置:   article > 正文

C语言之#define,#ifdef,typedef,extern,statis,__weak的用法,看懂stm32中的.h和.c文件_extern __weak

extern __weak

1. #define
c语言中的预处理命令,用于宏定义。
示例:

#define		number	0xff(不用加分号)
  • 1

这里就是用number代替了0xff。

2. #ifdef
条件编译,满足条件时对下面的程序进行编译,否则不编译。
格式:#ifdef    标识符
                      程序1(如果标识符是有定义的就编译程序1)
          #else
                      程序2(如果标识符是没有定义的就编译程序2)
          #endif
示例:

#define  number
#ifdef	number
void module1
{
	;
}
#else
void module2
{
	;
}
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面的程序开头标识符number被定义过,所以module1不会被编译,会编译module2。

#ifdef	number
void module1
{
	;
}
#else
void module2
{
	;
}
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里number没有被定义过,所以module1会被编译,而module2不会被编译。
#ifdef与if…else …的区别:#ifdef是决定程序会不会被编译,编译,编译!而if…else…是决定语句是否执行(无论执不执行都被编译过)。
还有一个#ifndef,刚好和#ifdef相反,是没有定义过的标识符会被编译。

3. typedef
对一个类型的关键词重新定义一个别名,用于简化长的变量类型关键词。
示例:

typedef		unsigned int	uint;(要加分号)
  • 1

这里就是用uint代替了unsigned int。
typedef和define是用区别的:define只是简单的替换,无论什么都能替换,而typedef替换一些有类型的标识符,如int,int*。。。

typedefint*)	example1;
#define		example2	int*
example1	a,b;
example2	c,d;

  • 1
  • 2
  • 3
  • 4
  • 5

上面的程序,虽然都是替代了int*,但是有差别的。example1 a,b;表示定义了两个整型变量的指针;而example2 a,b;表示定义了一个整型变量指针和一个整型变量。

4. extern
用于全局变量的申明,extern可以对不是同一个文件的全局变量或函数进行申明,告诉编译器去其他文件找变量或者函数的定义。extern申明变量可以多次,但是变量的定义只有一次。

文件module1.c
			int a;在模块1文件中声明了一个全局变量a

文件module2.c
			extern int a;声明a在其他文件被定义
			a=10;
			


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

用include引用头文件和用extern没什么太大区别,但是如果有多个extern申明,一般会写到.h文件,用include包含进来。
另外说明:为了防止.h文件多次被include引用,一般不在.h文件里定义变量和函数,只用来申明变量和函数。变量和函数的定义一般写在.c文件里,然后用.h包含进来。

5. static
用来申明局部变量存储在静态存储区,函数结束时不会被释放。

void module1()
{
	static int a;

}
  • 1
  • 2
  • 3
  • 4
  • 5

这里a虽然是局部变量,但函数结束后也不会被释放。如果一个有静态变量的函数被调用多次,静态变量只会初始化一次。

void module1()
{
	static int a=0;
	a++;
	printf("%d",a);
}

void module2()
{
	static int a=0;
	a++;
	printf("%d",a);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

要是上面的程序被调用了两次,那么module1中的printf打印出来的是0和1;而module2打印出来的是0和0。
注意:静态变量是存储类型是全局的,但它仍有作用域的概念,在函数中声明static变量,它的作用域是局部的,但它的存储类型是全局,整个程序在编译过程就为它分配好空间了。最好不要定义全局变量,可以用静态局部变量传值。static申明的函数作用域仅限于当前的文件,其他无法用。

6. __weak
在使用STM32的hal库的时候,我们常常可以看到很多库自带的函数有很多是使用__weak修饰的。

在这里插入代码片
  • 1

weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。


 

.
  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/264284
推荐阅读
相关标签
  

闽ICP备14008679号