小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C/C++中的 extern 和extern“C“關(guān)鍵字的理解和使用(對比兩者的異同)

 lichwoo 2024-12-25

前言

不知道有人是否在意過C中的extern這個關(guān)鍵字,又或者說是否使用過該關(guān)鍵字,當(dāng)學(xué)C++時候,我發(fā)現(xiàn)了在C++中有關(guān)鍵字 extern"C"的用法,和C語言中的 extern還是有區(qū)別的,所以今天來總結(jié)一些對他們的理解,和使用的方式。


一. extern關(guān)鍵字

extern關(guān)鍵字的用法很簡單,就是簡簡單單的聲明,它可以明確的指出一個語句是聲明;
比如extern int i;那么就說明 這是聲明變量 i,而不是定義i,聲明是不開辟內(nèi)存的,定義是開辟內(nèi)存的。
假如int i;沒有extern修飾,那就說明為定義,會分配內(nèi)存空間的。

extern 的使用場景1

extern 可以聲明一個變量,使得該變量是來自其他文件的變量在本文件可以被訪問。

比如:創(chuàng)建兩個文件 test.c 和 main.c文件;
在test.c文件中定義一個全局變量:

//test.c
int i = 20; //定義一個全局變量

在main.c文件,聲明變量 i;

main.c文件
# include<stdio.h>
extern int i; //聲明變量i,當(dāng)編譯鏈接時候,main.c文件就可以訪問到test.c文件的i的值了;
int main()
{
	printf("%d",i);
	return 0;
}

這樣我們就可以跨文件(test.c),在本文件(main.c)訪問這個變量了;


extern 的使用場景2

但是上訴的使用方式并不好,假如我一個大工程,這個工程由超級多的文件,這些文件假如都要訪問
test.c文件的 變量 i,那么,只能在這些文件中,每個文件的開頭都 聲明變量 i,并且,假如我的test.c,不止一個定義一個變量i,有好多其他變量呢?在其他文件訪問時候,都要聲明好多變量,這會使得書寫難度很繁瑣,并且維護(hù)成本也大;

所以一般,我們都把聲明語句放到頭文件使用,即我定義一個test.h的頭文件;
在該頭文件中,聲明 extern int i;
然后,假如你在其他文件要使用改變量i,直接包含該頭文件即可,
比如:test.h 頭文件

//test.h 頭文件
extern int i;
extern int j;
extern int k;
//...
//聲明很多很多變量

在其他.c文件,只要包含該頭文件,就可以啦,比如在main.c文件:

# include<stdio.h>
# include"test.h"
//extern int i; 不用寫了
//extern int j;不用寫了
//extern int k;不用寫了
//...
//聲明很多很多變量,都不用寫了,因?yàn)榘祟^文件,聲明都在頭文件中
int main()
{
	printf("%d %d %d",i,j,k);
	return 0;
}

extern的用法總結(jié)

extern一般用于聲明,在.h文件中,聲明變量或者函數(shù)(函數(shù)可以不加extern,但是最好加上,這樣比較統(tǒng)一);在其他文件要訪問該變量函數(shù)時候,包含頭文件就行哦。


二. extern “C” 的理解和用法

在C++中,extern"C"修飾的語句是按照C語言的方式進(jìn)行編譯的。

怎么理解這句話呢?

我來舉幾個例子:(理解它extern"C"的含義)
我們知道在C++中函數(shù)是可以發(fā)生重載的,即編譯的時候并不會報錯,在C語言中,是沒有重載的說法的;那么假如我用extern"C"去修飾重載的函數(shù)的話,即在編譯時候,就會按照C語言的方式去編譯了:
這個時候,就會發(fā)生錯誤;
看例子:創(chuàng)建一個main.cpp文件

# include<iostream>
using namespace std;

