#ifdef __cplusplus extern "C" { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif
看到了如上一段代碼(《Advance Linux Programming》 代碼列表1.3),從如下幾個方面解讀一下:函數
#ifdef xxx 至關於#if defined(xxx),用於條件編譯,若xxx已經被宏定義,那麼編譯包括其後的各行,直到遇到#endif,#elif,#else語句爲止。spa
__cplusplus是C++的自定義宏,若是定義了這個宏說明這是一段C++代碼。blog
以上代碼的意思就是若是這是一個cpp文件,那麼編譯器就執行extern "C"{}語句。ip
另外在C/C++中經常使用#ifndef xxx/#endif來避免重複的定義,#ifndef xxx至關於#if !defined(xxx)。內存
extern用來聲明變量,該關鍵字告訴編譯器,其聲明的變量和函數能夠在本模塊使用。ci
用extern時僅僅聲明變量而不分配內存空間。在一個項目中函數,變量等在全部源文件中必須保持一致,除非指定定義爲局部的,全局變量在全部模塊中只能定義一次,能夠聲明屢次,但聲明類型必須保持一致。編譯器
注:C語言中的定義和聲明:源碼
聲明:io
extern int x; extern int g(int); int f(int, int);
聲明只指定標識符,不分配空間。編譯
函數的聲明能夠省略extern關鍵字,但加上extern關鍵字能夠知道該函數可能在其餘模塊定義過。
定義:
int x; int g(int x, int y){ return x + y;}
定義是對聲明的實現或實例化。
C和C++編譯的區別:C++爲了支持函數重載,在將代碼編譯到二進制文件後,函數fun(int)的函數名其實已經變成了相似fun_int這種形式,這時調用fun()函數如fun(2)就對應fun_int(2),而在C語言中是沒有重載的,這樣C文件在和C++混合編譯的時候就會報鏈接錯誤。
"C"表示了一種編譯和鏈接的規約,extern "C"則給代碼指定了這種規約,並且不影響語義。函數聲明中聲明指定了extern "C",仍要遵照C++的語法規則,如類型檢測參數轉換等。
若是有多句代碼須要加上extern "C",能夠將它們放到extern "C" {}中。
《Advanced Linux Programming》中第一節的示例就用了extern "C"實現了在C語言中調用C++函數:
代碼列表 1.1 ( main.c ) C源碼—— main.c
#include <stdlib.h> #include <stdio.h> #include 「reciprocal.hpp」 int main (int argc, char **argv) { int i;
i = atoi (argv[1]); printf (「The reciprocal of %d is %g\n」, i, reciprocal (i)); return 0; }
代碼列表 1.2 ( reciprocal.cpp ) C++ 源碼—— reciprocal.cpp
#include <cassert> #include 「reciprocal.hpp」 double reciprocal (int i) { // i 不能爲 0 assert (i != 0); return 1.0/i; }
代碼列表 1.3 ( reciprocal.hpp )包含文件—— reciprocal.hpp
#ifdef __cplusplus extern "C" { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif