[C]关于extern与struct
问题
我曾经很困惑,就是在两个编译单元当中,如何把一个单元中声明的struct结构引入到另外一个单元中来,折腾了很久,后来发现这位大神的留言
不是这么用的…… 类型的定义和类型变量的定义不同, 类型定义只是描述一个类型, 是给编译器看的, 不会产生可执行代码。 变量定义是指在执行文件中真实得存在这么一块内容。 因为每个.c里都要写清楚类型定义很麻烦, 所以一般都把类型定义写在.h里 ,而在.c里采用简单的写法,如struct A a; 这样定义变量, 不需把整个类型的描述再写一遍。 -------------------------------- 所以,struct类型定义放到 ser.h里面, ser.cpp 里加struct str st_r; CmfcDlg.cpp加上#include "ser.h" 然后直接使用extern struct str st_r; -------------------------------- 楼主要有研究精神…… 你先试下我上面说的…… |
我顿时发现自己是有多么的傻x.
说白了extern面向结构的语法,只针对对象的本身,而不包括结构,结构只是一个模板,是写给编译器看得。并不存在extern结构的说法,只能extern结构对象。
如果需要在两个编译单元内引入外部变量,那么你必须在两个文件当中引入这个结构,才能使用。
最科学的方法就是把结构写进一个.h文件,然后把它各自#include进每一个需要用到这个结构的文件当中。
示例,在a.c中声明结构chicken,随后声明一个叫jason的chicken对象。把jason引入b.c
a.c
struct chicken { char name[20]; int age; }; struct chicken jason = { "jason", 2 };
b.c
#include <stdio.h> struct chicken { char name[20]; int age; }; extern struct chicken jason; int main(void) { printf("%s\n", jason.name);//输出jason }
这个例子有一个不合理的地方,就是两个文件都需要在各自上下文中声明结构chicken,一旦结构chicken有所改动,就会相当麻烦,你需要修改所有包含了该结构的页面。
所以这种情况下,通常会采取把结构声明语句挪出来独立作为一个头文件,之后用到的地方各自引用该头文件,下面是改动过的示例。
结构chicken被单独至于这个chicken.h文件当中:
struct chicken { char name[20]; int age; };
a.c:
#include "chicken.h" struct chicken jason = { "jason Chao", 2 };
b.c:
#include <stdio.h> #include "chicken.h" //extern struct chicken jason; struct chicken jason; int main(void) { printf("%s\n", jason.name); }
结果是b.c会正常输出jason.name.
题外话
1.其实extern关键字是c的标识符声明中的[存储类修饰符]的一员,[存储类修饰符]包括extern、static、auto、register,在声明变量、函数、结构化数据时,extern标识符是默认的,也就是说,上面的例子即使不手动指明extern关键字,编译器也会默认把它当成extern关键字处理.
a.c
struct chicken { char name[20]; int age; }; struct chicken jason = { "jason", 2 };
b.c
#include <stdio.h> struct chicken { char name[20]; int age; }; struct chicken jason;//等价于extern struct chicken jason; int main(void) { printf("%s\n", jason.name);//输出jason }
2.注意哦,变量只能初始化(赋予变量字面值)一次,就算外部变量也是一样哦,不然编译器会提示multiple definition of `xxx'