国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr

這篇具有很好參考價值的文章主要介紹了C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

1.內(nèi)聯(lián)函數(shù)

1.1 概念

1.2 特性

?1.3 內(nèi)聯(lián)函數(shù)與宏的區(qū)別

2.auto關(guān)鍵字(C++11)

2.1?auto簡介

2.2 auto的使用細則

2.3 auto不能推導(dǎo)的場景

3.基于范圍的for循環(huán)(C++11)

3.1 范圍for的語法

3.2 范圍for的使用方法

4.指針空值nullptr(C++11)

4.1 C++98中的指針空值


1.內(nèi)聯(lián)函數(shù)

1.1 概念

以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時C++編譯器會在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開,沒有函數(shù)調(diào)
用建立棧幀的開銷,內(nèi)聯(lián)函數(shù)提升程序運行的效率。

inline int Add(int left, int right)
{
	return left + right;
}

int main()
{
	int ret = 0;
	ret = Add(1, 2);
	return 0;
}

如果在上述函數(shù)前增加inline關(guān)鍵字將其改成內(nèi)聯(lián)函數(shù),在編譯期間編譯器會用函數(shù)體替換函數(shù)的
調(diào)用

查看方式:

  1. 在release模式下,查看編譯器生成的匯編代碼中是否存在call Add,而release模式下不能調(diào)試,所以采用第二種方法。
  2. 在debug模式下,需要對編譯器進行設(shè)置,否則不會展開(因為debug模式下,編譯器默認(rèn)不會對代碼進行優(yōu)化,以下給出vs2022的設(shè)置方式)

右鍵點擊解決方案管理器中的項目名稱,打開屬性,設(shè)置下面兩個選項。?

C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr,C++,c++,開發(fā)語言,nullptr,auto,內(nèi)聯(lián)函數(shù)

?發(fā)現(xiàn)沒有使用調(diào)用函數(shù)指令call,沒有調(diào)用Add函數(shù),而是直接在這里展開了內(nèi)聯(lián)函數(shù)。

C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr,C++,c++,開發(fā)語言,nullptr,auto,內(nèi)聯(lián)函數(shù)

1.2 特性

  • inline是一種以空間換時間的做法,如果編譯器將函數(shù)當(dāng)成內(nèi)聯(lián)函數(shù)處理,在編譯階段,會用函數(shù)體替換函數(shù)調(diào)用,缺陷:可能會使目標(biāo)文件變大,優(yōu)勢:少了調(diào)用開銷,提高程序運行效率。
  • inline對于編譯器而言只是一個建議,當(dāng)不當(dāng)做內(nèi)聯(lián)函數(shù)還需要編譯器自己判斷,不同編譯器對于inline實現(xiàn)機制可能不同,一般建議:將函數(shù)規(guī)模較小(即函數(shù)不是很長,具體沒有準(zhǔn)確的說法,取決于編譯器內(nèi)部實現(xiàn))、不是遞歸、且頻繁調(diào)用的函數(shù)采用inline修飾,否則編譯器會忽略inline特性。下圖為《C++prime》第五版關(guān)于inline的建議:C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr,C++,c++,開發(fā)語言,nullptr,auto,內(nèi)聯(lián)函數(shù)
  • inline不建議聲明和定義分離,分離會導(dǎo)致鏈接錯誤。因為內(nèi)聯(lián)函數(shù)在編譯時展開,如果只有聲明,就找不到,只能通過函數(shù)調(diào)用,但是符號表中沒有內(nèi)聯(lián)函數(shù),因為內(nèi)斂函數(shù)不生成指令,不會進入符號表。
  • 內(nèi)聯(lián)函數(shù)推薦在頭文件中定義。當(dāng)然內(nèi)聯(lián)函數(shù)定義也可以放在源文件中,但此時只有定義的那個源文件可以用它,如果其他源文件使用必須拷貝一份定義。當(dāng)然定義在頭文件中,包含頭文件時編譯器會幫你拷貝一份,不用自己拷貝。
  • 關(guān)鍵字 inline 必須與函數(shù)定義體放在一起才能使函數(shù)成為內(nèi)聯(lián),僅將 inline 放在函數(shù)聲明前面不起任何作用。(聲明前可以不用加 inline)

