最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++入門(命名空間,缺省參數,函數重載,引用,內聯(lián)函數,auto,范圍for)

 更新時間:2021年05月24日 09:36:35   作者:DR5200  
這篇文章主要介紹了C++入門(命名空間,缺省參數,函數重載,引用,內聯(lián)函數,auto,范圍for),這些基礎知識是學習C++最最基礎需要掌握的知識點,需要的朋友可以參考下

一.C++關鍵字

C++總共有63個關鍵字,在入門階段我們只是大致了解一下就可,在后續(xù)博客中會逐漸講解

二.命名空間

相信學過C++的同學,一定都寫過下面這個簡單的程序

#include<iostream>
using namespace std;
int main()
{
	cout<<"hello world"<<endl;
	return 0;
}

我們先來看第二行代碼,using namespace std , 這行代碼是什么意思呢 ?

這里我們就要來引入命名空間的概念,命名空間是用來解決C語言命名沖突問題的,在我們的C語言階段,如果我們寫了下面的程序,是不能通過編譯的,原因是因為scanf函數包含在 <stdio.h>這個庫里,是一個全局的函數,而我們用scanf去命名全局變量,會報重定義的錯誤,這就導致了命名沖突,C語言是無法解決這個問題的,因此C++為了解決這個問題,引入了命名空間,來做名字的隔離

#include<stdio.h>
int scanf = 10;
int main()
{
	printf("%x\n",scanf);
}

命名空間 :
在C/C++中,變量、函數和我們后面要學到的類都是大量存在的,這些變量、函數和類的名稱將都存在于全局作用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染,namespace關鍵字的出現就是針對這種問題的。

上面的代碼改正后如下

#include<stdio.h>
namespace N
{
	int scanf = 10;
}
int main()
{
	printf("%x\n",scanf);  // 以十六進制打印出scanf函數的地址
	printf("%x\n",N::scanf); // 以十六進制打印出 N命名空間域里的 scanf變量
}

其中 N::scanf 中的 :: 為域作用限定符,表明要打印的 scanf 是 N命名空間域里的

了解了命名空間后,回到我們最開始的問題 using namespace std 是什么意思呢?

C++庫為了防止命名沖突,將自己庫里的東西都定義在一個名為 std 的命名空間里,要使用標準庫里的東西,有以下三種方式:

(1).指定命名空間

#include<iostream>
int main()
{
	std::cout<<"hello world"<<std::endl;
}

(2).把std整個展開,即 using namespace std,雖然使用起來比較方便,但如果我們自己定義的東西跟庫里沖突了,就沒辦法解決了,因此在規(guī)范的工程項目中不推薦此種方式

#include<iostream>
using namespace std;
int main()
{
	cout<<"hello world"<<endl;
}

(3).對部分常用的庫里面的東西展開

#include<iostream>
using std::cout;
using std::endl;
int main()
{
	cout<<"hello world"<<endl;
}

命名空間的幾點注意事項 :

(1). 命名空間里既可以定義變量,也可以定義函數
(2).命名空間可以嵌套定義

namespace A
{
	int a;  // 定義變量
	int Add(int left,int right) // 定義函數
	{
		return left + right;
	}
	namespace B  // 嵌套定義
	{
		int b;
		int Sub(int left,int right)
		{
			return left - right;
		}
	}
}

(3).在同一個工程里可以存在多個相同名稱的命名空間,在編譯時最終會合成到一個命名空間里,因此注意不要定義同名的變量或函數,否則會報重定義的錯誤

三.缺省參數

(1).缺省參數的概念

缺省參數是聲明或定義函數時為函數的參數指定一個默認值。在調用該函數時,如果沒有指定實參則采用該默認值,否則使用指定的實參

void Testfunc(int a = 0) // 缺省參數
{
	cout<<a<<endl;
}
int main()
{
	Testfunc(10); // 使用給定的實參
	Testfunc();   // 使用默認值
}

(2). 缺省參數的分類

全缺省參數 : 函數參數都指定了默認值

void TestFunc(int a = 10,int b = 20,int c = 30)
{
	cout<<a<<endl;
	cout<<b<<endl;
	cout<<c<<endl;
}

半缺省參數 : 函數參數部分指定了默認值

void TestFunc(int a,int b = 20,int c = 30)
{
	cout<<a<<endl;
	cout<<b<<endl;
	cout<<c<<endl;
}

