C语言extern与static的用法,及extern "c "

一、c语言static与extern的用法

1.static和extern:

大工程下我们会碰到很多源文件。

文件a.c

static int i; //只在a文件中用

int j; //在工程里用

static void init() //只在a文件中用

{

}

void callme() //在工程中用

{

static int sum;

}

上面的全局i变量和init()函数只能用在a.c文件中,全局变量sum的作用域只在callme里。变量j和函数callme()的全

局限扩充到整个工程文件。所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。

文件b.c

extern int j; //调用a文件里的

extern void callme(); //调用a文件里的

int main()

{

...

}

extern的另外用法是当C和C++混合编程时如果c++调用的是c源文件定义的函数或者变量,那么要加extern来告诉编译器用c方式命名函数:

文件A.cpp调用a.c里面的变量i和函数callme()

extern "C" //在c++文件里调用c文件中的变量

{

int j;

void callme();

}

int main()

{

callme();

}

2.static法则

A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;

B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;

二、extern ”c"

extern "C"的作用是在C++编译器中生成C的变量和函数符号

extern "C"包含双重含义,

一:被它修饰的目标是“extern”的;

二:被它修饰的目标是“C”的。

1)函数或变量是extern类型的;导出函数或变量,使其它模块可以用

extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其他模块中使用。

注意:extern int a;

仅仅是在声明一个变量,并不是定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。

通常,在模块的头文件中对模块提供给其他模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只

需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错,它会在连接阶段中从模块A编译生

成的目标代码中找到此函数。

与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern "C"修饰。

2)被extern "C"修饰的变量和函数是按照C语言方式编译和连接的

作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。

例如,假设某个函数的原型为:void foo(int x, int y);

函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能产生的名字不同,但是

都采用了相同的机制)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。

例如,在C++中,函数void foo(int x, int y)与void foo(int x, float y)编译产生的符号是不相同的,后者为_foo_int_float。

extern "C"作用:实现C++与C及其它语言的混合编程。

---在C++中导出C的符号

3)extern "C"的惯用法

A)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

extern "C"

{

#include "cExample.h"

}

而在C语言的头文件中,对其外部函数只能指定为extern类型,(C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。)

例如:

/*c语言头文件:cExample.h*/

#ifndef C_EXAMPLE_H

#define C_EXAMPLE_H

extern int add(int x, int y);  //c中导出函数add

#endif

/*c语言实现文件:cExample.c*/

#include "cExample.h"

int add(int x, int y)

{

return x+y;

}

//以上C和h以.c方式被编译,产生"_add"这样的符号

//c++实现文件,cppFile.cpp

extern "C"

{

#include "cExample.h"

}

int main(int argc, char *argv[])

{

add(2,3);

return 0;

}

.cpp以.cpp方式被编译: 而add()被extern "C"限定为C方式编译为_add

在调用: add(2,3)时,就调用_add(2,3)

当cExample.c和cppFile.cpp的.o文件连接时,就把符号匹配上

B)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern

"C"的头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型.也就是说,在C中需要重复声明一下。

例如:

//C++头文件 cppExample.h

#ifndef CPP_EXAMPLE_H

#define CPP_EXAMPLE_H

extern "C" int add(int x, int y);

#endif

//C++实现文件 cppExample.cpp

#include "cppExample.h"

int add(int x, int y)

{

return x+y;

}

//cpp以.cpp方式被编译: 而add()被extern "C"限定为C方式编译为_add

/*C实现文件cFile.c

/*这样会编译出错:#include "cExample.h"*/

extern int add(int x, int y);

int main(int argc, char *argv[])

{

add(2,3);

return 0;

}

.在c中就直接调用就可以了.

转自:http://blog.21ic.com/user1/7747/archives/2010/76557.html

c语言中的static和extern,C语言extern与static的用法,及extern “c相关推荐

  1. c语言中 printf(quot;nquot;),关于C语言 printf(quot;%d\nquot;,printf(quot;%dquot;,printf(quot;%dquot;...

    luokaiwei19824级被浏览104次2013.10.11 检举 #include int main(){ int i=43; printf("%d\n",printf(&q ...

  2. 在众多编程语言中,你可知哪种语言的安全性更高,安全漏洞最少?

    编程语言之争,一直以来是开发者社区的热议问题,因为开发者喜欢证明自己所使用的编程语言占据主导地位,尤其是安全性,只不过讨论的过程往往都伴随着双方的愤怒,最后不了了之.那么,你可知在众多热门编程语言中, ...

  3. c语言中const的作用面试,C语言const关键字作用

    C语言中const代表着"不可变",基本和常量一样不可修改,但是应用场景不一样. 一.应用在变量 const char a='A'; a='B';  //错误,变量a的值不可以修改 ...

  4. c语言中switch结构,switch结构c语言

    C语言中switch结构的使用 用switch结构编制程序,输入1个学生的C语言课程考试成绩(百分制整形数因为case后面不能接范围,也就是说case后面是一个确实固定的常量.用下面的方法比较好, # ...

  5. c语言中break语句的功能,C语言break语句

    C语言中的break语句用于中断循环的执行(while,do while和for)和switch case. 在内循环的情况下,仅终止内循环的控制. C语言中有两种使用break关键字: 与switc ...

  6. c语言中int 3.6 =,(C语言中的常量)乐创DIY C语言讲义​——3.6节

    3.6 常量 常量,顾名思义就是在程序执行期间不会改变的固定值.在C语言中,常量的主要作用有两个,其一为给变量赋值,其二为与变量比较,作为判断条件. 在C语言程序中的常量有四大类,分别是整数型常量,浮 ...

  7. C语言中,printf、sprintf、fprintf之间的区别及用法举例

    目录 1. printf 2. sprintf 3. fprintf 在C语言中,sprintf.printf.fprintf都是用来输出字符串的函数,它们之间的主要区别在于输出的位置不同. 它们之间 ...

  8. Go语言中的JSON处理 【Go语言圣经笔记】

    JSON JavaScript对象简谱(JSON, Java Script Object Notation)是一种用于发送和接收结构化信息的标准协议.在类似的协议中,JSON并不是唯一的一个标准协议. ...

  9. c语言中函数static变量,[转]C语言中的 static变量、static函数

    1. static 变量 静态变量的类型 说明符是 static. 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量. 例如外部变量虽属于静态 存储方式,但不一定是静态变量, ...

  10. c语言中1u1是什么意思,C语言U1的.ppt

    C语言U1的 程序设计基础 ( C 语言 );课程要求; 为什么要学习C语言 1.C语言功能强大,表达能力强 2.生成的目标程序效益高,可移植性好 3.既具有高级语言的优点,又有低级语言特色 4.C语 ...

最新文章

  1. github下载速度改善
  2. 一句话生成数字人形象、昆仑芯2量产…百度大脑升级7.0,王海峰:技术更强了门槛却更低...
  3. 看本地网速_安装 ANSYS 本地帮助
  4. Matlab中用到的bsxfun函数
  5. lombok常用注解使用说明
  6. BCHN近期收到一笔1000 BCH的匿名捐款
  7. windows操作系统的使用 —— 资源监视器
  8. Selectsort Tournamentsort Heapsort
  9. 将Excel的数据导入DataGridView中[原创]
  10. LeetCode4 寻找两个正序数组的中位数
  11. php 延迟输出,PHP循环;如何打印每个结果并将其延迟一秒钟,然后再回显另一个结果?...
  12. vue 圆形 水波_canvas 水滴图、液体进度条、仿加速球、圆球水波图
  13. sd卡插入计算机要格式化,内存卡一直提示格式化,内存卡插电脑要格式化-
  14. win10熄屏时间不对_win10的息屏时间怎么调
  15. oracle设置自增序列,oracle设置自增字段,oracle序列
  16. mysql repeat 游标_mysql循环结构 Repeat ... until循环中使用游标
  17. 联想Thinkpad E430搜不到无线网络
  18. 建模阶段性总结(一)
  19. JavaWeb——RequestResponse笔记
  20. Shopee申请开店需要审核吗?

热门文章

  1. SPI 通信原理详述
  2. 第一次使用零页的缺页页故障
  3. 信访分析 大数据_信访大数据解决方案
  4. PayPal助中国手机游戏开发商制胜海外市场
  5. js数组中indexOf和findIndex的区别
  6. 行内元素,块元素,行内块元素特点
  7. 质量管理岗位中,为何SQE的工资最高?
  8. 关于DevC++如何调试的问题,还不会调试的同学看这里--->>>超级详细调试教程,手把手教你如何调试
  9. 数字经济时代,数字技术颠覆传统商业
  10. UOS 切换任务栏模式为时尚模式或高效模式