亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入解讀C++ 內(nèi)聯(lián)函數(shù)inline|nullptr

 更新時(shí)間:2024年07月18日 09:28:44   作者:Harper·Lee  
內(nèi)聯(lián)函數(shù):用** inline 修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用的地方展開(kāi)內(nèi)聯(lián)函數(shù)**,這樣調(diào)用內(nèi)聯(lián)函數(shù)就需要?jiǎng)?chuàng)建棧楨,就提高效率了,這篇文章給大家介紹C++ 內(nèi)聯(lián)函數(shù)inline|nullptr的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧

一、inline關(guān)鍵字

1.1 什么是內(nèi)聯(lián)函數(shù)?

內(nèi)聯(lián)函數(shù):用** inline 修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用的地方展開(kāi)內(nèi)聯(lián)函數(shù)**,這樣調(diào)用內(nèi)聯(lián)函數(shù)就需要?jiǎng)?chuàng)建棧楨,就提高效率了。

1.2 為什么會(huì)有內(nèi)聯(lián)函數(shù)?

1.2.1 回顧宏

主要目的就是為了替代C語(yǔ)言中的宏。先回顧一下什么是宏:

宏就是一種替換,右邊的替換掉左邊的;

#include<iostream>
using namespace std;
//right
#define ADD(x,y) ((x)+(y))//括起來(lái)
int main()
{
    int ret = ADD(1,2);//替換后:int ret = ((1)+(2));
    cout << ADD(1,2) << endl;
    return 0;
}

宏的末尾不能加分號(hào),否則 ; 對(duì)語(yǔ)句造成干擾,出現(xiàn)語(yǔ)法錯(cuò)誤。

#include<iostream>
using namespace std;
//如果加了分號(hào)
#define ADD(x,y) ((x)+(y));
int main()
{
    int ret = ADD(1,2);//替換后:int ret = ((1)+(2));
    cout << ADD(1,2); << endl;//error
    return 0;
}

宏用于替換的表達(dá)式一定加整體括號(hào)。

C語(yǔ)言中宏的缺點(diǎn):

  • 不能進(jìn)行調(diào)試(預(yù)處理時(shí)宏就被處理掉了)。
  • 沒(méi)有類型安全的檢查。
  • 缺一個(gè)括號(hào)都容易出現(xiàn)錯(cuò)誤。有里面的括號(hào),也有外層的括號(hào)。括號(hào)的優(yōu)先級(jí)最高。
  • 復(fù)雜時(shí)容易寫(xiě)錯(cuò)。例如一個(gè)加法函數(shù):
//right
#define ADD(x,y) ((x)+(y))//括起來(lái)
int main()
{
    int ret = ADD(1,2);//替換后:int ret = ((1)+(2));
    return 0;
}
//error
#define ADD(x,y) (x+y)
#define ADD(x,y) (x)+(y)
#define ADD(x,y) (x+y)
#define ADD(x,y) ((x)+(y));//不能加分號(hào)
#define ADD(int x,int y) return x+y;//不能加分號(hào);

1.2.2 宏的改進(jìn)–內(nèi)聯(lián)函數(shù)

根據(jù)上面的回顧可知,宏的問(wèn)題缺陷很多,因此C++將它改進(jìn)為一種函數(shù)——內(nèi)聯(lián)函數(shù)。
C語(yǔ)言實(shí)現(xiàn)宏函數(shù)時(shí),也會(huì)在預(yù)處理是替換展開(kāi),但是宏函數(shù)實(shí)現(xiàn)很復(fù)雜很容易出錯(cuò),而且不方便調(diào)試,C++設(shè)計(jì)實(shí)現(xiàn) inline 的目的就是替代C的宏函數(shù)。

1.3 內(nèi)聯(lián)函數(shù)的特性

宏不能進(jìn)行調(diào)試,但是內(nèi)聯(lián)函數(shù)可以。宏的原理是直接替換,內(nèi)聯(lián)函數(shù)的原理根據(jù)反匯編研究。

#include<iostream>
using namespace std;
inline int Add(int a, int b)
{
	int ret = a + b;
	return ret;
}
int main()
{
	int ret = Add(1, 2);
	cout << Add(1, 2) * 5 << endl;
	cout << ret << endl;
	return 0;
}

