c语言中结构体头文件是什么 |
您所在的位置:网站首页 › 头文件定义结构体怎么调用 › c语言中结构体头文件是什么 |
怎样在C语言中用H头文件声明一个外部struct变量 要定义一个struct变量,首先要定义一个结构体变量类型名 即struct 结构体名 例如定义一个按键属性结构体(包含 是否有按键值更新(renew)和按键值(num)两个成员) struct Key_attribute { unsigned char renew; unsigned char num; }; 到此只是定义了一个类型名为 struct Key_attribute的结构体变量类型,仅仅是定义了一个类型而已,不生成代码,它的的属性和 int ,char,一样,只是一个类型说明。 有了类型之后就可以像 int i;定义i为一个整型变量一样,利用刚刚声明过的结构体变量类型struct Key_attribute 定义一个类型属性如struct Key_attribute(包含 两个unsigned char 无符号字符型变量 成员)的结构体变量了。 如 struct Key_attribute Key;//就定义了Key 为一类型为struct attribute 的结构体变量 此时Key 就会产生代码,占用内存了。 具体应用如下: 在KEY.H头文件中声明Key为一外部结构体变量 #ifndef _KEY_H_ #define _KEY_H_ 。。。。 struct Key_attribute//定义一个名为 struct Key_attribute 的结构体类型。类型属性为包含两个无符号字符型变量成员 { unsigned char renew; unsigned char num; }; //到此就定义好 struct Key_attribute 类型了,只要C文件中包含 "KEY.H"就可以直接像用 int 定义变量一样,定义struct Key_attribute 类型的结构体变量了 //如果 file1.c中包含 "KEY.H" 并定义了 struct Key_attribute Key;则只要在"KEY.H"文件中用一条外部变量声明 extern struct Key_attribute Key,其它文件只要包含"KEY.H"就可以对结构体变量Key进行操作了。 extern struct Key_attribute Key; //声明变量Key 为一属性为struct Key_attribute的外部结构体变量,任何包含"KEY.H"都可以不用再次声明Key为外部变量而直接使用结构体变量Key 了。 //这样做的好处是,如果在头文件里面定义变量则编译器会为调用头文件里的同一变量的不同文件分配不同的存储空间,造成存储空间浪费。所以一般只在头文件里声定义变量类型,或声明变量为外部变量,而不定义变量。 。。。。 #endif //------------------------------------------------------------------------ 分清声明和定义: 例如: //ta.c extern int a; //声明 //tb.c extern int a; //声明 //tc.c extern int a; //声明 void changa(void) { ++a; //a在别处有定义 } //td.c #include "ta.c " #include "tb.c " #include "tc.c " #include int a = 0; //此处定义a int main(void) { changa(); printf( "a = %d ",a); return 0; } //------------------------------------------------------------------------ C语言头文件中定义变量问题 头文件重复包含问题,问题描述如下: 他在程序中建立了一个global.h的文件,代码如下: #ifndef _GLOBAL_H_ #define _GLOBAL_H_ int a; int b; int c; 然后在其他文件代码中,有多个.cpp文件引用他,编译的时候编译器报变量重复定义。 其实这是个C语言的基本问题,如果学过编译原理的人就很清除问题在哪里。假设上面的头文件global.h,有三个.cpp文件,1.cpp, 2.cpp, 3.cpp都包含了这个头文件。那么在编译的时候分别生成 1.obj, 2.obj, 3.obj。在这三个obj文件中都包含变量a, b, c。那么在链接的时候你让机器怎么去分别三个a变量,三个b变量,三个c变量,那么就只好给你报个错了。 不过,如果是从事Linux或者以前标准C语言开发的人可能会想,我原来编程就是这么编的,怎么就没有报错。对的,有些编译器是具有这种重定义自动检测的,如Linux下C编程。我目前用的编程环境是Visual studio.net 2003。我写了两个小程序测试了一下,一个是标准C程序,如下: head1.h #ifndef _HEADER1_H_ #define _HEADER1_H_ void print_1(); #endif head2.h #ifndef _HEADER2_H_ #define _HEADER2_H_ void print_2(); #endif global.h #ifndef _GLOBAL_H_ #define _GLOBAL_H_ int g_test; #endif head1.c void print_1() { g_test=1; printf("%dn",g_test); } head2.c void print_2() { g_test=2; printf("%dn",g_test); } main.c void main() { print_1(); print_2(); } 经过测试,这种方式是对的。 然后,我写了段c++代码,程序代码和上面的一模一样,就是.c文件变成了.cpp文件。结果就报重定义的错误。 由此可见,这个问题是C++新标准。而上述标准C能够编译过,说明这种对重定义的支持是依据编译器的,但是对于编译器来说,不是必须的。所以程序员写程序最好不要用上述代码写,现在一般程序员对这个问题流行的写法是如下: #ifndef _GLOBLE_H #define _GLOBLE_H extern int a; extern int b; extern int c; #endif 然后在其他的某个.cpp文件中定义 int a; int b; int c; 但是这种写法在具有大量的变量时候,容易造成声明的头文件和变量定义的cpp文件中变量的不一致。 下面是我给出一个的解决方法。 定义一个宏,如:MAIN,在global.h中,加入如下代码: #ifdef MAIN #define EXTERN //定义变量 #else #define EXTERN extern //声明变量 #endif EXTERN int a; EXTERN int b; EXTERN int c; 然后在你的1.cpp , 2.cpp , 3.cpp 中,在其中的一个.cpp中 #define MAIN #include "gloabl.h" 进行定义。这样相当于对gloabl.h中的变量进行定义。 而在其他的cpp中,如需要引用global.h中的变量,则 #include "gloabl.h" 而不需要#define MAIN.或者将#define MAIN定义在#include "gloabl.h"的后面。这样编译的时候就会将gloabl.h中的变量作为声明来看待。 这样即使变量再多,也不会出现头文件和CPP文件中的变量不符。因为所有的变量只需在一个文件中写入。 //------------------------------------------------------------------------ PS:首先,尽管一个全局变量或函数可以(在多个编译单元中)有多处“声明”,但是“定义”却只能允许出现一次。定义是分配空间并赋予初值(如果有)的声明。最好的安排是在某个相关的.c文件中定义,然后在头文件(.h)中进行外部声明,在需要使用的时候,只要包含对应的头文件即可。定义变量的.c文件也应该包含该头文件,以便编译器检查定义和声明的一致性。 作为一般规则,你应该放在头文件(.h)中的有: 宏定义(预处理#defines) 结构、联合、和枚举声明 typedef声明 外部函数声明 全局变量声明 当声明或定义需要在多个文件中共享时,尤其需要把它们放在头文件中。特别是,永远不要把外部函数原型放到.c文件中。如果定义或声明为一个.c文件私有,则最好放在.c文件中。 另外:#incluse语法通常用于标准或系统提供的头文件,而#include""通常用于程序自己的头文件。通常在搜索时,由#incluse包含的头文件会现在一个或多个标准位置搜索,而用#incluse""包含的头文件会首先在“当前目录”中搜索,然后(如果没有找到)再在标准位置搜索。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |