C与C++中的extern与static、extern C与__cplusplus的作用

一、概述

以C语言编写的源文件后缀名为.c,以C++语言编写的源文件后缀名为.cpp,C++支持函数的重载,C和C++编译器对函数的编译处理是不完全相同。C++编译后的函数一般是以函数名和形参类型来命名,C则是直接利用函数名进行命名。

假设有函数void MyFunc(int, int, int),则在C++编译后的函数名为_MyFunc_int_int_int,用函数名和参数类型来命名编译后的函数名;而C编译后的函数可能会是_MyFunc,因此C不支持重构。

那么如果需要在C++程序中使用C代码,如何操作呢,这涉及到混合编程。首先看一下extern与static。

二、extern 与 static

extern用于在C和C++语言中声明某变量或者函数的作用域是全局,告诉编译器其声明的函数和变量可以在本文件或其他文件中调用。在头文件中用extern 修饰声明全局对象,引用时处添加该头文件。

例如存在三个文件,A.c, A.h,  B.c。B.c 调用A.c中定义的变量ValueA,在A.h中对该变量进行extern声明,A.c中进行定义。

A.c A.h文件内容

//A.h
#idndef __A_H 
#define __A_Hextern uint16_t ValueA;//extern 声明#endif//A.c
...
uint16_t ValueA;
...

在B.c中添加A.h头文件进行引用:

//B.c
#include "A.h"
...
printf("ValueA = %d\r\n",ValueA);
...

static的作用与extern相反,被static修饰过的函数或者变量只能在本文件中使用,并且对同一变量或者函数无法同时使用static和extern进行修饰。static根据修饰变量处在的位置不同,其作用域也不同。在函数内部修饰变量(静态局部变量),编译过后该值存放在全局变量处,但作用域只是该函数,即只能该函数使用该变量。在函数外部修饰(静态变量),只能在该文件内使用。

举个例子:一个求和函数的写法,函数递归调用,每次调用的计算结果存在函数的局部静态变量_sum中。

