如何寫好C/C++程序

2021-02-15 C語言三人行+

1. 基本認識

1.1. 計算機科學是"人為"的科學

計算機科學是一門新興的科學,它不同於物理、化學、天文等自然科學,它是人為創造的,它的研究對象也是人為創造的,是一門人為科學。自然科學的研究對象是客觀世界,是對未知的探索;發現自然規律,研究並利用自然規律是其根本目的。作為工程師,要在給定條件下"做得更好",就是說要根據實際情況利用現有條件充分發揮"人為"的優越性。

1.2. 軟體經常是理論落後於實踐

眾所周知,任何一門科學,都有它的理論,都應做到理論與實踐相結合,軟體理所當然應該這樣,然而,實際情況並非如此。軟體是工程,軟體理論落後於實踐的情況比比皆是。比如說,幾乎沒有人將圖靈機理論應用於實際軟體開發,計算機更多的是工程,工程是靠實踐的,工程師要始終堅持"身體力行",不要忽視寫程序,要從實際應用中去領悟軟體的真諦。

1.3. 程式語言不是目的

首先,語言是工具,程式語言同樣是工具;其次,語言不是目的,學習語言的目的就是為了更好地表達人的意思,而不是為了學習而學習。因此,對於工程師來說,不應把學習幾門程式語言作為最終目的,而是要多快好省的"使用工具"實現自己的目的,開發出優秀的軟體。

1.4. 馮·諾伊曼模型至今顛撲不破

存儲程序理論至今已有五十年歷史,馮·諾伊曼模型今後仍是計算機的基本模型,非馮模型不是不可能,但卻越來越遙遠。因此,工程師要恪守"規矩成方圓"的準則,好的工程師要會用工具,要會用"尺"來衡量,這裡的"尺"就是馮·諾伊曼機的內存,做工程時一定要用"尺"量,儘量減小誤差,編寫程序不能違背計算機的基本模型,掌握語言,要做到知其然更知其所以然,利用語言操作計算機硬體,使其有效工作,才是最終目的。


北京科泰世紀科技有限公司 版權所有 2000年--2002年


2. C/C++編程中應該特別注意的一些問題

下面通過變量、棧、堆在設計中如何使用,來討論如何寫好C/C++程序(所有例題答案附在全文後)

2.1. 全程、局部、動態變量

例1:請回答下面程序中注釋行中提出的問題
int a; // 內存中佔多少字節?分配在哪一區?
int b = 1; // b 與 a 是否相連?什麼是數據區?

void main()
{
int *p; // 分配在哪一區?
p = (int *)malloc(100); // 100 字節在哪?

}

2.2. 內存空間

不清楚內存就寫不了好程序,因此對內存的理解,對工程師來說至關重要。(對於本公司的工程師,搞不清楚內存,程序不可以check in)

下圖是內存空間的簡單邏輯結構示意圖,低(零)地址在下面,高地址在上面。

· 用戶禁區:是從零地址開始的一段空間,嚴禁用戶使用,保護系統空間;
· 程序代碼區:用來存儲當前運行程序的原始碼;
· 全程數據區:存儲全程變量,大小不受限制;
· 堆:堆是內存中可以動態分配的一片空間,用於存放程序運行過程中動態產生的變量,它是從低地址向高地址生長的,可以是鏈式結構,原則上講只要內存中有剩餘空間,堆就可以動態增長下去;
· 棧:是從高地址向低地址方向生長的存儲區,它的實現有特殊性,是後進先出的,並且它的大小是受限的,使用中具有靈活,速度快,不需要人工釋放,不存在競爭冒險問題等優點;
· 動態連接庫代碼;動態連接庫數據;每個動態連接庫又有它的堆、棧。

例2:一個關於指針入棧的問題。
void foo(char * p) {p = "世界";}
void main() {
char *p = "你好";
foo(p);
printf("%s/n", p); // 輸出什麼?
}
此題要求察看反彙編代碼,建議使用Microsoft的compiler。並且要求了解編譯後產生的所有文件,至少知道它們都是做什麼的,有什麼用途。

例3:請回答下面程序中注釋行中提出的問題。

