一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - C和C++的區(qū)別詳解

C和C++的區(qū)別詳解

2022-01-20 14:39Sauron7i C/C++

這篇文章主要介紹了C和C++之間的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

通過程序來介紹

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

1.iostream文件

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

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

2.頭文件名的區(qū)別

C語言

C語言的傳統(tǒng)是頭文件使用擴展名 h,將其作為一種通過名稱標(biāo)識文件類型的簡單方式。例如 math.h支持一些數(shù)學(xué)函數(shù)。

C++

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

3.名稱空間namespace

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

using namespace std;

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

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

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

示例

封裝性

示例:

首先定義一個頭文件

C和C++的區(qū)別詳解

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

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

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

C和C++的區(qū)別詳解

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;
}

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

運行結(jié)果:

C和C++的區(qū)別詳解

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

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

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

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

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

圖示

C和C++的區(qū)別詳解

 

指針和數(shù)組名的區(qū)別

程序示例:

#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和一個數(shù)組arr。

運行結(jié)果都是地址

C和C++的區(qū)別詳解

反匯編查看區(qū)別

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

區(qū)別

C和C++的區(qū)別詳解

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

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

結(jié)論

指針是變量;

數(shù)組名是一個地址――常量。

解引用

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

可以來探索原理

程序示例

#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的內(nèi)存中取四個字節(jié),即變量a的地址放入寄存器,再將20給到寄存器所存的的四字節(jié)中。完成對變量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里取出四字節(jié)放入寄存器

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

3.的內(nèi)容放入到變量b的四字節(jié)中。

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

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

示例:

#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地址里取出四字節(jié)放到寄存器,再通過寄存器給入b。

結(jié)論

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

 

const的區(qū)別

C語言中為常變量

示例:

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

兩次賦值的區(qū)別:

	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的四字節(jié)中;

用const修飾的a賦值時,還是需要從a里取出四字節(jié)再賦給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和C++的區(qū)別詳解

C++中的const

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

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

示例:

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修飾的變量和常量性質(zhì)一樣,都是在編譯期將常量值替換到常量的使用點。

另外

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

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

聲明時const位置不同的區(qū)別

示例:

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與離他最近的類型結(jié)合,是該變量的類型,除了最近的類型,剩下的就是const修飾的內(nèi)容。

const修飾的內(nèi)容是不可作為左值。

根據(jù)上面的原理,來判斷以下內(nèi)容:

	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所修飾的內(nèi)容,所以它們兩個所修飾的內(nèi)容為 *p2 、*p3。

對于int* const p4

const修飾的類型為int*,那修飾的內(nèi)容就是p4。

下面的四個q同理。

可以推出錯誤的是:

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

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

p4為const修飾的內(nèi)容,不能被改變。

const修飾形參

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

程序示例:

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

編譯器并沒有報錯,但編譯無法通過,原因如下

C和C++的區(qū)別詳解

結(jié)論:如果const修飾的內(nèi)容不包括指針,則不參與類型問題。

 

引用變量

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

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;
}

運行示例:

C和C++的區(qū)別詳解

通過A可以改變a的值,這就是引用。A相當(dāng)于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

可以看出:引用的實現(xiàn)居然和指針是一樣的。

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

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

常問問題

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

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

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

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

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

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

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

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

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

示例:

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

 

動態(tài)申請空間的區(qū)別

C語言

使用malloc和free

示例:

int main(void)
{
	//申請一維數(shù)組與釋放
	int* arr = (int*)malloc(sizeof(int) * 10);
	if (arr == NULL)
		return -1;
	free(arr);
	//申請二維數(shù)組與釋放
	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類型數(shù)組
	int* arr = new int[10];
	arr[0] = 10;
	delete[]arr;
	//申請二維數(shù)組
	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后面跟的類型就表示申請的大小。

 

面向過程和面向?qū)ο?/h2>

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;
}

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

但如果改變flag,也會改變其他地方調(diào)用的打印函數(shù)的結(jié)果。

所以C語言沒有封裝性。

C++

面向?qū)ο笳Z言

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;
}

運行結(jié)果:

C和C++的區(qū)別詳解

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

C++作為半面向?qū)ο笳Z言,具有封裝性,若想改變示例中想打印的值,只會影響到這個模塊。

 

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/m0_56257585/article/details/120623579

延伸 · 閱讀

精彩推薦
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進行了詳細(xì)的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++C語言實現(xiàn)電腦關(guān)機程序

    C語言實現(xiàn)電腦關(guān)機程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)電腦關(guān)機程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
主站蜘蛛池模板: 黑人女性猛交xxxxxⅹxx | 教室眠催白丝美女校花 | 亚洲热在线视频 | 国产高清一区二区三区免费视频 | 国产色司机在线视频免费观看 | 99国产成人精品2021 | 国产第一福利影院 | 欧美精品一区二区三区免费 | 精品午夜中文字幕熟女人妻在线 | 国产传媒在线播放 | 亚洲 欧美 国产 日韩 字幕 | 久久囯产精品777蜜桃传媒 | 日本在线看| 国产精品午夜国产小视频 | 四虎精品免费视频 | 欧美日本道免费一区二区三区 | 国产精品久久久久久久久久久久久久 | 香蕉在线精品亚洲第一区 | 91小视频在线观看免费版高清 | 青青草99热这里都是精品 | 日本一区二区三区久久精品 | 91专区 | 成功精品影院 | 免费黄色片在线观看 | 日韩制服丝袜在线观看 | 教师波多野结衣在线播放 | 成人aaaa| 99av涩导航 | 337p大尺度啪啪人体午夜2020 | 久久久伊人影院 | 久久久亚洲国产精品主播 | 成人网18免费网 | 天天干天天色综合网 | 日韩毛片大全免费高清 | 国产在线xvideos | 亚洲国产日韩欧美mv | 1024人成网色www | 日本高清中文字幕一区二区三区 | 欧美精品一区二区三区久久 | 99精品网站 | 天堂网www中文天堂在线 |