?1.3 內(nèi)聯(lián)函數(shù)與宏的區(qū)別

  1. 內(nèi)聯(lián)函數(shù)是在編譯時展開(編譯器),而宏在預(yù)編譯時展開(預(yù)處理);在編譯的時候,內(nèi)聯(lián)函數(shù)直接被嵌入到目標(biāo)代碼中去,而宏只是一個簡單的文本替換。
  2. 內(nèi)聯(lián)函數(shù)可以進行類型安全檢查、自動類型轉(zhuǎn)換、語句是否正確等編譯功能,宏不具有這樣的功能。
  3. ?宏在定義時要注意宏參數(shù),一般用括號括起來,否則容易出現(xiàn)二義性。而內(nèi)聯(lián)函數(shù)不會出現(xiàn)二義性。
  4. .宏定義不是真正的函數(shù),沒有參數(shù)類型檢查,不安全;而內(nèi)聯(lián)函數(shù)是真正的函數(shù),有類型檢查,更為安全。

宏函數(shù)實現(xiàn)Add。

#include<iostream>
using namespace std;
#define ADD(x,y) ((x)+(y))
int main()
{
	int a = ADD(1, 2);
	//printf("%d\n", ADD(1, 2));宏不能帶分號
	// #define ADD(x,y) x+y
	//printf("%d\n", ADD(1, 2)*3);//不加括號變?yōu)?+2*3
	cout << a << endl;

	//#define ADD(x,y) (x+y)
	int b = 1, c = 2;
	ADD(b | c, b & c);//x和y不加括號(x+y) 會變?yōu)閎|c+b&c,+優(yōu)先級比位操作符高

	return 0;
}

【面試題】

宏的優(yōu)缺點?
優(yōu)點:

  1. 增強代碼的復(fù)用性,沒有類型的嚴(yán)格限制。
  2. 提高性能,針對頻繁調(diào)用的小函數(shù),不需要再建立棧幀。

缺點:

  1. 不方便調(diào)試宏。(因為預(yù)編譯階段進行了替換)
  2. 導(dǎo)致代碼可讀性差,可維護性差,容易誤用。
  3. 沒有類型安全的檢查。

C++有哪些技術(shù)替代宏?

1. 常量定義 換用const enum
2. 短小函數(shù)定義 換用內(nèi)聯(lián)函數(shù)

2.auto關(guān)鍵字(C++11)

2.1?auto簡介

在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量。

在C++11中,標(biāo)準(zhǔn)委員會賦予了auto全新的含義即:auto不再是一個存儲類型指示符,而是作為一個新的類型指示符來指示編譯器,auto聲明的變量必須由編譯器在編譯時期推導(dǎo)而得。

int TestAuto()
{
    return 10;
}

int main()
{
    int a = 10;
    //int b = a;
    //auto 賦值時,可以通過右邊的值自動推導(dǎo)左邊值的類型
    auto b = a;
    auto c = 'a';
    auto d = TestAuto();
    cout << typeid(b).name() << endl;//可以得到變量的類型
    cout << typeid(c).name() << endl;
    cout << typeid(d).name() << endl;
    //auto e; 無法通過編譯,使用auto定義變量時必須對其進行初始化
    return 0;
}

【注意】

使用auto定義變量時必須對其進行初始化,在編譯階段編譯器需要根據(jù)初始化表達式來推導(dǎo)auto的實際類型。因此auto并非是一種“類型”的聲明,而是一個類型聲明時的“占位符”,編譯器在編譯期會將auto替換為變量實際的類型。


有什么用處呢??隨著程序越來越復(fù)雜,程序中用到的類型也越來越復(fù)雜,經(jīng)常體現(xiàn)在:

  1. 類型難于拼寫
  2. 含義不明確導(dǎo)致容易出錯

比如我們C++以后要學(xué)習(xí)的std::map<std::string, std::string>::iterator 是一個類型,但是該類型太長了,特別容易寫錯。這時可以使用auto自動推導(dǎo)類型。

int main()
{
	//普通情況下,沒有價值
	//類型名很長,就會有價值
	std::vector<std::string> v;
	//std::vector<std::string>::iterator it = v.begin();
	auto it = v.begin();
	return 0;
}

2.2 auto的使用細則

1. auto與指針和引用結(jié)合起來使用

用auto聲明指針類型時,用auto和auto*沒有任何區(qū)別,但用auto聲明引用類型時則必須加&

int main()
{
    int x = 10;
    auto a = &x;
    auto* b = &x;//與上一行相同
    auto& c = x;

    cout << typeid(a).name() << endl;
    cout << typeid(b).name() << endl;
    cout << typeid(c).name() << endl;

    *a = 20;
    *b = 30;
    c = 40;

    return 0;
}

2. 在同一行定義多個變量

當(dāng)在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯器實際只對第一個類型進行推導(dǎo),然后用推導(dǎo)出來的類型定義其他變量。

void TestAuto()
{
    auto a = 1, b = 2;
    auto c = 3, d = 4.0; // 該行代碼會編譯失敗,因為c和d的初始化表達式類型不同
}

2.3 auto不能推導(dǎo)的場景

1. auto不能作為函數(shù)的參數(shù)