int a[10000000]; // 是否出錯?
void main() {
int a[10000000]; // 是否出錯?
int *a = (int *) malloc(10000000); // 是否出錯?
*a = 1;
printf("%d/n", *a);
}

例4:關於堆使用的問題。

void main() {
char *p = (char *) malloc(10000000);
char *q = new char[10000000];
……
free(p); // 釋放多少內存?
delete q; // 釋放多少內存?
}
2.3. C/C++ Calling Conventions(調用習慣)
調用習慣決定編譯程序編譯源文件時,如何處理函數調用時傳遞參數的壓棧次序,由誰(調用者還是被調用者)負責彈棧等。(參見MSDN)
· __cdecl Caller pops stack (C)
· __stdcall Callee pops stack (C++)
· __fastcall ECX passes this pointer (優化C)
__cdecl 是C/C++函數調用的默認形式,由調用函數清除棧,生成的可執行代碼包含清除棧的部分,因此,對於同樣的函數,它比__stdcall形式調用的可執行代碼長。
__stdcall通常用於Win32 API函數調用,由被調用函數清除棧,採用這種方式調用,要有函數原型。
__fastcall用於優化的C,只要可能,就使用寄存器,速度快。


北京科泰世紀科技有限公司 版權所有 2000年--2002年


3. 程序運行基本概念

3.1. 主程序/子程序(EXE)

二進位文件,可以在機器上直接運行。

3.2. 程序庫/模版庫(LIB)

對於一些常用的函數,如printf、strcpy等,把他們編成庫函數,由使用者調用,減少重複勞動和出錯的可能,但編譯後代碼長度並沒有變小。

3.3. 動態連結庫(DLL)

當多個進程都需要調用某個函數時,為了節省內存空間把這些函數編成動態連接庫,由多個進程動態共享。
在選擇使用LIB還是DLL時,要考慮應用中具體情況,比如說多少進程共享一個DLL合適,效率如何等等,更具實際做出權衡。另外,DLL也有其缺點,例如不同版本DLL的兼容性不可能做到完美。


北京科泰世紀科技有限公司 版權所有 2000年--2002年


4. 面向對象程序設計

在面向對象的程序設計中,我們常涉及到的是封裝、繼承、多態、類、映射等特性。

4.1. 向誰最重要

面向對象,面向誰最為重要。這個問題可以從三個方面來考慮。首先,也是最重要的,要面向使用者,因為軟體的最終目的是滿足實際應用;其次,要面向開發者,開發者可能會使用這個對象去構造更大的對象,實現更多的功能;最後,要面向機器,對象最終必須能在馮·諾伊曼機器上運行,設計中必須考慮運行效率、軟體模型、實際誤差等問題。

4.2. 封裝 (Encapsulation)

C++中有public、protected、private關鍵字,這樣就可以叫封裝了。C++中封裝是對程式設計師的限制,沒有實現真正意義上的封裝。
下面的例子是兩種類的聲明。
class A { class B { public:
public: virtual foo();
foo(); virtual bar();
protected: virtual foobar();
bar(); }
private:
foobar();
int a;
}
class B的虛表(vtable)的物理存儲結構如下圖:

如果將上例class A中protected改為public,比較前後兩種情況下編譯之後的結果,就會發現它們是一樣的,也就是說在源文件中的不同之處編譯後在內存中是沒有反映的,既然沒有反映,就談不上真正的區別,所以,這裡的所謂封裝只是對程式設計師自身的一種約束,沒有真正的意義。

4.3. 繼承(Inheritance)

繼承是指能夠直接獲得已有的性質和特徵,而不必重複定義。是子類自動的共享基類中定義的數據和方法的機制。
C++ Base Class的程序復用(編譯時的靜態復用)

_繼承的實質就是少寫代碼,節省打字時間,減少出錯可能,它只是程序復用,是一種靜態機制。因為,代碼是自己寫的還是從別的類中繼承的,反映在內存中是一樣的,沒有區別,所以,繼承只是在工程上有意義,更多是面向開發者,工程師可以利用這個方法提高開發效率,對使用者而言,則毫無意義。

