以前还是项目接触的少了,这些基本功不扎实。
目录
一、变量
二、源文件前加一个自己文件名的宏定义现象
三、函数声明时前面加不加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;
}
编译运行:报变量重复定义错误。
现把变量定义在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;
}
还有一种做法是:头文件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"
在头文件中声明函数时,下面两种哪个好?
int myfun(int a,int b);
extern int myfun(int a,int b);
结论:不加extern。
因为函数的声明和函数的定义(有实现)形式不一样,系统能够自动区分函数是声明还是定义,所以我们的函数声明系统默认就是extern。所以,一般上,我们在声明函数的时候就不加extern。
结论:如果宏定义只在一个.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;
}
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;
}
留言与评论(共有 0 条评论) “” |