#ifndef PEOPLE_H
#define PEOPLE_H
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <iostream>
int a = 0; //这里只是多定义了一个变量.
class people
{
private:
char name[20];
int age;
public:
void set_name(char *s);
void set_age(int i);
const char * get_name();
const int get_age();
};
#endif
我知道在头文件定义变量是不规范的做法.我只是想了解.为什么即使在定义了宏的情况下.两个CPP文件包含该头文件依然会报变量a重复定义的错误. |
|
|
#ifndef PEOPLE_H
#define PEOPLE_H #endif 只是说明在在某一个编译单元不会重复包含,没有说在不同单元中不可以再次出现 |
|
|
5分 |
定义宏的目的:防止同一个cpp文件包含多次.h(有的时候同一个cpp会间接的包含多次同一个.h)
你的问题:在.h中声明变量,在多个.cpp中包含,编译时会在多个.o文件中有这个变量,所以在链接的时候会出错 |
|
5分 |
a是全局变量
B文件引用此头文件,不报错 C文件引用此头文件,不报错(没有重复定义) 此时,整个工程中 a变量因为是全局变量,就会被 定义两次,报错 |
|
15分 |
#ifndef PEOPLE_H
#define PEOPLE_H /* … */ #endif 这样写能够防止头文件被重复包含 在头文件中定义变量不是不规范,而是一种错误。 同样的, 在链接阶段,如果file1.o和file2.o链接在一起,变量a的定义就是重复的。 $ cat file1.c file2.c main.c header.h
/* file1.c */
#include "header.h"
/* file2.c */
#include "header.h"
/* main.c */
#include <stdio.h>
#include "header.h"
int main(void)
{
printf("a=%d\n", a);
return 0;
}
/* header.h */
#ifndef HEADER_H
#define HEADER_H
int a = 0;
#endif
$ nm file1.o file2.o main.o file1.o: file2.o: main.o: $ gcc -o demo file1.o file2.o main.o 正确的方法是,在header.h里声明变量,在一个单独的global.c文件里定义变量。
/* file1.c */
#include "header.h"
/* file2.c */
#include "header.h"
/* main.c */
#include <stdio.h>
#include "header.h"
int main(void)
{
printf("a=%d\n", a);
return 0;
}
/* header.h */
#ifndef HEADER_H
#define HEADER_H
extern int a;
#endif
/* global.c */
int a = 0;
$ gcc -c file1.c file2.c main.c global.c file1.o: file2.o: main.o: global.o: |
|
5分 |
a重复定义 一般这样用
#ifndef INIT #define DECLARE extern #else #define DECLARE // nothing!!! #endif DECLARE int a; 找一个cpp定义一个INIT, 包含头文件即可 |
|
5分 |
你要搞清楚编译错误 和连接错误
你每一个文件都是可以编译通过的,因为每一个文件里面都只有一个变量。 但是,在链接时,把各个文件链接成一个单独模块时,链接器发现各个文件都有同一个名字的变量,连接器没有办法把它们合并在一个模块里面。所以报错。 链接错误 和 编译错误是不一样的 |
|
用宏定义只解决编译时不会重复的问题,并无法解决链接时的问题
|
|
|
3分 |
定义成全局变量
使用的地方声明,就没这个问题 |
|
感谢耐心回复.如果一个CPP里定义了一个宏.可以作用在另一个CPP吗,当然是同一项目. |
|
|
2分 |
C/C++ 是以文件作为单独的编译单元的。
然后这些编译后的 .obj 文件有链接器链接成目标文件。 |