COM Aggregation(聚合)

組件復用(運行時的動態復用)、相對靈活構造。(參見COM編程技術)

4.4. 多態(Polymorphism)

多態一詞來源於希臘語,簡單說就是有許多形態,它增加了面向對象軟體系統的靈活性,C++中使用虛函數實現,是C++中最重要的概念。例5中class B的函數前加上virtual關鍵字之後,在這個數據結構中前4個字節保留下來,形成運算表(虛函數表vtbl),運算表中存放函數的入口地址,通過指針訪問,形成間址結構,如下圖所示。只要通過指針訪問這個表(通過這層間址),調用不同的函數,從前的很多程序問題都可迎刃而解。

UNIX 的驅動程序模型就是用的這種結構,取得了巨大的成功。如:
_open(); close(); read(); write(); ioctl();

4.5. 類(Class) 類廠(ClassFactory)

類是對具有相同屬性和行為的一個或多個對象的描述,它是建立對象時使用的"樣板"。C++中類的概念是假的,它的類在編譯之後,到內存中沒有實體與其對應,因此C++不存在真正的類的概念。而smalltalk中類是一種特殊的對象,對象是一種特殊的類,對象這種數據結構是佔內存的,所以類也是佔內存的,這樣才是真正的類。

類的概念有多重要性是:

_第一,對象要有生死的概念(lifetime),對象從哪裡來,由類來控制,Microsoft則叫它類廠,強調產生類、產生對象這個概念。

第二,類引出映射的概念。例如整數集合上的加、減、乘、除這四個運算,它們是跟整數類相對應的,按照馮·諾伊曼的存儲程序理論,程序就是數據,所以它們既是運算也是數據,作為數據應該放在整數類中,放在類中有什麼用呢?這裡引出映射的概念,來解答這個問題。

4.6. 映射(Reflection)

下面 通過對加法運算的兩種不同情況闡述映射的概念。

· 普通的32位加法,如果溢出了,怎麼辦?可不可以做64位加呢?既然是數,就能改,可以在運行過程中(動態)把一個32位數用一個PUSH語句入棧,再把另一個也壓入棧中,這樣32位加法運算轉變為64位加法運算,問題解決了。同樣的加、減、乘、除這四個運算,可以映射出不同的運算實現來,32位運算,64位運算是兩種不同的實現,這種不同的實現就是對同一個描述的不同映射。

· 網絡上的運算如何實現?同樣還是加、減、乘、除運算,在網上,計算可以在本地進行,也可以在遠程進行。比如說會做加法的進程在遠程,這時本地進程將運算數據打包發給遠程進程,遠程進程計算後將結果打包送回。本地和遠程,這是兩種不同的實現方式,對於設計者來說,本地計算方式是用一段代碼進行計算,遠程計算方式是用一段代碼與遠程進行通信,但對於用戶來說都是加法,除了時間上可能有差別外,其它完全一樣,這是完全透明的網絡運算。這就是映射。
C++中不存在真正的類,更不存在映射的概念。然而,類和映射的概念至關重要,要提到一個新的高度來認識。C++源程序編譯後的目標代碼是 .obj,而JAVA源程序編譯後目標代碼是 .class,JAVA想說明運算可以在運行中改,只有有了這個前提才能真正做到完全透明的網絡運算。認識到這一點,舉一反三,JAVA還能把32位加法動態提升為64位加法等等。如果把這種思想應用於軟體設計,那麼是不是能做到他人無法做到的事情呢?

映射(Reflection)這個概念怎麼強調也不過分,它是程序設計的一個裡程碑,從結構化設計到面向對象,有了多態這個概念,程序設計靈活了,現在又有了映射,程序設計更加靈活,人們走入了一個新境界。


北京科泰世紀科技有限公司 版權所有 2000年--2002年


5. C++、COM、COM+程序設計的比較

5.1. C++

程序模型
C++是面向對象編程的,它的模塊是靜態的,連結後不可分割,這是C++的最主要的缺點,它不能動態升級。