inline 對(duì)于編譯器而言只是一個(gè)建議,不同編譯器關(guān)于 inline 什么情況展開(kāi)各不相同。也就是說(shuō),就算加了 inline,編譯器也可以選擇在調(diào)用的地方不展開(kāi)。因?yàn)镃++標(biāo)準(zhǔn)沒(méi)有規(guī)定這個(gè)。一般建議:將函數(shù)規(guī)模較小(即函數(shù)不是很長(zhǎng),具體沒(méi)有準(zhǔn)確的說(shuō)法,取決于編譯器內(nèi)部實(shí)現(xiàn))、不是遞歸、且頻繁調(diào)用的函數(shù)采用inline修飾,否則編譯器會(huì)忽略inline特性,直接選擇調(diào)用該函數(shù),不再展開(kāi)。

**VS編譯器debug版本下默認(rèn)是不展開(kāi) inline 的,這樣方便調(diào)試。**讓編譯器展開(kāi) inline 內(nèi)聯(lián)函數(shù)的具體操作如下:(兩個(gè)地方改動(dòng))編譯器無(wú)條件展開(kāi)其實(shí)是有條件的 :如果某個(gè)大函數(shù)有許多地方都在調(diào)用,若每個(gè)位置都展開(kāi),函數(shù)的合計(jì)展開(kāi)次數(shù)就會(huì)很大,指令就會(huì)非常多。大函數(shù)進(jìn)行內(nèi)聯(lián)展開(kāi),編譯的可執(zhí)行程序變大,用戶體驗(yàn)感變差。

a.

b.

**inline 不建議聲明和定義分離到兩個(gè)文件,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。C++編譯器默認(rèn)不需要函數(shù)地址。**所以 inline 被展開(kāi),沒(méi)有函數(shù)地址,鏈接時(shí)就會(huì)出現(xiàn)報(bào)錯(cuò)。也就是說(shuō),**加了inline的函數(shù)會(huì)讓編譯器認(rèn)為這并不是一個(gè)函數(shù),所以不會(huì)被存到函數(shù)調(diào)用符號(hào)表里,因此不能將聲明和定義分離??!**正確做法:將inline的聲明和定義都放在頭文件里!這樣子在預(yù)處理的時(shí)候該定義就會(huì)被放到執(zhí)行文件里。

// F.h
#include <iostream>
using namespace std;
inline void f(int i);//聲明
// F.cpp
#include "F.h"
void f(int i)//定義
{
	cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{
	// 鏈接錯(cuò)誤:?法解析的外部符號(hào) 
	f(10);//鏈接:但是.h文件中函數(shù)的聲明被inline修飾了,就沒(méi)有函數(shù)地址 
	return 0;
}

二、指針空值nullptr

2.1 C和C++中NULL的含義

NULL實(shí)際上是一個(gè)宏NULL,在傳統(tǒng)C語(yǔ)言文件stddef.h中,可以看到如下代碼:

#ifndef NULL
#ifdef __cplusplus
#define NULL  0
#else
#define NULL  ((void *)0)
#endif
#endif

由上面的代碼可以看出,NULL可能被定義為是字面常量0,或者被定義為是無(wú)類型指針(void)的常量。這兩種定義在使用空值指針時(shí),就會(huì)出現(xiàn)歧義。比如下面:*

#include<iostream>
using namespace std;
void f(int x)
{
	cout << "f(int x)" << endl;
}
void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}
int main()
{
	f(0);
	// 本想通過(guò)f(NULL)調(diào)?指針版本的f(int*)函數(shù),但是由于NULL被定義成0,調(diào)?了f(intx),因此與程序的初衷相悖。
	f(NULL);
	f((int*)NULL);//NULL寫(xiě)成0也可以
	// f((void*)NULL);//強(qiáng)轉(zhuǎn)成void*,編譯報(bào)錯(cuò):error C2665: “f”: 2 個(gè)重載中沒(méi)有?個(gè)可以轉(zhuǎn)換所有參數(shù)類型
    f(nullptr);
	return 0;
}

運(yùn)行結(jié)果:

image.png

根據(jù)運(yùn)行結(jié)果可知,NULL被定義為0,就沒(méi)有調(diào)用指針版本的 f(int*) 函數(shù)。
為了解決這個(gè)問(wèn)題,C++11中引入了一個(gè)特殊的關(guān)鍵字——nullptr,這樣就可以調(diào)用該函數(shù)了。

2.2 nullptr的特點(diǎn)

nullptr有以下幾個(gè)特點(diǎn):

nullptr是一種特殊類型的字面量,它可以轉(zhuǎn)化成任一其他類型的指針類型。

使用nullptr定義空指針可以避免類型轉(zhuǎn)換的問(wèn)題,因?yàn)?strong>nullptr只能被隱式轉(zhuǎn)換位指針類型,而不能轉(zhuǎn)換成整數(shù)類型。