注意 :

(1).半缺省參數必須從右往左依次給出,不能間隔給出

void TestFunc(int a = 10,int b,int c = 20) // 錯誤寫法
{
	cout<<a<<endl;
	cout<<b<<endl;
	cout<<c<<endl;
}

(2).缺省參數不能在聲明和定義中同時出現

a.h
void TestFunc(int a = 10);
a.c
void TetsFunc(int a)
{
	cout<<a<<endl;
}

(3).缺省參數的值必須為常量或全局變量

四.函數重載

(1).函數重載的概念

C語言并不支持同名函數的存在,若定義了同名函數會報重定義的錯誤,C++在C語言的基礎上引入了函數重載的概念,即函數的名稱可以相同,但函數的參數列表不能相同(參數的類型,參數的個數,參數的順序),函數的返回值不能作為重載的標志,原因會在后面解釋

// 函數重載
int Add(int left,int right)
{
	return left + right;
}
double Add(double left,double right)
{
	return left + right;
}

C++重載機制很好理解,但C++是怎么支持重載的呢?為什么C語言不支持重載呢?

在講述這個問題之前,我們要先回顧一下我們之前學的編譯鏈接過程

編譯可分為以下三個階段

1.預處理
預處理階段主要做的事情有以下幾點
(1).頭文件的展開
(2).進行宏替換
(3).去掉注釋
(4).執(zhí)行條件編譯指令

經過預處理階段后生成后綴名為.i的文件

2.編譯
編譯階段主要做的事情有以下幾點
(1).詞法分析
在詞法分析過程中,我們的源代碼程序會被輸入到掃描器中,掃描器會將源代碼的字符序列分割成不同的記號并分類,如關鍵字,標識符,字面量,同時掃描器將分好類的記號存儲到對應的位置,為后面的操作做好鋪墊
(2).語法分析
語法分析是通過建立一顆語法樹來實現的,我們所寫的語句是由多個表達式組成的,因此我們的語法樹是一顆以表達式為結點的樹,在語法分析的過程中,操作符的優(yōu)先級和結合性也被確定下來了,如果在語法分析過程中,出現了語法錯誤,編譯器就會報語法分析階段的錯誤
(3).語義分析
語法分析僅僅對語法進行檢測,但并不知道語義是否正確,這就需要語義分析器上場了,語義分析階段主要做的是類型的匹配,轉換,比如我們將一個浮點型表達式賦值給一個整型表達式,需要進行隱式類型轉換,語義分析需要完成這個步驟,將一個浮點型賦值給一個指針,語義分析會發(fā)現類型不匹配,編譯器會報錯,經過語義分析階段后,語法樹的各個節(jié)點會被標記上類型,需要類型轉換的,會插入相應的轉換節(jié)點

經過編譯階段后,生成了后綴名為.s的匯編代碼文件

3.匯編
匯編階段所做的事情比較簡單,匯編階段將編譯產生的匯編代碼文件轉換成二進制機器指令

經過匯編階段生成后綴名為.o的目標文件

生成的目標文件是按照ELF文件格式進行存儲的,ELF文件由多個段組成,如.text(代碼段) .data(數據段) .symtab(符號表)等,這里重點要說的是符號表,符號表是一個數組,數組的元素是結構體,結構體描述了文件中符號的各種信息(符號名,符號值,符號類型等)

而C++支持函數重載,C不支持函數重載的原因是它們生成符號名時機制不同

C語言在生成符號表時,符號名是變量或函數名
C++在生成符號表時,符號名是函數名和形參列表的組合

如GCC編譯器的修飾規(guī)則如下 :
(1).所有的符號都以_Z開頭
(2).沒有嵌套的名字后跟函數名,函數名前是函數名的字符串長度,后跟參數類型首字母
(3).對于嵌套的名字(在命名空間或類里),后面緊跟'N',然后是命名空間或類的名稱,每個名字前是每個名字的字符串長度,后跟函數名,函數名前是函數名的字符串長度,后跟'E',后跟參數類型首字母

由此我們就知道了C++為什么支持重載,而C語言不支持重載,因為C++生成目標文件以后,同名函數只要參數列表不同,符號名就不相同,而C語言生成目標文件以后,同名函數的符號名相同,就會引發(fā)命名沖突