模塊實現
C++將運算與數據結合起來,放在類中,通過繼承實現程序重用,採用二進位標準,將不同模塊聯繫起來實現不同功能。
C++最關鍵的技術要點就是它加了一個vtbl(如下圖),它帶來很多好處,這在前面已經介紹過了,與原來的程序設計語言相比已經是一個跨越式的發展。

這裡區分兩個概念,語言和思想。C++是一種語言,是一種非常好的語言。它表達設計者的思想最容易、最直觀,但它或多或少的帶有設計者的歷史局限性,語言雖然還是好語言,但如今思想的局限性卻越來越明顯。

5.2. COM

1993年6月,Microsoft發布了COM標準,主要是認識到了C++的不足。另外,並不是只有Microsoft這樣認為,包括IBM發明Smalltalk、Digital發明CORBA、SUN發明JAVA,也都是認識到了這一點。在美國,所有大軟體公司的大的工程項目很少直接採用C++的編程思想,而是採用它們自己的編程思想,實現軟體設計。

COM解決了C++做不到的不同來源的組件之間的互操作,使某個組件升級時不影響其他組件,並且獨立於程式語言,實現了組件在進程內、跨進程甚至於跨網絡運行時對用戶的透明性。

程序模型

COM解決了C++做不到的不同來源的組件之間的互操作,使某個組件升級時不影響其他組件,並且獨立於程式語言,實現了組件在進程內、跨進程甚至於跨網絡運行時對用戶的透明性。

模塊實現

