如果编译器在编译cpp文件,那么 _cplusplus
就会被定义,如果是一个C文件被编译,那么 _STDC_
就会被定义,_STDC_
是预定义宏,当它被定义后,编译器将按照ANSIC标准来编译C语言程序。
所以,可以采用下列程序示例判断:
#include<stdio.h>
#ifdef _cplusplus
#define USING_C 0
#else
#define USING_C 1
#endif
#include<stdio.h>
int main()
{
if(USING_C)
printf("C\n");
else
printf("C++\n");
return 0;
}
//在C++编译环境下,程序应输出结果为C++,但不知为何我在visul stdio2010中cpp文件中编译结果为C
需要注意的是,如果在C++编译器里使用通过C编译的目标文件,需要通知C++编译器:
#ifdef _cplusplus
extern "C"{
#endif
//具体的代码
#ifdef _cplusplus
}
#endif
那么,在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”呢?
C++语言是一种面向对象编程语言,支持函数重载,而C语言是面向过程的编程语言,不支持函数重载,所以函数被C++编译后在库中的名字与C语言不同。如果声明一个函数float f(int a,char b)
,C++编译器会将这个名字变成像_f_int_char
之类的东西以支持函数重载,而C编译器内部名为_f
,这样连接器将无法解释C++对f()的调用。
C++提供了C语言替代连接说明符符号extern”C”来解决名字匹配的问题,extern 关键字告诉编译器其声明的函数和变量可以在模块或其他模块中使用。extern后跟一个字符串来指定想声明的函数的连接类型,后面是函数声明。
extern "C"{
float f(int a,char b);
//其他函数
}
//或者写成
extern "c"{
#include "Myheader.h"
//其他C头文件
}
该语句的目的是告诉编译器f()是C连接的,函数f是采用C语言方式链接的,应该在库中找名字_f而不是找_f_int_char
,这样C++就不会转换函数名。标准的连接类型指定符有“C”“C++”两种。