1. 宏中的#
宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号。
如定义好#define STRING(x) #x之后,下面二条语句就等价。
char *pChar = "hello"; == char *pChar = STRING(hello);
还有一个#@是加单引号(Charizing Operator)
#define makechar(x) #@x; == char ch = makechar(b);与char ch = 'b';等价。
注意,宏中遇到#或##时就不会再展开宏中嵌套的宏了。
比如使用char *pChar =STRING(__FILE__);虽然__FILE__本身也是一个宏,但编译器不会展开它,所以pChar将指向"__FILE__"。
因此要加一个中间转换宏,先将__FILE__解析成你希望的字符串。
#define _STRING(x) #x
#define STRING(x) _STRING(x)
再调用下面语句将输出带""的源文件路径
char* pChar = STRING(__FILE__);
printf("%s %s\n", pChar, __FILE__);
2. 宏中的##
##的功能:拼接符号(Token-pasting operator)。
eg. #define paster( n ) printf( "token"#n" = %d\n", token##n )
int token9 = 100;
再调用 paster(9);宏展开后token##n直接合并变成了token9。整个语句变成了 printf( "token""9"" = %d", token9 );
在C语言中字符串中的二个相连的双引号会被自动忽略,于是上句等同于 printf("token9 = %d", token9);。
即输出token9 = 100.
3. extern "C"
extern "C"的真实目的是实现类C和C++的混合编程。在C++源文件中的语句前面加上extern "C",表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约,但仍然要遵守C++的类型检测、参数转换规则。这样在类C的代码中就可以调用C++的函数/变量等。(注:类C,代表的是跟C语言的编译和连接方式一致的所有语言)
4. C++中调用C的代码
假设一个C的头文件cHeader.h中包含一个函数print(int i),为了在C++中能够调用它,必须要加上extern关键字(原因在extern关键字那节已经介绍)。它的代码如下:
1
2
3
4
5
6
|
#ifndef C_HEADER
#define C_HEADER
extern
void
print(
int
i);
#endif C_HEADER
|
相对应的实现文件为cHeader.c的代码为:
1
2
3
4
5
6
|
#include <stdio.h>
#include "cHeader.h"
void
print(
int
i)
{
printf
(
"cHeader %d\n"
,i);
}
|
现在C++的代码文件C++.cpp中引用C中的print(int i)函数:
1
2
3
4
5
6
7
8
9
|
extern
"C"
{
#include "cHeader.h"
}
int
main(
int
argc,
char
** argv)
{
print(3);
return
0;
}
|
5. C中调用C++的代码
现在换成在C中调用C++的代码,这与在C++中调用C的代码有所不同。如下在cppHeader.h头文件中定义了下面的代码:
1
2
3
4
5
6
|
#ifndef CPP_HEADER
#define CPP_HEADER
extern
"C"
void
print(
int
i);
#endif CPP_HEADER
|
相应的实现文件cppHeader.cpp文件中代码如下:
1
2
3
4
5
6
7
8
|
#include "cppHeader.h"
#include <iostream>
using
namespace
std;
void
print(
int
i)
{
cout<<
"cppHeader "
<<i<<endl;
}
|
在C的代码文件c.c中调用print函数:
1
2
3
4
5
6
|
extern
void
print(
int
i);
int
main(
int
argc,
char
** argv)
{
print(3);
return
0;
}
|
注意在C的代码文件中直接#include "cppHeader.h"头文件,编译出错。而且如果不加extern int print(int i)编译也会出错