extern "C" void func() //用 extern"C"修飾
{

}
extern "C" void func(int v)//用 extern"C"修飾
{
{

}
int main()
{
	
	return 0;
}

看下面的報錯信息,不允許重載啊,本來我C++文件就是可以重載的,但是用extern“C”修飾過后,就不可重載函數(shù)了,這就是按照C的編譯方式編譯,假如按C++編譯方式編譯那就是能通過的。

在這里插入圖片描述


extern"C" 也是可以修飾聲明函數(shù)的,也說明該函數(shù)時按照C語言的方式編譯;
extern"C" 也是可以用大括號{ } 的方式聲明函數(shù)的;
如下例子:

extern "C" void func(); //用 extern"C"修飾聲明函數(shù)
extern "C" void func(int v);//用 extern"C"修飾聲明函數(shù)
//上訴例子會報錯,C語言編譯沒有重載啊。

///
///
///

extern "C" { //修飾函數(shù)聲明
 	void func();
 	void func(int v);
} //用大括號的方式一起寫進(jìn)來,也是可以。
//上訴例子會報錯,C語言編譯沒有重載啊。

///
///
///

extern "C" { //修飾函數(shù)定義
 	void func()
 	{ 
 	
 	}
 	void func(int v)
 	{
 	
 	}
} //用大括號的方式一起寫進(jìn)來,也是可以。
//上訴例子會報錯,C語言編譯沒有重載啊。

但是可以使用大括號的方式使用extern“C”,這是正確的

看看下面的例子:

# include<iostream>
using namespace std;

extern "C" void func() //用 extern"C"修飾
{

}
 void func(int v) //這個不用extern“C”聲明
 {
 
 }

int main()
{
	
	return 0;
}

上面的情況不會報錯,原因很簡單:extern "C" void func() { }按C語言方式編譯,這個不會錯;void func(int v){ }按C++方式編譯,所以也不會報錯,這兩者雖然函數(shù)名字相同,但是他們時按照不同的編譯方式編譯的,所以不報錯;


extern"C "使用 在C與C++混合開發(fā)中的使用方式

通常在C++ 中,假如需要使用C語言中的庫文件的話,可以使用extern "C"去包含

那如何使用呢?接下來我一步一步帶你理解如何使用,先舉幾個例子。

比如:創(chuàng)建math.c(C文件)中,有一些函數(shù)是數(shù)學(xué)的加法和減法功能函數(shù)。
我想在main.cpp文件中使用math.c文件中的函數(shù),如何使用呢?
第一種辦法:在main.cpp文件用extern"C"包含math.c文件中的你想用的函數(shù)。

//math.c文件

int add (int x,int y)//加法
{
	return x+y;
}
int sub(int x,int y)//減法
{
	return x-y;
}
int mult(int x,int y)//乘法
{
	return x*y;
}
int div(int x,int y) //除法
{
	return x/y;
}

main.cpp(C++文件)中,要使用math.c文件中的函數(shù).

//main.cpp文件
#include<iostream>
using namespace std;
extern “C” //用extern“C”{ }聲明math.c文件中的函數(shù),以至于可以在main.cpp文件使用。
{
	int add (int x,int y);
	int sub(int x,int y);	
}

int main()
{
	cout<<add(10,20)<<endl; //由于有聲明該函數(shù),所以訪問成功,結(jié)果30
	cout<<sub(10,20)<<endl;//由于有聲明該函數(shù),所以訪問成功,結(jié)果-10
	return 0;
}

第二種使用方式:

假如我有一個需求,我想在main.cpp文件,用math.c文件中的其他函數(shù),比如除法函數(shù),乘法函數(shù);
那么我就只能在 main.cpp 中 extern"C"{ }的括號中,逐個的加上這兩個函數(shù);這好像也可以正常使用沒問題,但是,這很麻煩啊,別人使用你的.c庫時候會先得非常麻煩。所以我們一般使用頭文件的方式,即創(chuàng)建多一個頭文件math.h,在math.h里聲明函數(shù),在math.c文件定義函數(shù),在main.cpp,即要使用該庫文件里面,用extern"C"{ } ,在括號里包含該math.h頭文件即可

看下math.h頭文件內(nèi)容:

// math.h文件的內(nèi)容 
int add (int x,int y);//加法
int sub(int x,int y);//減法
int mult(int x,int y);//乘法
int div(int x,int y); //除法

在math.c中定義函數(shù)

//math.c文件

int add (int x,int y)//加法
{
	return x+y;
}
int sub(int x,int y)//減法
{
	return x-y;
}
int mult(int x,int y)//乘法
{
	return x*y;
}
int div(int x,int y) //除法
{
	return x/y;
}

這時候我們只要在main.cpp文件中,用extern “C”{ }包含該頭文件就可以使用了。

//main.cpp文件
#include<iostream>
using namespace std;

extern"C"{ //包含頭文件,該里面是C語言方式編譯的。
	# include"math.h"
}

int main()
{
	cout<<add(10,20)<<endl; //由于有聲明該函數(shù),所以訪問成功,結(jié)果30
	cout<<sub(10,20)<<endl;//由于有聲明該函數(shù),所以訪問成功,結(jié)果-10
	cout<<mutl(10,20)<<endl;
	cout<<div(10,20)<<endl;
	
	return 0;
}

這樣就可以正常使用了。


但是,上面的使用方式還是不太好,該方式還是有一定的問題,什么問題呢?就是我在main.cpp文件使用extern "C"{ #include"math.h"} ,即要多寫一個 extern"C"{ },顯得格外麻煩,再說了,假如還有其他Cpp文件要用這個C語言的庫呢。都是這種方式,extern"C"太麻煩啦 。我們之前都是直接#include"math.h",這樣才是我們平時的使用習(xí)慣呢。

所以有了這第三種使用方式:(為的是直接在main.cpp中,#include"math.h"就可以使用,不用多謝extern"C")

直接在math.h中,用extern"C"的方式修飾就行啦。那么我就可以在main.cpp直接#include"math.h"。
(代碼就不寫啦,文字可以理解就行)


上面的使用有并不是完全好的方式,如何說呢?假如我有一個.c文件,創(chuàng)建為other.c,我這個文件呢,也想使用math.c的函數(shù),那么我就可以在other.c文件直接包含該math.c文件就可以了,可是事實(shí)卻不如所想,這樣會報錯,報錯的原因是,由于在math.h文件中,聲明函數(shù)用了extern"C",而other.c文件# include"math.h",會包含里面的所有內(nèi)容,包括里面的 extern"C", 這個extern"C"other.c文件,即C語言文件是不認(rèn)識extern"C"啊,所以會報錯

下面展示報錯的代碼,創(chuàng)建other.c文件(C文件),里面包含math.h文件(該文件有extern"C"{ }聲明方式 )

//other.c文件
# include"math.h" 
//包含頭文件,由于這是.c文件,不是.cpp文件。所以.c文件不認(rèn)識extern"C",所以會報錯

void test()
{
	int ret = add(10,20);//報錯,不認(rèn)識,add.
}

所以如何解決上面問題呢? 核心問題是,我希望有一種使用 extern"C"的方式,在C語言文件中,能夠使用該庫,在C++文件中也可以使用該庫。

要解決這個問題:
也是 第四種使用方式

由于編譯器默認(rèn)會在,你創(chuàng)建的任何一個.cpp文件中,默認(rèn)定義一個宏 #define __cplusplus,這個宏是你看不到的,是編譯器默認(rèn)給每個.cpp文件創(chuàng)建的,而在.c文件,即C語言的編譯器,是沒有這個宏的,所以我們可以借助它,來在 math.h文件中使用下面的代碼:

看math.h的代碼

// math.h文件的內(nèi)容 

//意思是如果使用該頭文件math.h的文件定義了__cplusplus,
//則下面代碼到#endif都是有效的,在這里是 extern "C" { 有效
#ifdef __cplusplus 
extern "C" {
#endif  //__cplusplus

int add (int x,int y);//加法
int sub(int x,int y);//減法
int mult(int x,int y);//乘法
int div(int x,int y); //除法

//意思是如果使用該頭文件math.h的文件定義了__cplusplus,
//則下面代碼到#endif都是有效的,在這里是 } 有效
#ifdef __cplusplus
}
#endif  //__cplusplus

在main.cpp文件你直接包含該頭文件math.h就可以使用了;
在other.c文件中你直接包含該頭文件math.h就可以使用了;

只要按上面的方式書寫,那么就可以完美的解決了在C文件和C++文件中混用的問題;你既可以在.c文件使用該頭文件,也可以在.cpp文件中使用該文件庫。

第四種方式是最值得推薦的。


三. 總結(jié)

兩者 extern 和 extern"C"有點(diǎn)區(qū)別:

  1. extren 在C和C++中,都表示聲明語句的意思;
  2. 而 extern"C"是按C語言方式去編譯文件;
  3. extern"C"只能在C++文件使用,extern在C和C++都可以使用;

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多