// 此處代碼編譯失敗,auto不能作為形參類型,因為編譯器無法對a的實際類型進行推導(dǎo)
void TestAuto(auto a)
{}

2. auto不能直接用來聲明數(shù)組

void TestAuto()
{
    int a[] = {1,2,3};
    auto b[] = {4,5,6};//編譯失敗
}

3. 為了避免與C++98中的auto發(fā)生混淆,C++11只保留了auto作為類型指示符的用法

4. auto在實際中最常見的優(yōu)勢用法就是跟下面會講到的C++11提供的新式for循環(huán),還有后面會學(xué)的lambda表達式等進行配合使用
?

3.基于范圍的for循環(huán)(C++11)

3.1 范圍for的語法

在C++98中如果要遍歷一個數(shù)組,可以按照以下方式進行

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5 };
    for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
        array[i] *= 2;
    for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
        cout << *p << endl;
}

對于一個有范圍的集合而言,由程序員來說明循環(huán)的范圍是多余的,有時候還會容易犯錯誤。因
此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號由冒號“ :”分為兩部分:第一部分是范
圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5 };
   
    for(auto& e : array)//會依次取array中的元素賦值給e
        e *= 2;
    
    //for(auto* e : array)//這種寫法不對,因為array中的元素類型是int類型
    //    (*e) *= 2;      //不是一種地址,這里會發(fā)生類型不匹配
     

    for(auto e : array)
        cout << e << " ";
}

注意:與普通循環(huán)類似,可以用continue來結(jié)束本次循環(huán),也可以用break來跳出整個循環(huán)。

3.2 范圍for的使用方法

1. for循環(huán)迭代的范圍必須是確定的

對于數(shù)組而言,就是數(shù)組中第一個元素和最后一個元素的范圍;對于類而言,應(yīng)該提供begin和end的方法,begin和end就是for循環(huán)迭代的范圍。

注意:以下代碼就有問題,因為for的范圍不確定,因為函數(shù)傳參,array這里只是地址,不是代表一個數(shù)組。

void TestFor(int array[])
{
    for(auto& e : array)
    cout<< e <<endl;
}

2. 迭代的對象要實現(xiàn)++和==的操作。(關(guān)于迭代器這個問題,以后會講,現(xiàn)在提一下,沒辦法
講清楚,現(xiàn)在大家了解一下就可以了)
?

4.指針空值nullptr(C++11)

4.1 C++98中的指針空值

在良好的C/C++編程習(xí)慣中,聲明一個變量時最好給該變量一個合適的初始值,否則可能會出現(xiàn)
不可預(yù)料的錯誤,比如未初始化的指針。如果一個指針沒有合法的指向,我們基本都是按照如下
方式對其進行初始化:

void TestPtr()
{
    int* p1 = NULL;
    int* p2 = 0;
    // ……
}

NULL實際是一個宏,在傳統(tǒng)的C頭文件(stddef.h)中,可以看到如下代碼

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

條件編譯指令,可以看到,NULL可能被定義為字面常量0,或者被定義為無類型指針(void*)的常量。不論采取何種定義,在使用空值的指針時,都不可避免的會遇到一些麻煩,比如在函數(shù)重載中:

void func(int)//參數(shù)類型匹配即可調(diào)用
{
	cout << "void f(int)" << endl;
}

void func(int*)
{
	cout << "void fx(int*)" << endl;
}

int main()
{
	func(0);
	func(NULL);//會調(diào)用第一個函數(shù)
	func((int*)NULL);//調(diào)用第二個

	//#define nullptr ((void*)0)
	func(nullptr);//nullptr類型是void*
	return 0;
}

程序本意是想通過f(NULL)調(diào)用指針版本的f(int*)函數(shù),但是由于NULL被定義成0,因此與程序的
初衷相悖。

在C++98中,字面常量0既可以是一個整形數(shù)字,也可以是無類型的指針(void*)常量,但是編譯器
默認(rèn)情況下將其看成是一個整形常量,如果要將其按照指針方式來使用,必須對其進行強轉(zhuǎn)(void
*)0。所以在(C++11)引入了nullptr表示空指針。#define nullptr ((void*)0)

注意:

  1. ?在使用nullptr表示指針空值時,不需要包含頭文件,因為nullptr是C++11作為新關(guān)鍵字引入的。
  2. 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節(jié)數(shù)相同。
  3. ?為了提高代碼的健壯性,在后續(xù)表示指針空值時建議最好使用nullptr

本篇結(jié)束。?文章來源地址http://www.zghlxwxcb.cn/news/detail-669292.html

到了這里,關(guān)于C++入門:內(nèi)聯(lián)函數(shù),auto,范圍for循環(huán),nullptr的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包