int sum(int m, int n)
{static int _sum = 0;if(m == n){return n;//退出条件}   else{_sum += sum(++m,n);// 递归条件}return _sum;
}

三、extern C 与__cpluscplus

extern C是扩展C的意思,常用在头文件的开头处,写为:extern "C" 。用于描述被它修饰的目标是外部实现的,被它修饰的目标代码是C语言编写的。extern "C" 紧跟花括号{}来指明其作用域,代码和定义等内容放在括号{ }中。

嵌入式开发基本采用C语言,因此在一些头文件中会看到extern C,例如以下头文件代码:

#ifndef __STM32F100xB_H
#define __STM32F100xB_H#ifdef __cplusplusextern "C" {
#endif ...
...#ifdef __cplusplus}
#endif /* __cplusplus */  
#endif /* __STM32F100xB_H */

__cpluscplus是C++定义的宏,被定义为一个整形值,随着标准的更新,这个值将增大。在c++03中,__cplusplus定义为199711L;在c++11中,__cplusplus定义为201103L。所以还可以利用__cplusplus对编译器进行检测,看其是否支持c++11。

#if __cplusplus < 201103L#error "should use c++11 implementation"
#endif // __cplusplus

一般来说新建的.cpp文件会定义__cplusplus。


 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

共谋节点两个单列表

题目&#xff1a;输入两个单链表。找出公共结点。 思路&#xff1a;若两个单链表有公共结点。其形状必然为“Y”型&#xff0c;也就是说公共结点后的全部结点都是同样的。我们首先获得两个链表的长度。求得长度之差为n&#xff0c;再定义两个指针分别指向两个链表首部&#xff…

bzero, memset ,setmem 区别

From: http://blog.csdn.net/agathe/article/details/6066157 bzero 原型&#xff1a; extern void bzero(void *s, int n);用法&#xff1a; #include <string.h>功能&#xff1a;置字节字符串s的前n个字节为零。 说明&#xff1a;bzero无返回值。 举例&am…

OPENCV2.2移植说明

OPENCV2.2移植说明 系统&#xff1a;Ubuntu10.10  编译OPENCV2.2 reference URL: http://opencv.willowgarage.com/wiki/InstallGuide  安装库&#xff1a; apt-get install build-essential cmake pkg-config libpng12-0 libpng12-dev libpng-dev li…

前端问题记录1:debounce is not a function

目录 项目场景&#xff1a; 问题描述&#xff1a; 原因分析&#xff1a; 解决方案&#xff1a; 项目场景&#xff1a; 问题描述&#xff1a; 原因分析&#xff1a; 变量重名 解决方案&#xff1a; 变量重名 关注我 一起进入前端学习群 谢谢

计算机word求差函数,表格里怎么自动求差/怎样在word2010表格中求差

如何在Excel表格中求差你这15分貌似很好赚啊怎样在word2010表格中求差一步&#xff1a;打开Excel&#xff0c;单击第一排&#xff0c;第三个“格”&#xff0c;也就C1&#xff0c;在C1中输入“A1-B1”&#xff1b;第二步&#xff1a;这个公式的意思就是说&#xff1a;A1-B1C1&a…

Linux 使用fcntl c_cc[VMIN] c_cc[CTIME]设置串口阻塞与非阻塞读取数据

一、概述 Linux串口非常灵活&#xff0c;可以根据需要配置成标准串口和自定义串口模式&#xff0c;就Linux 串口读取数据来说&#xff0c;有有两种主要方式&#xff1a;阻塞与非阻塞。 阻塞&#xff1a;一直等待数据&#xff0c;直到退出条件成立&#xff1b;非阻塞&#xff…

CSS3选择器(二)--表单

:enabled 选择可用状态的表单元素 :disabled 选择不可用状态的表单元素 :checked 复选框、单选框选中状态的选项 ::selection 用来匹配突出显示的文本(用鼠标选择文本时的文本)。 :read-only 用来指定处于只读状态元素的样式.即元素中设置了“readonly’readonly’” :read…

Linux Shell 通配符、元字符、转义符使用实例介绍

From: http://www.cnblogs.com/chengmo/archive/2010/10/17/1853344.html 说到shell通配符&#xff08;wildcard&#xff09;&#xff0c;大家在使用时候会经常用到。下面是一个实例&#xff1a; ?1?1234[chengmolocalhost ~/shell]$ lsa.txt b.txt c.old#2?1234[chengmo…

ant design model实现图片预览

代码部分 <divgutter{16}style{{width: 100%,display: flex,justifyContent: space-between,flexWrap: wrap ,}}>{detailMsg.imgList &&detailMsg.imgList.map((item, index) > (<div style{{ width: 30% }} key{index} onClick{() > this.handleClick(…

VMware Workstation Pro 无法在Windows 上运行的 解决办法

一、问题描述 国庆期间window10来了一次更新&#xff0c;导致VMware Workstation 无法在windows上运行&#xff0c;我的虚拟机版本是VMware Pro14。有两种方法解决该问题&#xff0c;第一种是直接卸载新安装的windows安装包&#xff0c;然后重启。第二种方式是升级VMware到最新…

机器学习之深度学习

本文基于台大机器学习技法系列课程进行的笔记总结。 一、主要内容 topic 1 深度神经网络结构 从类神经网络结构中我们已经发现了神经网络中的每一层实际上都是对前一层进行的特征转换&#xff0c;也就是特征抽取。一般的隐藏层&#xff08;hidden layer&#xff09;较少的类神…

sockaddr和sockaddr_in的区别

From: http://www.it165.net/pro/html/201211/4066.html 初学者很容易对二者有困惑的感觉&#xff0c;下面来讲一下二者的区别。 sockaddr是在头文件 /usr/include/bits/socket.h 中定义的&#xff0c;如下&#xff1a; view sourceprint?1.struct sockaddr2.{3.__SOCKADDR_C…

[react] 什么时候使用状态管理器?

[react] 什么时候使用状态管理器&#xff1f; 1用户的使用方式复杂 2.不同身份的用户有不同的使用方式&#xff08;比如普通用户和管理员&#xff09; 3.多个用户之间可以协作 4.与服务器大量交互&#xff0c;或者使用了WebSocket 5.View要从多个来源获取数据 从组件角度看 1.…

FlexViewer2.3中拉帘Widget下载

http://www.giser.net/?p280 由于最新的ArcGIS API for flex2.x使用了Flex SDK4&#xff0c;因此造成了对之前ArcGIS API for flex1.x制 作的拉帘Widget无法使用&#xff0c;因此重新制作了拉帘工具供大家使用。 下载地址&#xff1a; Swipe 使用方法&#xff1a;将下载后的sw…

scanf sscanf 的用法

一、scanf函数 scanf() - 以屏幕(stdin)为输入源&#xff0c;提取输入指定格式的数据&#xff0c;返回提取的数据个数。 函数原型:int scanf( const char *format [,argument]... ); 二、sscanf函数 sscanf() - 从一个字符串中读进与指定格式相符的数据&#xff0c;非常适合…

spring ioc原理

IOC&#xff08;DI&#xff09;&#xff1a;java程序员都知道&#xff1a;java程序中的每个业务逻辑 至少需要两个或以上的对象来协作完成&#xff0c;通常&#xff0c;每个对象在使用他的合作对象时&#xff0c;自己均要使用像new object&#xff08;&#xff09; 这样的语法来…

五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O

From: http://blog.163.com/xychenbaihuyeah/blog/static/13222965520112163171778/ 五种I/O 模式&#xff1a; 【1】 阻塞 I/O (Linux下的I/O操作默认是阻塞I/O&#xff0c;即open和socket创建的I/O都是阻塞I/O) 【2】 非阻塞 I/O (可以通过f…

【hive】Hive中的大宽表及其底层详细技术点

简介: 在大数据环境中&#xff0c;处理大规模数据集是常见的需求。为了满足这种需求&#xff0c;Hive引入了大宽表&#xff08;Large Wide Table&#xff09;的概念&#xff0c;它是一种在Hive中管理和处理大量列的数据表格。本文将详细介绍Hive中的大宽表概念以及其底层的详细…

[react] render函数中return如果没有使用()会有什么问题?

[react] render函数中return如果没有使用()会有什么问题&#xff1f; 我们在使用JSX语法书写react代码时&#xff0c;babel会将JSX语法编译成js&#xff0c;同时会在每行自动添加分号&#xff08;&#xff1b;&#xff09;&#xff0c;如果return后换行了&#xff0c;那么就会…

小程序tabbar文字在服务器上不显示,小程序的tabbar不显示

1. tabbar 不显示刚开始给页面加tabbar时{"pages":["pages/index/index","pages/all/all","pages/relax/relax","pages/me/me","pages/wen/wen","pages/logs/logs"],"window":{"backgro…