#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/