五.extern"C"

C++為了與C兼容,在符號的管理上,C++有一個用來聲明或定義C的符號的extern "C"關鍵字的用法

extern "C"
{
	int func(int);
	int var;
}

C++編譯器會將大括號里面的代碼當成C語言的代碼來處理

六.引用

引用概念 : 引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內存空間,它和它引用的變量共用同一塊內存空間。

使用: 類型& 引用變量名(對象名) = 引用實體

void TestRef()
{
 	int a = 10;
 	int& ra = a;//<====定義引用類型
 
 	printf("%p\n", &a);
 	printf("%p\n", &ra);
 	// 打印的地址一樣
}

注意 : 引用類型必須和引用實體是同種類型的

引用特性 :
(1).引用必須初始化
(2).引用一旦初始化,不能被更改
(3).一個變量可以有多個引用

void TestRef()
{
 	int a = 10;
 	// int& ra; // 該條語句編譯時會出錯
 	int& ra = a;
 	int& rra = a;
 	printf("%p %p %p\n", &a, &ra, &rra); // 地址都一樣 
}

常引用 :

void TestConstRef()
{
 	const int a = 10;
 	//int& ra = a; // 該語句編譯時會出錯,a為常量
 	const int& ra = a;
 	// int& b = 10; // 該語句編譯時會出錯,b為常量
 	const int& b = 10;
 	double d = 12.34;
 	//int& rd = d; // 該語句編譯時會出錯,類型不同
 	const int& rd = d;
}
const int a = 10;
 //int& ra = a; // 該語句編譯時會出錯,a為常量

編譯出錯的原因 :
原來a不能被修改,類型為 const int,但ra的類型為int,使權限提升了

double d = 12.34;
 //int& rd = d; // 該語句編譯時會出錯,類型不同
 const int& rd = d;

編譯出錯的原因 :
在進行類型轉換時,會產生一個臨時變量,rd是臨時變量的別名,但因為臨時變量具有常性,因此 int& rd = d;是錯誤的

引用做參數

void Swap(int& left,int& right)
{
	int tmp = left;
	left = right;
	right = tmp;
}

引用做返回值

// 正確寫法
int& Count()
{
 	static int n = 0;
 	n++;
 	// ...
 	return n;
}

下面代碼的運行結果是什么?

// 錯誤示范
int& Add(int a, int b)
{
 	int c = a + b;
 	return c; 
}
int main()
{
 	int& ret = Add(1, 2);
 	Add(3, 4);
 	cout << "Add(1, 2) is :"<< ret <<endl;
 	// Add(1,2) is : 7
 	return 0; 
}

錯誤在于返回了局部變量的引用,Add函數返回的是局部變量c的引用,c出了作用域以后,c的空間就被操作系統(tǒng)回收了

引用和指針的區(qū)別
(1).引用必須初始化,指針可以不初始化
(2).引用初始化一個實體之后,不能再引用另外一個實體,指針指向一個實體后,可以再指向另外一個實體
(3).不存在空引用,存在空指針
(4).在語法上,引用是給一個變量取別名,指針取的變量的地址
(5).在sizeof中含義不同:引用結果為引用類型的大小,但指針始終是地址空間所占字節(jié)個數(32位平臺下占4個字節(jié))
(6).引用自加即引用的實體增加1,指針自加即指針向后偏移一個類型的大小
(7).有多級指針,但是沒有多級引用
(8). 訪問實體方式不同,指針需要顯式解引用,引用編譯器自己處理
(9). 引用比指針使用起來相對更安全

七.內聯(lián)函數

內聯(lián)函數概念 : 以inline修飾的函數叫做內聯(lián)函數,編譯時C++編譯器會在調用內聯(lián)函數的地方展開,沒有函數壓棧的開銷,內聯(lián)函數提升程序運行的效率。

C語言為了小函數避免棧幀的消耗,提供了宏函數的支持,那為什么C++還要引入內聯(lián)函數呢?

(1).宏函數在預處理階段會被替換掉,不能進入函數內部進行調試
(2).宏函數不支持類型檢查,語法復雜,容易出錯

inline int Add(int x,int y)
{
	return x + y;
}
int main()
{
	int ret = Add(1,2);
	cout<<ret<<endl;
}

八.auto關鍵字(C++11)

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

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

