91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C和C++的區別有哪些

發布時間:2021-10-09 13:44:53 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

本篇內容介紹了“C和C++的區別有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    通過程序來介紹

    //c++ program
    #include<iostream>
    using namespace std;
    int main(void)
    {
    	cout << "This is a c++ program." << endl;
    	return 0;
    }

    1.iostream文件

    iostream中的io指的是輸入(進入程序的信息)和輸出(從程序中發送出去的信息)。

    并且c++的輸入、輸出方案涉及iostream文件中的多個定義。比如用來輸出信息的cout就在其中。

    2.頭文件名的區別

    C語言

    C語言的傳統是頭文件使用擴展名 h,將其作為一種通過名稱標識文件類型的簡單方式。例如 math.h支持一些數學函數。

    C++

    C++頭文件沒有擴展名。
    有些C頭文件被轉換成C++頭文件,這些文件被重新命名,去掉了擴展名h,并在文件名稱前面加上前綴c(表示來自C語言)

    3.名稱空間namespace

    如果使用的是iostream,而不是iostream.h,則應使用名稱空間編譯指令來使iostream中的定義對程序可用,即

    using namespace std;

    有了這句using編譯指令,才能使用cout、cin等,或者用第二種方式:

    using std::cout;
    using std::cin;
    using std::endl;

    名稱空間是C++的特性之一,簡單理解為:可以將自己的產品封裝起來。

    示例

    封裝性

    示例:

    首先定義一個頭文件

    在里面寫上我們自己編的東西:

    #pragma once
    namespace AA
    {
    	typedef int INT;
    	typename char CHAR;
    };

    然后在cpp文件中引入該頭文件,但我們卻無法使用之前寫好的東西。

    INT a會報錯,因為我們只引入了頭文件,沒有使用里面的名稱空間。

    正確做法:

    //c++ program
    #include<iostream>
    #include"AA.h"
    using namespace std;
    using namespace AA;
    //using AA::INT;
    int main(void)
    {
    	INT a = 10;
    	cout << a << endl;
    	return 0;
    }

    需要第六行的該名稱空間才可以使用其中的產品。或者可以用第七行這種寫法來確定自己只需要哪個產品。

    4.使用cout進行C++的輸出

    上面的程序有這條C++語句:

    	cout << "This is a C++ program." << endl;

    <<符號表示該語句將把這個字符串發送給cout,該符號指出了信息流動路徑。 cout是一個預定義的對象。

    從概念上看,輸出是一個流,即從程序流出的一系列字符。cout對象表示這種流,其屬性是在iostream文件中定義的。
    cout的對象屬性包括一個插入運算符(<<),它可以將其右側的信息插入到流中。

    指針和數組名的區別

    程序示例:

    #include<iostream>
    using namespace std;
    int main(void)
    {
    	int a = 10;
    	int* p = &a;
    	int arr[] = { 0,1,2,3,4 };
    	cout << p << endl;
    	cout << arr << endl;
    	return 0;
    }

    這里定義了一個指針p和一個數組arr。

    運行結果都是地址

    反匯編查看區別

    cout << p << endl;

    	cout << p << endl;
    008F52AF  mov         esi,esp  
    008F52B1  push        offset std::endl<char,std::char_traits<char> > (08F103Ch)  
    008F52B6  mov         edi,esp  
    008F52B8  mov         eax,dword ptr [p]  
    008F52BB  push        eax

    cout << arr << endl;

    	cout << arr << endl;
    008F52DE  mov         esi,esp  
    008F52E0  push        offset std::endl<char,std::char_traits<char> > (08F103Ch)  
    008F52E5  mov         edi,esp  
    008F52E7  lea         eax,[arr]  
    008F52EA  push        eax

    區別

    在輸出指針時,需要先從p里面取出四字節,再放到寄存器里push;

    在輸出arr時,直接把arr放到寄存器里再push。

    結論

    指針是變量;

    數組名是一個地址——常量。

    解引用

    在C語言中學到,對指針解引用后得到的值就是它寸的地址對應的變量值。

    可以來探索原理

    程序示例

    #include<iostream>
    using namespace std;
    int main(void)
    {
    	int a = 10;
    	int* p = &a;
    	*p = 20;
    	return 0;
    }

    反匯編代碼:

    	int a = 10;
    000D18FF  mov         dword ptr [a],0Ah  
    	int* p = &a;
    000D1906  lea         eax,[a]  
    000D1909  mov         dword ptr [p],eax  
    	*p = 20;
    000D190C  mov         eax,dword ptr [p]  
    000D190F  mov         dword ptr [eax],14h

    對于*p = 20

    先從p的內存中取四個字節,即變量a的地址放入寄存器,再將20給到寄存器所存的的四字節中。完成對變量a的改變。

    所以解引用的意思就是從地址中把值取出來,這里是去p的地址里取出所存的變量a的地址。

    程序示例2:

    #include<iostream>
    using namespace std;
    int main(void)
    {
    	int a = 10, b = 20;
    	int* p = &a;
    	b = *p;
    	return 0;
    }

    反匯編代碼:

    	int a = 10, b = 20;
    000818FF  mov         dword ptr [a],0Ah  
    00081906  mov         dword ptr [b],14h  
    	int* p = &a;
    0008190D  lea         eax,[a]  
    00081910  mov         dword ptr [p],eax  
    	b = *p;
    00081913  mov         eax,dword ptr [p]  
    00081916  mov         ecx,dword ptr [eax]  
    00081918  mov         dword ptr [b],ecx

    對于 b = *p;

    1.先去p里取出四字節放入寄存器

    2.再從寄存器eax取出四字節放入寄存器ecx再把ecx

    3.的內容放入到變量b的四字節中。

    也可以看出:解引用這一步其實是去地址里取值的。

    這樣也可以得出:用一個變量賦值給另一個變量,其實也是在解引用

    示例:

    #include<iostream>
    using namespace std;
    int main(void)
    {
    	int a = 10;
    	int b;
    	b = a;
    	return 0;
    }

    反匯編:

    	int a = 10;
    002D18F5  mov         dword ptr [a],0Ah  
    	int b;
    	b = a;
    002D18FC  mov         eax,dword ptr [a]  
    002D18FF  mov         dword ptr [b],eax

    對于 b = a;

    也是從a地址里取出四字節放到寄存器,再通過寄存器給入b。

    結論

    解引用:到地址里去取值。

    const的區別

    C語言中為常變量

    示例:

    //const
    #include<stdio.h>
    int main(void)
    {
    	const int a = 10;
    	int b = 100; //常量賦值
    	b = a; //常變量賦值
    	return 0;
    }

    兩次賦值的區別:

    	const int a = 10;
    00311825  mov         dword ptr [a],0Ah  
    	int b = 100;
    0031182C  mov         dword ptr [b],64h  
    	b = a;
    00311833  mov         eax,dword ptr [a]  
    00311836  mov         dword ptr [b],eax

    常量賦值時,是直接把值給到b的四字節中;

    用const修飾的a賦值時,還是需要從a里取出四字節再賦給b。

    所以C語言中const修飾的變量叫做常變量——不能作為左值。

    甚至可以用指針改變它的值:

    #include<stdio.h>
    int main(void)
    {
    	const int a = 10;
    	int b = 100;
    	b = a;
    	int* p = &a;
    	*p = 20;
    	return 0;
    }

    a的變化:const修飾的變量a居然能被改變

    C++中的const

    在C++中,const修飾的變量就是常量,和常量性質一樣:

    在編譯期間直接將常量的值替換到常量的使用點。

    示例:

    int main(void)
    {
    	const int a = 10;
    	int b, c;
    	b = 16;
    	c = a;
    	return 0;
    }

    反匯編代碼:

    	const int a = 10;
    00B917F5  mov         dword ptr [a],0Ah  
    	int b, c;
    	b = 16;
    00B917FC  mov         dword ptr [b],10h  
    	c = a;
    00B91803  mov         dword ptr [c],0Ah

    可以看出,對b賦值常量是直接賦值;

    對c賦值const修飾的變量a,同樣是用常量賦值的。所以:

    在C++中, const修飾的變量和常量性質一樣,都是在編譯期將常量值替換到常量的使用點。

    另外

    1.而且const修飾的變量必須初始化,同樣因為編譯期間就會替換為常量,不初始化,后面也沒有機會再對其賦值。

    2.如果用變量對const修飾的變量賦值,則會使其退化成常變量。

    聲明時const位置不同的區別

    示例:

    const可在不同位置修飾變量

    int main(void)
    {
    	int a = 10;
    	int* p1 = &a;
    	const int* p2 = &a;
    	int const* p3 = &a;
    	int* const p4 = &a;
    	int* q1 = &a;
    	const int* q2 = &a;
    	int const* q3 = &a;
    	int* const q4 = &a;
    	return 0;
    }

    要注意的是:

    const與離他最近的類型結合,是該變量的類型,除了最近的類型,剩下的就是const修飾的內容。

    const修飾的內容是不可作為左值。

    根據上面的原理,來判斷以下內容:

    	p1 = q1;
    	p1 = q2;
    	p1 = q3;
    	p1 = q4;
    	p2 = q1;
    	p2 = q2;
    	p2 = q3;
    	p2 = q4;
    	p3 = q1;
    	p3 = q2;
    	p3 = q3;
    	p3 = q4;
    	p4 = q1;
    	p4 = q2;
    	p4 = q3;
    	p4 = q4;

    p1是普通指針。

    對于

    const int* p2和int const* p3

    const修飾的類型是離他最近的類型,即int,剩下的為const所修飾的內容,所以它們兩個所修飾的內容為 *p2 、*p3。

    對于int* const p4

    const修飾的類型為int*,那修飾的內容就是p4。

    下面的四個q同理。

    可以推出錯誤的是:

    	p1 = q2;
    	p1 = q3;
    	p4 = q1;
    	p4 = q2;
    	p4 = q3;
    	p4 = q4;

    因為 *q2 和 *q3不能改變,所以把 q2/q3賦值給普通指針時,會造成普通指針來改變其中內容的后果,即 泄露常量地址給非常量指針 ,所以不能這樣賦值。

    p4為const修飾的內容,不能被改變。

    const修飾形參

    這里主要說能否形成函數重載的問題

    程序示例:

    int fun(int a)
    {
    	return a;
    }
    int fun(const int a)
    {
    	return a;
    }

    編譯器并沒有報錯,但編譯無法通過。

    結論:如果const修飾的內容不包括指針,則不參與類型問題。

    引用變量

    之前C語言學到,&符號用來指示變量的地址。

    C++給該符號賦予了另一個含義,將其用來聲明引用。

    示例,若我想用 A作為變量 a的別名,可以這樣用:

    #include<iostream>
    using namespace std;
    int main(void)
    {
    	int a = 10;
    	int& A = a;
    	A = 20;
    	cout << a << endl;
    	cout << A << endl;
    	return 0;
    }

    運行示例:

    通過A可以改變a的值,這就是引用。A相當于a的別名,就和魯迅和周樹人一樣。。。

    引用的原理

    示例:

    int a = 10;
    	int& A = a;
    	int* p = &a;

    反匯編代碼:

    	int& A = a;
    00ED5326  lea         eax,[a]  
    00ED5329  mov         dword ptr [A],eax  
    	int* p = &a;
    00ED532C  lea         eax,[a]  
    00ED532F  mov         dword ptr [p],eax

    可以看出:引用的實現居然和指針是一樣的。

    所以引用的底層是一個指針。

    結論:在使用到引用的地方,編譯期會自動替換成底層指針的解引用。

    常問問題

    1.引用為什么必須初始化?

    2.引用為什么一經過初始化,就無法改變引用的方向?

    答:因為只有在初始化的時候能給它賦值,其他使用到它的地方都替換成了底層指針

    無法改變底層指針的指向,所以無法改變引用的方向。

    3.不能將const限定的變量賦給普通引用變量:

    原因是將常量的地址賦給了普通指針。

    	const int a = 10;
    	int& b = a; //錯誤

    4.當引用一個不可以取地址的量的時候,使用常引用。

    會生成一個臨時量,然后常引用臨時量,臨時量都有常屬性。

    示例:

    int& a = 10; //錯誤
    const int& a = 10; //正確

    動態申請空間的區別

    C語言

    使用malloc和free

    示例:

    int main(void)
    {
    	//申請一維數組與釋放
    	int* arr = (int*)malloc(sizeof(int) * 10);
    	if (arr == NULL)
    		return -1;
    	free(arr);
    	//申請二維數組與釋放
    	int** brr = (int**)malloc(sizeof(int*) * 10);
    	if (brr == NULL)
    		return -1;
    	for (int i = 0; i < 10; ++i)
    	{
    		free(brr[i]);
    	}
    	return 0;
    }

    C++

    int main(void)
    {
    	//申請int類型變量
    	int* p = new int;
    	*p = 10;
    	delete p;
    	//申請int類型數組
    	int* arr = new int[10];
    	arr[0] = 10;
    	delete[]arr;
    	//申請二維數組
    	int** brr = new int* [5];
    	for (int i = 0; i < 5; ++i)
    	{
    		brr[i] = new int[10];
    	}
    	for (int i = 0; i < 5; ++i)
    	{
    		delete[]brr[i];
    	}
    	return 0;
    }

    new后面跟的類型就表示申請的大小。

    面向過程和面向對象

    C語言

    面向過程語言

    示例

    void echo()
    {
    	if (flag == 0)
    	{
    		printf("printf screen\n");
    	}
    	else if (flag == 1)
    	{
    		printf("printf file\n");
    	}
    }
    void Set_flag_file()
    {
    	flag = 1;
    }
    void Set_flag_screen()
    {
    	flag = 0;
    }

    對于這個打印函數,可以通過改變flag的值來控制其打印的結果。

    但如果改變flag,也會改變其他地方調用的打印函數的結果。

    所以C語言沒有封裝性。

    C++

    面向對象語言

    class Note
    {
    public:
    	Note()
    	{
    		flag = 0;
    	}
    	void echo()
    	{
    		if (flag == 0)
    		{
    			printf("printf screen\n");
    		}
    		else if (flag == 1)
    		{
    			printf("printf file\n");
    		}
    	}
    	void Set_flag_file()
    	{
    		flag = 1;
    	}
    	void Set_flag_screen()
    	{
    		flag = 0;
    	}
    private:
    	int flag;
    };

    使用示例:

    int main(void)
    {
    	Note n;
    	n.echo();
    	n.Set_flag_file();
    	n.echo();
    	return 0;
    }

    C語言作為面向過程語言,如果示例中的flag做出改變,會影響全局的改變。

    C++作為半面向對象語言,具有封裝性,若想改變示例中想打印的值,只會影響到這個模塊。

    “C和C++的區別有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    驻马店市| 正镶白旗| 河源市| 丰台区| 平山县| 鄂伦春自治旗| 六枝特区| 名山县| 荔波县| 伊金霍洛旗| 玉屏| 奉化市| 元阳县| 孝义市| 彝良县| 弋阳县| 定日县| 离岛区| 睢宁县| 泰和县| 漳平市| 陆川县| 衡阳县| 东莞市| 湘乡市| 开封县| 华宁县| 连平县| 和平县| 五河县| 瑞安市| 新竹市| 剑河县| 泰和县| 海城市| 巴楚县| 陆河县| 灵丘县| 定边县| 炎陵县| 合水县|