C项目中变量、宏定义、结构体等声明定义位置问题

以前还是项目接触的少了,这些基本功不扎实。

目录

一、变量

二、源文件前加一个自己文件名的宏定义现象

三、函数声明时前面加不加extern

四、宏定义、结构体、typedef定义等位置


一、变量

一个全局变量到底是定义在头文件中,还是定义在源文件中?

结论:应该定义在.c文件中,不能.h文件中。如果定义在.h文件中,在链接的时候会报变量重复定义错误。

例如:有main.c、myadd.h、myadd.c三个文件,在myadd.h中定义了一个全局变量int a = 10,声明了一个函数myadd;在myadd.c中包含了头文件myadd.h,定义了函数myadd;main.c中包含了头文件myadd.h,调用了函数myadd。代码如下:

//myadd.h
#ifndef _MYADD_H
#define _MYADD_H

int a = 10;

int myadd(int b);

#endif

//myadd.c,一个求和全局变量a相加和的函数
#include "myadd.h"

int myadd(int b)
{
	return a+b;
}
//main.c
#include 
#include "myadd.h"

int main(int argc, char const *argv[])
{
	printf("a的值为:%d
",a);
	printf("a+5=%d
",myadd(5));
	return 0;
}

编译运行:报变量重复定义错误。

C项目中变量、宏定义、结构体等声明定义位置问题

现把变量定义在myadd.c文件中,声明在myadd.h中,在main.c中就可以用全局变量a了,程序编译运行正常。

//myadd.h
#ifndef _MYADD_H
#define _MYADD_H

extern int a;

int myadd(int b);

#endif

//myadd.c,一个求和全局变量a相加和的函数
#include "myadd.h"

int a = 10;

int myadd(int b)
{
	return a+b;
}
#include 
#include "myadd.h"
//extern int a;
int main(int argc, char const *argv[])
{
	printf("a的值为:%d
",a);
	printf("a+5=%d
",myadd(5));
	return 0;
}
C项目中变量、宏定义、结构体等声明定义位置问题

还有一种做法是:头文件myadd.h中不放a的声明,而是在main.c中放a的声明,效果是一样的。当然,你同时在myadd.h中和main.c中都放a的声明也是可以的,反正变量可以声明多次。

参考:https://ask.csdn.net/questions/704337?sort=votes_count

https://www.cnblogs.com/tshua/p/5741009.html

二、源文件前加一个自己文件名的宏定义现象

https://ask.csdn.net/questions/704337?sort=votes_count (Avoiding Code Duplication部分)

https://www.cnblogs.com/zhengluyao/p/7958628.html

看下面这种写法,在常见的头文件#ifndef、#define、#endif之中,还加了一段,宏定义了#define ADCBSPEXT,从程序可以看出,当一个.c文件开头宏定义了ADCBSPEXT之后,ADCBSPEXT就为空,下面的变量就变成了定义;当.c文件当中没有宏定义ADCBSPEXT时,ADCBSPEXT就为extern,下面的变量就变成了申明。起到了双关的作用。

#ifndef DSP_ADC_BSP_H_    //防止头文件被重复包含
#define DSP_ADC_BSP_H_

#ifdef _DSP_ADC_BSP_C_   //判断是否被定义了
#define ADCBSPEXT         //定义时执行
#else
#define ADCBSPEXT extern //未定义时执行
#endif //_DSP_ADC_BSP_C_
ADCBSPEXT int a;
ADCBSPEXT void InitileAdc(void); 
ADCBSPEXT void CaptureAdcInt(); 
ADCBSPEXT unsigned char CaptureAdcInt_data();

#endif /* DSP_ADC_BSP_H_ */

使用上面这种形式的写法时,在头文件对应的源文件开头加上自己名称宏定义就可以了,其他源文件不加。

#define _DSP_ADC_BSP_C_ 
#include "xxx.h"

三、函数声明时前面加不加extern

在头文件中声明函数时,下面两种哪个好?

int myfun(int a,int b);
extern int myfun(int a,int b);

结论:不加extern。

因为函数的声明和函数的定义(有实现)形式不一样,系统能够自动区分函数是声明还是定义,所以我们的函数声明系统默认就是extern。所以,一般上,我们在声明函数的时候就不加extern。

四、宏定义、结构体、typedef定义等位置

结论:如果宏定义只在一个.c文件中使用,则宏定义放在这个.c文件中;若果多个源文件中需要使用这个宏,则放在.h文件中定义。其实这个很好理解,因为宏的展开是在编译预处理阶段完成的,如果多个源文件中需要使用某个宏,而它只放在一个.c文件中的话,则编译的时候肯定会报变量未定义错误。(宏定义、结构体、typedef结论一样,放的位置相同)

#include 
#include "myadd.h"

int main(int argc, char const *argv[])
{
	MYint a = 1;
	struct Student student;
	printf("a=%d
",a);
	printf("A+B=%d
",A+B);
	return 0;
}
//myadd.h
#ifndef _MYADD_H
#define _MYADD_H

int myadd(int a,int b);

#endif

//myadd.c,
#include "myadd.h"
#define A 10
#define B 20
typedef int MYint;
struct Student
{
	int age;
	char name[10];
};
int myadd(int a,int b)
{
	return a+b;
}
C项目中变量、宏定义、结构体等声明定义位置问题

typedef和define类似,根据使用范围确定放的位置。单个.c文件使用就放在它当中定义,多个使用就放在头文件中定义。与define稍微不同的是,typedef是在编译的时候执行的。

把他们都放到.h文件中,就没有问题了。不过会报宏定义重复定义警告。

//myadd.h
#ifndef _MYADD_H
#define _MYADD_H

#define A 10
#define B 20
typedef int MYint;
struct Student
{
	int age;
	char name[10];
};

int myadd(int a,int b);

#endif

//myadd.c,
#include "myadd.h"

int myadd(int a,int b)
{
	return a+b;
}

//main.c
#include 
#include "myadd.h"

int main(int argc, char const *argv[])
{
	MYint a = 1;
	struct Student student;
	printf("a=%d
",a);
	printf("A+B=%d
",A+B);
	return 0;
}
C项目中变量、宏定义、结构体等声明定义位置问题

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章