int main()
{
	int a = 10;
	auto b = a;
	// 類型聲明成auto,可以根據a的類型自動推導出b的類型
}

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

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

int main()
{
 	int x = 10;
 	auto a = &x;  // 推導出 a 的類型為 int*
 	auto* b = &x; // 推導出 b 的類型為 int*
 	auto& c = x;  // 推導出 c 的類型為 int
 	cout << typeid(a).name() << endl;  // int*
 	cout << typeid(b).name() << endl;  // int*
 	cout << typeid(c).name() << endl;  // int
 	*a = 20;
 	*b = 30;
 	 c = 40;
 	 return 0;
}

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

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

(3). auto不能作為函數的參數

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

(4). auto不能直接用來聲明數組

void TestAuto()
{
 	int a[] = {1,2,3};
 	auto b[] = {4,5,6}; // 錯誤
}

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

九.范圍for

C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號由冒號“ :”分為兩部分:第一部分是范圍內用于迭代的變量,第二部分則表示被迭代的范圍。

void TestFor()
{
 	int array[] = { 1, 2, 3, 4, 5 };
 	for(auto& e : array)
 		 e *= 2;
 
 	for(auto e : array)
		 cout << e << " ";
	// 2, 4, 6, 8, 10
}

以上就是C++入門(命名空間,缺省參數,函數重載,引用,內聯(lián)函數,auto,范圍for)的詳細內容,更多關于c++ 入門基礎知識的資料請關注腳本之家其它相關文章!

相關文章

  • Opencv實現最小外接矩形和圓

    Opencv實現最小外接矩形和圓

    這篇文章主要為大家詳細介紹了Opencv實現最小外接矩形和圓,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • C語言實現電子時鐘程序

    C語言實現電子時鐘程序

    這篇文章主要為大家詳細介紹了C語言實現電子時鐘程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • C語言實現單位車輛調度管理

    C語言實現單位車輛調度管理

    這篇文章主要為大家詳細介紹了C語言實現單位車輛調度管理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言數組按協(xié)議存儲與按協(xié)議解析數據的實現

    C語言數組按協(xié)議存儲與按協(xié)議解析數據的實現

    今天小編就為大家分享一篇關于C語言數組按協(xié)議存儲與按協(xié)議解析數據的實現,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • MFC串口通信發(fā)送16進制數據的方法

    MFC串口通信發(fā)送16進制數據的方法

    這篇文章主要為大家詳細介紹了MFC串口通信發(fā)送16進制數據,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C++調用Python基礎功能實例詳解

    C++調用Python基礎功能實例詳解

    c++調用Python首先安裝Python,本文以win7為例,給大家詳細介紹C++調用Python基礎功能,需要的朋友參考下吧
    2017-04-04
  • C語言之沒有main函數的helloworld示例

    C語言之沒有main函數的helloworld示例

    這篇文章主要介紹了C語言之沒有main函數的helloworld示例,本文分解了帶main函數的helloworld示例,從而分析出不需要main函數的helloworld示例,需要的朋友可以參考下
    2015-03-03
  • C語言讀取文件流的相關函數用法簡介

    C語言讀取文件流的相關函數用法簡介

    這篇文章主要介紹了C語言讀取文件流的相關函數用法簡介,包括fread()函數和feof()函數的使用,需要的朋友可以參考下
    2015-08-08
  • C++中string使用+號與int拼接方式

    C++中string使用+號與int拼接方式

    這篇文章主要介紹了C++中string使用+號與int拼接方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C語言學習基礎知識分享

    C語言學習基礎知識分享

    這篇文章主要介紹了C語言學習基礎知識分享的相關資料,需要的朋友可以參考下
    2023-01-01

最新評論

兰考县| 安平县| 辽源市| 鲜城| 济南市| 余江县| 新化县| 榆社县| 壤塘县| 巴马| 井冈山市| 定州市| 盐津县| 荔波县| 鲁山县| 湖口县| 长治县| 贡嘎县| 六盘水市| 华阴市| 临沧市| 定安县| 福鼎市| 饶河县| 北安市| 岳普湖县| 休宁县| 敖汉旗| 观塘区| 乌鲁木齐市| 大英县| 会理县| 阜城县| 京山县| 于都县| 聂荣县| 河间市| 拉萨市| 新田县| 吴忠市| 光山县|