一、概述
以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。