int* p1 = nullptr;  //right
int i = nullptr;    //error

2.3 C和C++中void*的區(qū)別

上面的例子代碼中,f(void*) NULL;會(huì)報(bào)錯(cuò),報(bào)錯(cuò)原因分析:C語(yǔ)言中 void 指針是一個(gè)垃圾桶,什么類型的指針都可以接受;C++中 void 指針需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。**

//test.c
void* p1 = NULL;   //p1表示空指針
void* p2 = p1;     //right,不用強(qiáng)轉(zhuǎn)
//test.cpp
void* p3 = NULL;
int* p4 = p3;      //error
int* p5 = (int*)p3;//right,需要強(qiáng)轉(zhuǎn)

到此這篇關(guān)于C++ 內(nèi)聯(lián)函數(shù)inline|nullptr的文章就介紹到這了,更多相關(guān)C++ 內(nèi)聯(lián)函數(shù)inline|nullptr內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫(xiě)的操作

    C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫(xiě)的操作

    本文將使用標(biāo)準(zhǔn)C++庫(kù)實(shí)現(xiàn)對(duì)數(shù)據(jù)為PCM格式的WAV文件的讀寫(xiě)操作,只使用標(biāo)準(zhǔn)C++庫(kù)函數(shù),不依賴于其他的庫(kù),對(duì)C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫(xiě)相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-01-01
  • 基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法示例

    基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法示例

    這篇文章主要介紹了基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法,結(jié)合具體實(shí)例形式分析了C語(yǔ)言解決迷宮問(wèn)題算法的實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-09-09
  • windows?使用ffmpeg?.a靜態(tài)庫(kù)讀取Wav音頻并保存PCM的方法

    windows?使用ffmpeg?.a靜態(tài)庫(kù)讀取Wav音頻并保存PCM的方法

    這篇文章主要介紹了windows?使用ffmpeg?.a靜態(tài)庫(kù)讀取Wav音頻并保存PCM,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-02-02
  • C++拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載詳解

    C++拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載詳解

    拷貝構(gòu)造函數(shù)是特殊的構(gòu)造函數(shù),是用一個(gè)已經(jīng)存在的對(duì)象,賦值拷貝給另一個(gè)新創(chuàng)建的已經(jīng)存在的對(duì)象,這篇文章主要介紹了C++拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載,需要的朋友可以參考下
    2024-05-05
  • c++實(shí)現(xiàn)掃雷小游戲代碼分享

    c++實(shí)現(xiàn)掃雷小游戲代碼分享

    這篇文章主要介紹了c++實(shí)現(xiàn)掃雷小游戲并附上代碼分享,代碼不能夠?qū)崿F(xiàn)當(dāng)所查坐標(biāo)周?chē)椎臄?shù)量為0時(shí),直接展開(kāi)周?chē)鴺?biāo),但有一點(diǎn)的知識(shí)性參考價(jià)值,需要的小伙伴可以參考一下
    2022-02-02
  • C++通過(guò)類實(shí)現(xiàn)線性表

    C++通過(guò)類實(shí)現(xiàn)線性表

    這篇文章主要為大家詳細(xì)介紹了C++通過(guò)類實(shí)現(xiàn)線性表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++之智能指針初步及棄用auto_ptr的原因分析

    C++之智能指針初步及棄用auto_ptr的原因分析

    這篇文章主要介紹了C++之智能指針初步及棄用auto_ptr的原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++接口文件小技巧之PIMPL詳解

    C++接口文件小技巧之PIMPL詳解

    C++ 里面有一些慣用法(idioms),如 RAII,PIMPL,copy-swap、CRTP、SFINAE 等,今天要說(shuō)的是 PIMPL,即 Pointer To Implementation,指向?qū)崿F(xiàn)的指針,感興趣的可以了解一下
    2023-06-06
  • C++枚舉類型用法總結(jié)(枚舉字符常量代替常量)

    C++枚舉類型用法總結(jié)(枚舉字符常量代替常量)

    這篇文章主要介紹了C++枚舉類型用法總結(jié)(枚舉字符常量代替常量),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 使用matlab繪制七夕表白玫瑰花束

    使用matlab繪制七夕表白玫瑰花束

    又是一年七夕節(jié)要到了,每年一次直男審美MATLAB繪圖大賽開(kāi)始了,于是今年對(duì)我之前寫(xiě)的老代碼進(jìn)行了點(diǎn)優(yōu)化組合,整了個(gè)花球變花束,感興趣的小伙伴可以動(dòng)手試一試
    2023-08-08

最新評(píng)論