C語言是面向過程的,而C++是面向?qū)ο蟮?/p>
C和C++的區(qū)別:
C是一個結(jié)構(gòu)化語言碘箍,它的重點在于算法和數(shù)據(jù)結(jié)構(gòu)。C程序的設(shè)計首要考慮的是如何通過一個過程,對輸入(或環(huán)境條件)進行運算處理得到輸出(或?qū)崿F(xiàn)過程(事務(wù))控制)庆捺。
C++,首要考慮的是如何構(gòu)造一個對象模型屁魏,讓這個模型能夠契合與之對應的問題域滔以,這樣就可以通過獲取對象的狀態(tài)信息得到輸出或?qū)崿F(xiàn)過程(事務(wù))控制。 所以C與C++的最大區(qū)別在于它們的用于解決問題的思想方法不一樣氓拼。之所以說C++比C更先進你画,是因為“ 設(shè)計這個概念已經(jīng)被融入到C++之中 ”抵碟。
C與C++的最大區(qū)別:在于它們的用于解決問題的思想方法不一樣。之所以說C++比C更先進坏匪,是因為“ 設(shè)計這個概念已經(jīng)被融入到C++之中 ”拟逮,而就語言本身而言,在C中更多的是算法的概念适滓。那么是不是C就不重要了敦迄,錯!算法是程序設(shè)計的基礎(chǔ)粒竖,好的設(shè)計如果沒有好的算法颅崩,一樣不行。而且蕊苗,“C加上好的設(shè)計”也能寫出非常好的東西沿后。
很多小伙伴都老是會碰到疑問,其實還是基礎(chǔ)沒打扎實朽砰,這些題如果你不看答案你能知道多少呢尖滚?如果還有很多不知道就證明基礎(chǔ)沒打扎實,如果你還在入門糾結(jié)瞧柔,如果你還在苦惱怎么入門漆弄!小編推薦一個學C語言/C++的學習裙【 六九九,四七零造锅,五九六 】撼唾,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學習哥蔚!裙內(nèi)有開發(fā)工具倒谷,很多干貨和技術(shù)資料分享!
函數(shù)參數(shù)的按值傳遞機制:
給函數(shù)傳遞參數(shù)時糙箍,參數(shù)值不會直接傳遞給函數(shù)渤愁,而是先生成參數(shù)值的一份副本,存儲在內(nèi)存中的棧上深夯,再把這個副本用于函數(shù)語句里抖格,而不是使用初始值,我們來用一個程序更清楚的說明這一點:
#include
void swap(int a,int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void main()
{
int a = 1;
int b = 2;
printf("a=%d,b=%d ",a,b);
swap(a,b);
printf("a=%d,b=%d ",a,b);
}
程序運行結(jié)果:
a=1,b=2
a=1,b=2
可能有人會不解咕晋,為什么我們在調(diào)用了swap(a,b)函數(shù)后雹拄,a、b的值并沒有發(fā)生交換捡需,這就是我們說的按值傳遞機制办桨,我們在把a、b作為參數(shù)傳遞給swap函數(shù)時站辉,這里其實是生成了a呢撞、b的副本再供swap函數(shù)使用的损姜,所以就算是a、b的副本發(fā)生了交換殊霞,a摧阅、b本身也還是原來的值。我們在這里要達到我們想要的功能绷蹲,就要使用指針棒卷,修改如下:
#include
void swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void main()
{
int a = 1;
int b = 2;
printf("a=%d,b=%d ",a,b);
swap(&a,&b);
printf("a=%d,b=%d ",a,b);
}
我們只是把函數(shù)swap里的所有a、b的部分分別換成了*a祝钢、*b比规,同時我們傳遞了&a和&b給swap函數(shù),這樣就能得到預期結(jié)果了拦英。我們來看看我們到底做了何種修改蜒什,首先我們把a、b的地址(&a和&b)傳遞給swap函數(shù)疤估,盡管這里還是會拷貝a灾常、b地址的副本(我們假定是指針*pa和*pb)傳遞給swap,但是這兩個副本pa和pb仍然是指向a铃拇、b的指針钞瀑,它們和&a、&b是不同的指針慷荔,但是卻指向了同一個地址雕什,所以當我們使用“*指針”這種形式時就可以改變該地址內(nèi)存放的值了。
可能有人要問C語言為什么要采用這種方式來傳遞參數(shù)呢显晶,直接使用原來的實參不好嗎监徘?你想一個問題,假設(shè)C不使用按值傳遞吧碾,就拿上面的swap函數(shù)舉例,那么當我們使用swap(1,2)這樣調(diào)用函數(shù)時會發(fā)生什么墓卦?我們難道要把常量1和2進行直接交換嗎倦春,讓1=2,2=1?這絕對不行落剪。提一下在Pascal編程語言中睁本,為了不給調(diào)用者的變量帶來影響,在定義函數(shù)的時候忠怖,會特別地指定參數(shù)為變量參數(shù)呢堰,如果試圖給參數(shù)為變量的函數(shù)傳遞常量,編譯器就會報錯凡泣。但是C語言講究的是簡單實用枉疼,所以它不可能背負常量修改這樣的危險皮假,也沒有采用Pascal那樣麻煩的方式來在語法上做文章,所以就使用了這種按值傳遞的方式來傳遞參數(shù)骂维。
函數(shù)聲明:
可能有的人會碰到這種情況惹资,當他把上面的代碼寫成
void main(){...}
void swap{...}
這種順序時程序就會報錯,這時候就是編譯器沒有正確識別swap函數(shù)導致的航闺,這就涉及到函數(shù)聲明了褪测。函數(shù)聲明是一個定義函數(shù)基本特性的語句,它定義了函數(shù)的名字潦刃、返回值類型和每個參數(shù)的類型侮措。事實上,可以將它編寫為與函數(shù)頭一模一樣乖杠,只是要在尾部加一個分號表示語句結(jié)束分扎。函數(shù)聲明也叫作函數(shù)原型,因為它提供了函數(shù)的所有外部規(guī)范滑黔。函數(shù)原型能使編譯器在使用這個函數(shù)的地方創(chuàng)建適當?shù)闹噶畎拾瑱z查是否正確地使用它。在程序中包含頭文件時略荡,這個頭文件就會在程序中為庫函數(shù)添加函數(shù)原型庵佣。例如,頭文件中就含有printf和scanf的函數(shù)原型汛兜,這個文件我們在C-Free 5mingwinclude目錄下就可以找到巴粪。所以,如果你想把swap的定義放在main函數(shù)后面粥谬,可以像下面這樣使用函數(shù)聲明:
#include
void swap(int *,int *);
//也可以寫成void swap(int *a,int *b);
void main()
{
int a = 1;
int b = 2;
printf("a=%d,b=%d ",a,b);
swap(&a,&b);
printf("a=%d,b=%d ",a,b);
}
void swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
函數(shù)指針:
可能有人不理解我為什么要把函數(shù)和數(shù)組放在一章講肛根,主要是因為它們都和指針有莫大的關(guān)系,前面我們說了數(shù)組名就是一個特殊的指針漏策,只是要注意sizeof(數(shù)組名)和&數(shù)組名兩種特殊情況派哲。其實函數(shù)名也是一種特殊的指針,我們的程序被編譯器翻譯成匯編語言時掺喻,函數(shù)會被翻譯成為一段相對獨立的匯編代碼芭届,函數(shù)名就是該段代碼的首地址,每個函數(shù)的最后都會有一個ret或retn匯編指令感耙,其實它就對應我們函數(shù)的return語句褂乍,不要以為有的函數(shù)沒有return語句,其實只是因為該函數(shù)是返回空(void)寫做return;所以就把return省略掉了即硼。稍微修改下上面的程序:
小編推薦一個學C語言/C++的學習裙【 六九九逃片,四七零,五九六 】只酥,無論你是大牛還是小白褥实,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學習呀狼!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享性锭!
赠潦,當我們使用void (*p)(int*,int*) = swap;這一句時其實就是定義了一個函數(shù)指針p,我們讓指針p的值賦值為swap函數(shù)名(在我們這里是地址0x00401014)草冈,然后我們可以發(fā)現(xiàn)我們可以使用p(&a,&b)這樣的方式來調(diào)用函數(shù)了她奥,就和使用swap(a,b)完全一樣,怎棱。當然我們還可以在最后再加上兩句:
可以看到我們居然可以使用((void(*)(int*,int*))0x00401014)(&a,&b);這樣的方式來通過地址0x00401014調(diào)用函數(shù)哩俭,(void(*)(int*,int*)其實就是定義了一個函數(shù)指針,(*)表示它是一個函數(shù)拳恋,void表示該函數(shù)返回值為空凡资,(int*,int*)表示函數(shù)有兩個int*類型的參數(shù),然后我們使用它把地址0x00401014進行強制類型轉(zhuǎn)換谬运,這樣我們的地址0x00401014就會被當成一個函數(shù)來使用了隙赁,要特別注意里面的括號,不要省略了梆暖,不然會報錯的伞访。
前面說了數(shù)組名作為指針有兩種特殊的情況,那么函數(shù)名是不是也有sizeof(函數(shù)名)和&函數(shù)名這兩種特殊情況呢轰驳,多說無益厚掷,當你不確定一件事時,就用代碼把它打印出來:
這是我在C-Free5上面的打印結(jié)果级解,在dev-c++也差不多冒黑,但是在vc6上面就會報錯,原因就是sizeof后面跟函數(shù)名會被vc6默認是違法操作勤哗,因為函數(shù)的代碼數(shù)量是不確定的抡爹,所以函數(shù)的大小也不能確定,盡量不要出現(xiàn)sizeof(add)這樣的操作芒划,C-Free5和dev-c++則采用了相對比較溫和的方式來處理豁延;而"函數(shù)名=&函數(shù)名"這條確是成立的。
下面我們再來看看數(shù)組作為函數(shù)參數(shù)的情況下腊状,我們使用sizeof會發(fā)生什么變化:
小編推薦一個學C語言/C++的學習裙【 六九九,四七零苔可,五九六 】缴挖,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學習焚辅!裙內(nèi)有開發(fā)工具映屋,很多干貨和技術(shù)資料分享苟鸯!
可以看到我們在main函數(shù)里調(diào)用sizeof(a)=40,而在作為參數(shù)傳遞給array函數(shù)后棚点,再次使用sizeof(a)時大小就只剩下4了早处,這是為什么呢,因為數(shù)組名是一個特殊的指針瘫析,當它作為參數(shù)傳遞給函數(shù)時砌梆,這時候就會拷貝a的副本傳遞給函數(shù),這個副本就是一個大小為4字節(jié)的指針贬循,所以我們在函數(shù)調(diào)用里得到參數(shù)數(shù)組a的大小為4咸包。如果我們要得到真實的數(shù)組大小,我們通常會采用額外的處理方式杖虾,一種就是我們前面在寫壓縮和解壓函數(shù)時用到的烂瘫,我們把數(shù)組名和數(shù)組大小都作為參數(shù)傳遞給函數(shù);另一種是我們在數(shù)組的即為加上一個特殊的符號表示數(shù)組結(jié)束奇适,比如字符串的結(jié)尾就是一個''坟比,我們只要使用循環(huán)讀取元素一直到結(jié)束符就可以得到數(shù)組大小,當然也可以用其它的符號表示結(jié)束嚷往,比如-1葛账,這都是你根據(jù)實際情況自己定義的。
今天就到這里间影,欲知后事如何且聽下回分解(手動滑稽)~
這些是C/C++能做的
服務(wù)器開發(fā)工程師注竿、人工智能、云計算工程師魂贬、信息安全(黑客反黑客)巩割、大數(shù)據(jù) 、數(shù)據(jù)平臺付燥、嵌入式工程師宣谈、流媒體服務(wù)器、數(shù)據(jù)控解键科、圖像處理闻丑、音頻視頻開發(fā)工程師、游戲服務(wù)器勋颖、分布式系統(tǒng)嗦嗡、游戲輔助等