C语言中extern关键字详解2
(3) 在多个文件中声明外部结构体变量
前面一节中,只是适合一般变量的外部声明,但是对于声明外部结构体变量时,则有些不同,需要加以注意。
例子:
文件a.c的内容:
#include <stdio.h>
#include “b.h”
#include “c.h”
A_class local_post={1,2,3}; //全局变量
A_class next_post={10,9,8}; //全局变量
int main(int argc,char *argv[])
{
A_class ret;
print(“first point”,local_post);
print(“second point”,next_post);
ret=fun(local_post,next_post);
printf(“the vector is (%d,%d,%d)n”,ret.x,ret.y,ret.z);
return 0;
}
文件b.h的内容:
#ifndef __B_H
#define __B_H
#if 1
typedef struct{
int x;
int y;
int z;
}A_class;
#endif
extern A_class local_post; //外部结构体变量声明
extern A_class fun(int x,int y,int z); //接口函数声明
#endif
文件b.c的内容:
#include <stdio.h>
#include “b.h”
A_class fun(A_class first,A_class next)
{
A_class ret;
ret.x=next.x-first.x;
ret.y=next.y-first.x;
ret.z=next.z-first.z;
return (ret);
}
文件c.h的内容:
#ifndef __C_H
#define __C_H
extern int print(char *,A_class post);
#endif
文件c.c的内容:
#include <stdio.h>
#include “b.h”
int print(char *str,A_class post)
{
printf(“%s : (%d,%d,%d)n”,str,post.x,post.y,post.z);
return 0;
}
利用gcc工具编译gcc a.c b.c c.c–o demo,再运行./demo,结果为
first point : (1,2,3)
second point : (10,9,8)
the vector is (9,8,5)
小结:在a.c文件中定义全局变量A_class local_post结构体,并且调用b.c中的接口函数A_class fun(int x,int y,int z)和c.c中int print(char *str,A_class post),在b.h中声明外部结构体变量local_post,同时,需要对其类型A_class进行实现,在b.h文件中,如果屏蔽掉A_class的实现,而在b.h以外的文件中实现,此时编译时就会出错,由于c.c文件中用到A_class定义的类型,所以需要在该文件中包含b.h。
这里需要说明的是,如果调用外部结构体等多层结构体变量时,需要对这种变量进行实现,使用时,加上模块的头文件即可,否则会报错。
实际工程中,模块化程序文件,一般提供一个.c和一个.h文件,其中.h文件被.c文件调用,.h文件中实现。
2. 用extern声明外部函数
a. 定义函数时,在函数返回值类型前面加上extern关键字,表示此函数时外部函数,可供其他文件调用,如extern int func (int x,int y),C语言规定,此时extern可以省略,隐形为外部函数。
b. 调用此函数时,需要用extern对函数作出声明。
作用域:使用extern声明能够在一个文件中调用其他文件的函数,即把被调用函数的作用域扩展到本文件。C语言中规定,声明时可以省略extern。
例子:
文件a.c的内容:
#include <stdio.h>
#include “b.h”
int main()
{
int x=10,y=5;
printf(“x = 10,y = 5n”);
printf(“x + y = %dn”,add(x,y));
printf(“x – y = %dn”,sub(x,y));
printf(“x * y = %dn”,mult(x,y));
printf(“x / y = %dn”,div(x,y));
return 0;
}
文件b.h的内容:
#ifndef __F_H
#define __F_H
extern int add(int x,int y);
extern int sub(int x,int y);
extern int mult(int x,int y);
extern int div(int x,int y);
#endif
文件b.c的内容:
#include <stdio.h>
int add(int x,int y)
{
return(x+y);
}
int sub(int x,int y)
{
return(x-y);
}
int mult(int x,int y)
{
return(x*y);
}
int div(int x,int y)
{
if(y!=0)
{
return(x/y);
}
printf(“mult() fail!the second para can not be zero!n “);
return(-1);
}
利用gcc工具编译gcc a.c b.c –o demo,再运行./demo,结果为
x = 10,y = 5
x + y = 15
x – y = 5
x * y = 50
x / y = 2。
小结:由上面简单的例子可以看出,在b.h文件中声明好b.c的函数,使用时,只需要在a.c中包含#include “b.h”头文件即可,这样就可以使用b.c的接口函数了,在实际工程中,通常也是采用这种方式,.c文件中实现函数,.h文件中声明函数借口,需要调用.c文件的函数接口时,只需包含.h头文件即可。
3. 总结
在实际工程中,有两种情况比较多。一是利用extern只声明外部函数,不需要传递需要外部声明的变量,一个模块化接口文件对应一个声明接口的头文件,需要调用接口函数时,只需要包含其头文件。二是利用用extern声明外部函数,同时声明需要传递的外部变量,做法和第一种情况一样,声明都放在头文件中,但是,模块文件也需要包含该头文件。另外,如果结构体等比较复杂的变量,则需要包含其定义的头文件。另外,定义的外部变量属于全局变量,其存储方式为静态存储,生存周期为整个程序的生存周期。
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《C语言中extern关键字详解2》
本文地址:http://www.xiupu.net/archives-582.html
关注公众号:
微信赞赏
支付宝赞赏