在C++模型基礎上增加了Interface ptr,目的就是要實現動態升級。舉例說明這個問題,例如下圖中已經有了兩個域,如果需要增加域怎麼辦?前面講過,棧有很多好處,要充分利用它,但是,如果一個數據結構放在棧上,這塊空間一旦分配,它是不可以更改的,這個模塊也就不可升級了,所以任何語言(JAVA、COM、C#等),它的組件、構件不可以生成在棧上,這是一個基本原則;然而,"指針,放之四海而皆準",可以在棧上放一指針(Interface ptr)來解決這個問題,(這個指針在JAVA中不是一個物理指針,是一個虛的,叫handle,相當於一個標識符,能訪問到就可以了),理論上講,這是增加一層間址,解決了組件動態可替換問題。

註冊資料庫

C++語言中使用new在堆上動態分配內存。例如,用new操作動態生成一個class,new是知道它所要分配的內存的大小的,既然知道大小,就沒有辦法升級。這個信息new是不該知道,這也正是C++當初違背封裝原則的一個體現;即使new不知道分配空間的大小,也要有一套協議,來查詢誰來支持這個class,誰來完成new操作。要想使模塊可以升級,就不能再用new。
在COM中,使用CoCreateInstance(),本公司的ezCOM使用NEW_COMPONENT,實際上是重載了new。為了在"new"的時候,知道class現在的大小、在什麼位置、由誰支持,需要在運行過程中創建一個資料庫,通過間址的方式查詢這個資料庫,獲得關於class的信息,之後才能創建一個class,只有這樣才能實現動態升級。創建class時要用一層間址,調用時同樣用一層間址,這兩方面構成了COM的基本內涵。

元資料庫(TypeLib)

COM,93年出現的時候,它已經提出了元數據的概念,但當時沒有給予強調,隨著Internet時代的到來,94、95年出現了browsor,SUN發明了JAVA,這兩件事大大加速了人們對軟體的理解。元數據已經應用在COM、JAVA和腳本語言中,但COM並沒有將元數據提高到一個無所不能的高度來理解,JAVA的設計者則不同,他把元數據提高到一個高層次,通過 .class便可一目了然。如何寫程序進入了嶄新的階段。

元數據(Metadata)是定義存儲在資料庫中數據的形式的數據,可認為是關於數據的數據。元數據是對運算的描述,比如對整數集上的加、減、乘、除這四個運算的描述就稱為整數集合(CLASS)上的Class Information,既為Metadata。CDL文件對ezCOM來說就是元數據,TLB是CDL的二進位表現,二者表達的信息是一樣的。

構件(Component) = 對象(Object) + 元數據(Metadata),構件是由兩部分組成的,一部分是對象,一部分是元數據,兩者打包在一起構成一個dll文件的構件。構件在物理上與對象是不同的,強調一點,如果在物理上不同(內存中反映不同),在現實中就會有不同的體現。正是因為這個原因,本公司的ezCOM與C++截然不同,如果認為ezCOM與C++完全一樣,或者就是用C++來編寫的,那就完全錯了。

程序應該用零件來構造,強調元數據的重要性,這是新的程序設計理念。

5.3. 關於自動化/自行化的概述

腳本語言

腳本語言(script),英文願意是手跡、手稿、副本的意思。腳本語言是解釋執行的,就相當於舞臺上話劇演員按著劇本的內容演出一樣,要一句一句的來。

模型/顯示/控制 (MVC)編程方式

本公司的圖形系統就是通過自動化來實現的,Model View Controller這個概念是smalltalk提出的,Windows、X-Windows都沒有按照面向對象、按照這套思路來做,JAVA、.NET都是按照這一套思路來做的,本公司也這樣做。

代理組件自動生成

自動遠程通訊主要通過自動化,通過元數據實現。(參見…)

自描述數據結構

雖然本公司的產品開發使用C++,但是在所有的接口函數上,參數都必須使用自描述數據結構,這也是對C++的限制,目的就是要動態生成中間件,通過映射動態生成不同的程序實現。能不能實現動態替換,很大程度上是通過元數據和自描述數據結構來完成的。

本公司的自描述數據結構如下(參見基礎數據類型文檔):
INT,LONG,CHAR,etc.
EzStr,EzByteBuf,etc.
EzIntArray,EzStrArray,etc.
EzVariant,EzDelegate,etc.

5.4. COM+

a. COM+ 程序模型

代理(虛擬)組件

COM+比COM更加重視元數據,有了元數據之後,達到的新境界,就是作業系統可以動態生成代理組件(由系統生成的組件就是中間件)。

在用戶程序與組件模塊之間插入代理組件帶來很多好處。Windows2000的COM+就是在強調這一點。代理組件,"薄"的時候可以什麼都沒有,就是一層間址,速度不會受損。它的靈活性是指可以動態替換零件,完成不同的功能,比如可以把一個圖形軟體放入內核或放到其它機器上等等,對用戶沒有影響;再如使用ORACLE時,假如有100個用戶,可是只買了10個版權,這時可以通過代理組件來給每個用戶分組件,實現動態共享;還比如說,在用戶通訊的過程中,可以通過代理組件中零件的替換實現呼叫轉移,接入Internet時,可以通過不同的零件加密、監控等等,這些都是加上代理組件的優越性。

COM+ 模塊實現

在COM的基礎上,再增加一層間址,定義運行環境 (Context),變為多層間址。工程師只要理解內存,學會用"尺"後,就會發現這種多重間址的妙處,程序設計就會變得非常靈活。

b. 組件運行環境對用戶透明

(詳細請參見其他相關文檔)


北京科泰世紀科技有限公司 版權所有 2000年--2002年



6. COM技術要點及編程(詳細請參見COM編程相關書籍)

1、 面向接口,可改變程序實現

2、 二進位標準 (無虛擬機)

3、 計數器控制生命周期

4、 動態模塊構造

5、 元數據支持解釋程序

6、 自描述數據結構

7、 自動遠程通訊


北京科泰世紀科技有限公司 版權所有 2000年--2002年


7. 例題解答

例1:
int a; // 佔4個字節,在全程數據區;在_BSS段,可參考cod文件
int b=1; // 佔4個字節,在全程數據區;與 a 不相連,在_DATA段

void main() {
int * p; // 分配在棧上
p = (int *) malloc (100); // 100 字節在堆上
……
}

例2:你好

例3:
int a[10000000]; // 不出錯

void main() {
int a[10000000];
// 出錯,棧的大小有限制,但可通過編譯器開關修改棧的大小
int *a = (int *) malloc(10000000);
// 在堆上只要硬體上有足夠的內存,是不出錯的,(堆可動態增長)
*a = 1;
printf("%d/n", *a);
}

例4:(堆)
void main() {
char *p = (char *) malloc(10000000);
char *q = new char[10000000];
……
free(p);
// 釋放10000000位元組的內存,malloc在堆上分配10000000位元組的內
// 存,不會自動釋放,需要用free來釋放
//delete q;
// 釋放10000000位元組的內存,new 在堆上分配10000000位元組的內存

相關焦點

  • python+C、C++混合編程的應用
    >在C/C++程序中使用Python.h,寫wrap包裝接口這種方法需要修改c/c++代碼,在外部函數中處理入/出參,適配python的參數。操作上,是針對c/c++程序編寫獨立的接口聲明文件(通常很簡單),swig會分析c/c++源程序自動分析接口要如何包裝。在指定目標語言後,swig會生成額外的包裝源碼文件。編譯so庫時,把包裝文件一起編譯、連接即可。
  • C 2 C++進階篇(1)
    首先談談筆者的水平,只學過c和數據結構,接觸過指針,對於取地址&從來沒有接觸過(因為據說是老師說不符合嚴謹的c....), python
  • C/C++優勢究竟在哪裡?是什麼讓他們經久不衰?看看這個你就懂了
    相較於C語言,c++誕生於1983年,緊隨c語言的步伐,c++是C語言的超集,大家所知道的C語言是面向過程的,java是面向對象的,那麼C語言為了面向對象,所以誕生出現在大家所熟知的c++,被廣泛視為大規模應用構建軟體。
  • 編譯器 | 五款好用的C/C++編譯器(IDE利器)
    這個 IDE 提供超強大的用戶界面開發 C/C++ 程序的接口。(編譯器獲取方式在文末)codeblocks擴展性能非常強大,也提供了很多工程模板,軟體內置大量的開發插件程序,你可以直接在軟體中進行連接下載,幫助您獲得更高效、穩定、快捷的開發輔助程序,codeblocks新版在項目構建。(編譯器獲取方式在文末)
  • C/C++可變參數函數
    c/c++支持可變參數的函數,即函數的參數是不確定的。一、為什麼要使用可變參數的函數?一般我們編程的時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的所有實際參數。但在某些情況下希望函數的參數個數可以根據需要確定,因此c語言引入可變參數函數。這也是c功能強大的一個方面,其它某些語言,比如fortran就沒有這個功能。典型的可變參數函數的例子有大家熟悉的printf()、scanf()等。二、c/c++如何實現可變參數的函數?
  • C語言?c+?到底先學哪個才能更好的理解編程,這些你造嗎
    本身C語言和c++的編程方法不同,一個面向過程,一個面向對象。而要做出大型的、複雜的、精彩的程序,面向對象的語言就更適合。所以要學習c++這樣的語言。但是,1.c語言是好多學校的基礎課;2.c語言很容易描述算法;3.軟體開發過程中也有很多面向過程的開發,以及模塊化程序設計思想。要學習這些,比起學c++的複雜、困難程度,學c語言就可以達到上述目的。
  • 九大程式語言優缺點第四期:c++
    C++:c++誕生於1983年,緊隨c語言的步伐,c++是C語言的超集,大家所知道的C語言是面向過程的,java是面向對象的,那麼C語言為了面向對象,所以誕生出現在大家所熟知的c++,被廣泛視為大規模應用構建軟體。
  • 編程大佬總結的50點學習C+的方法,一針見血,少走彎路
    14.浮躁的人容易問:xx和yy哪個好;——告訴你吧,都好——只要你學就行; 15.浮躁的人分兩種:a)只觀望而不學的人;b)只學而不堅持的人; 16.把時髦的技術掛在嘴邊,還不如把過時的技術記在心裡; 17.c++不僅僅是支持面向對象的程序設計語言;
  • C/C++程序CPU問題分析
    代碼片段2中的這段代碼中,第1、2行中的memset會導致程序的CPU使用過多,但即使是將這兩行的代碼注釋掉,程序的性能依然沒有明顯的改觀。問題的根源在於代碼片段2中最後一行代碼調用的odb_renew函數有釋放內存和大量的memset操作,導致消耗的CPU很多。如果在程序中調用了大量的odb_renew函數,其性能一定不太好。
  • 簡要記錄丨VSCode 搭建基礎 C/C++ 編譯環境
    我覺得首先概念要正確,然後才能好好正視這個軟體,參考知乎回答解釋如下:VSC 只是一個純文本編輯器( editor ),不是 IDE (集成開發環境),不含編譯器( compiler )和許多其它功能,所以編譯器要自己裝好。
  • 混合使用C、C++和彙編語之:內聯彙編和嵌入型彙編的使用
    使用它可以在C/C++程序中實現C/C++語言不能完成的一些工作。例如,在下面幾種情況中必須使用內聯彙編或嵌入型彙編。·程序中使用飽和算術運算(Saturatingarithmetic),如SSAT16和USAT16指令。·程序中需要對協處理器進行操作。
  • 如何通過wrap malloc定位C/C++程序的內存洩漏
    動態內存分配器是介於kernel跟應用程式之間的一個函數庫,glibc提供的動態內存分配器叫ptmalloc,它也是應用最廣泛的動態內存分配器實現。從kernel角度看,動態內存分配器屬於應用程式層;而從應用程式的角度看,動態內存分配器屬於系統層。
  • C 語言會比 C++ 快?
    和面向過程的 C 語言相比,其繼承者 C++ 不僅可以進行 C 語言的過程化程序設計,還可以進行以繼承和多態為特點的面向對象的程序設計。要論兩者上手的難易度,對此,有網友評價道,學好 C 只要 1 年,而學好 C++ 需要的可能不止 10 年。
  • 乾貨分享:用一百行代碼做一個C/C++表白小程序,程式設計師的浪漫!
    做一個浪漫的程序給她,放上你們照片,找一段有符合情景的音樂,既有心意,又有浪漫。所以說,程序猿的浪漫你根本想像不到啊。等下把程序自己做出來 慢慢體會程序呀的浪漫。5.話不多說咱們直接上代碼#include "graphics.h" //c++圖形界面庫#include "stdio.h"#include "time.h"#include "mmsystem.h"#pragma
  • C++隨機排序容器中的元素
    作者:apocelipes連結:https://www.cnblogs.com/apocelipes/p/10351335.html在各種程序語言中都提供了將容器元素隨機排序的shuffle方法,c++也不例外。
  • C/C++常見面試題整理
    1、C++裡面如何聲明const void f(void)函數為C程序中的庫函數?2、c++中類和c語言中struct的區別(至少兩點)3、變量的聲明和定義有什麼區別?4、memset ,memcpy 的區別5、程序什麼時候應該使用線程,什麼時候單線程效率高。6、介紹一下模板和容器。如何實現?
  • C語言,C++,C ,Java之間的關係
    再後來,發展到現在,就是高級語言了,c語言是最早的高級語言,我們現在的很多系統都是由c語言寫出來的。這也進一步說明c語言很經典,也很重要。再後來,出現了c++,這是為了彌補C語言的不足,C++很難,很複雜。
  • 剖析C語言中a=a+++a的無聊問題
    於是乎兄弟姐妹們開始討論它的運算結果,以及改如何理解。更有人寫出(a++)+(++a) a+(++(++a)) ((a++)++)+a這樣的東西,問應該如何計算。我表示鴨梨很大...本文引用地址:http://www.eepw.com.cn/article/198269.htm  針對這樣的問題我的觀點是,「絕不小心求證,只管大膽胡說!」
  • 學習c++筆記——標準輸出流cout
    前和往常一樣,一邊喝早茶,一邊上網和女粉絲侃大山,在手機和平板電腦上整理修改《html5》、《javascript》、《css3》、《c語言》等多年前寫的教程
  • 精通C++還是寫不好程序?
    最近群裡有些同學問我,為什麼我覺得我精通C++了還是寫不出來程序?這其實是學習程序挺普遍的狀態。我自己也遇到過。首先,這個精通的意義不是特別明確。但是只是精通了語法寫不出好程序。就好比你把字典整本記下來也寫不出好文章。學會語法不等於能寫出好程序。寫程序和寫文章差不多,你首先要明白寫程序的目的。然後分解為問題,再一步一步解決。這是做程序的常規流程。所以單獨記憶語法不行。