extren与.h头文件


#include <iostream>

/*
在test.cpp文件钟定义
#include<stdio.h>

int x = 12345;

int test()
{
	printf("hello!!!\n");
	return 0;
}
*/
int test(); //当没有包含头文件时使用声明就可以用了,函数的定义和声明是不一样的,所以extern可以省略。

extern int x; //当没有包含头文件时使用声明就可以用了.

int main()
{
    std::cout << "Hello World!\n";
	int a[10] = { 1,2,3,4,5,6,7,8,9,0};
	printf("%d\n", a);
	printf("%d\n", &a[0]);  //等价

	test();
	printf("%d", x);
	//system("pause");
	getchar();
	return 0;
}

上面的代码说明extern的一个作用和xx.h文件中声明,xx.cpp文件中定义是一样效果的。

include<xx.h>的意思是在include<xx.h>这里展开xx.文件,这里面有对xx.cpp文件的变量函数等的声明。

我们通常在.h文件写的int a; int  fun();等其实就是extern的声明。注意extern关键字不一定要出现,

在定义变量的时候,这个extern居然可以被省略(定义时,默认均省略);在声明变量的时候,这个extern必须添加在变量前,所以有时会让你搞不清楚到底是声明还是定义。或者说,变量前有extern不一定就是声明,而变量前无extern就只能是定义

也就是说,extern int  a不一定是声明, 看具体有没有赋值,哪个赋值那个是定义,extern int  a = 0;这个是定义。int  a一定是定义。对函数而言,定义和声明有一样就能看出来的区别(有无函数体,所以函数通常都是省略了extern。)总的来说,include的作用可以说是一个集成的extern声明其相对的.cpp文件。他的好处就是不用写一堆的extern。(以前的人写extern不耐烦了才发明的xx.h这个集成的声明文件)

自定义类型的声明:我们都知道类的声明什么都不用谢,在头文件上写 class myclass {......}就行了,主要是结构体的声明。

首先我们先来了解结构体的几种定义方式定义:

//1.常规定义
struct str
{
	std::string arr1;
	std::string arr2;
	
}str1,str3;   //注意,{}内才是定义,str是类型名,str1,str3已经是变量了,str1,str3也可以不写留空。

struct str str2 = {“hello”, " word"}; //定义一个变量

//2.没类型名定义,这种定义只能使用一次
struct 
{
	std::string arr1;
	std::string arr2;
	
}str1; //因为没有类型名,这里是唯一可以声明变量的地方。

//3.使用typedef取别名,省略struct,(事实上c++的struct不用别名也可以省略struct)
typedef struct str
{
	std::string arr1;
	std::string arr2;
	
}str1; //这里的str1不是变量名,是别名,还没有变量产生

str1 = {“hello”, " word!"}; //定义变量

//当然,str也可以不写,和前面不同,这里意义是一样的
typedef struct 
{
	std::string arr1;
	std::string arr2;
	
}str2;

str2 = {“hello”, " word!!!"};



extern在声明内置变量时,编译器是知道内置变量的长度的(类型名的意义就是在内存中定义不同的长度的内存,使用是按照类型名来决定读取多少长度的内存的内容),自定义的strcut编译器是不知道它的内存长度是多少字节的,想要编译器知道的话就要在声明变量之前 定义这个结构体,即是使用方法3的typedef ... str1,定义一个类型,这样编译器就知道extern str1 str2中的str1是什么东西了,基本上就是在相应的头文件上写方法3。

如果在相应的头文件上写方法3的话,有一个很有意思的地方,前面说的头文件的作用其实就是众多extern的集合,include头文件就是把头文件的内容在include的地方展开,那么就会出现在定义文件的头上声明该定义 = =,当然,编译器告你这是合法的。

 

当然在cpp里extern还有jiu'shi使用C语言函数的意思 extern  C 

比如在C++中调用C库函数,就需要在C++程序中用extern “C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern "C" {
        int add(int x, int y); //也可以写下整个头文件
}
#endif
//如果 cExample.h 中声明的函数要被其他 C 模块调用,那么严谨的写法是:

#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
#ifdef __cplusplus
extern "C" {
#endif

int add(int x, int y);

#ifdef __cplusplus
}
#endif
#endif

C++语言在编译的时候为了解决的多态问题,会将名和参数联合起来生成一个中间的名称,而c语言则不会,因此会造成链接时找不到对应的情况,此时C就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间名。

参考文章  http://lpy999.blog.163.com/blog/static/117372061201182051413310/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值