C 中值得注意的細節地方 逐步更新中

2021-05-27 22:40:44 字數 3089 閱讀 4774

1.static的作用

static對於函式來說,只有隱藏的作用,即把本函式設定為本檔案可見。

static對於變數來說,不僅可以隱藏,還讓變數存放在靜態儲存區域,具有永久性和預設為零。

2.struct與類的大小

在對struct和類用sizeof()取大小時,會遵循對齊原則(盡可能地湊4和湊8)

例如:class x   ;    sizeof() = 16  

解釋: 前三個占用6位元組,最後乙個占用8位元組,但是由於湊合,前三個剩下的兩位元組系統自動填充,所以是16位元組

class x   ;    sizeof() = 8

解釋:湊8,兩個位元組自動填充

class x   ;    sizeof() = 24

解釋:前三個是9,超出了8,所以前兩個填充至8,後面的話分別是4和8,盡量湊8,所以第三個占用8個位元組,總共24位元組

3.棧、堆、常量區、**區

棧:局域變數的存放區域,系統會自動申請與釋放,大小為2m

堆:程式設計師自己申請的區域,要自己釋放

常量區:常量存放的區域,預設值是0

**區:**存放區域

注:char string[10]=「abc」; 與 char*  str1=「abc」;是有區別的。前者存放在棧區域,而後者的指標放在棧,值存放在常量區域,而且string無效,而str1(指向乙個步不知的地方)有效。

4.strlen與sizeof的區別

前者的引數是char*,去到/0才結束,而sizeof則根據實際記憶體大小取值

5.string foo( );

void bar(string & s);

那麼下面的表示式將是非法的:

bar(foo( ));

bar("hello world");

原因在於foo( )和"hello world"串都會產生乙個臨時物件,而在c++中,這些臨時物件都是const型別的。因此上面的表示式就是試圖將乙個const型別的物件轉換為非const型別,這是非法的。

引用型引數應該在能被定義為const的情況下,盡量定義為const 。

6. 過載(overload)和重寫(overried,有的書也叫做「覆蓋」)的區別?

從定義上來說:

過載:是指允許存在多個同名函式,而這些函式的參數列不同(或許引數個數不同,或許引數型別不同,或許兩者都不同)。

重寫:是指子類重新定義復類虛函式的方法。

從實現原理上來說:過載:編譯器根據函式不同的參數列,對同名函式的名稱做修飾,然後這些同名函式就成了不同的函式(至少對於編譯器來說是這樣的)。如,有兩個同名函式:function func(p:integer):integer;和function func(p:string):integer;。那麼編譯器做過修飾後的函式名稱可能是這樣的:int_func、str_func.對於這兩個函式的呼叫,在編譯器間就已經確定了,是靜態的。也就是說,它們的位址在編譯期就繫結了(早繫結),因此,過載和多型無關!

重寫:和多型真正相關。當子類重新定義了父類的虛函式後,父類指標根據賦給它的不同的子類指標,動態的呼叫屬於子類的該函式,這樣的函式呼叫在編譯期間是無法確定的(呼叫的子類的虛函式的位址無法給出)。因此,這樣的函式位址是在執行期繫結的(晚繫結)。

7. 多型的作用?

主要是兩個:1. 隱藏實現細節,使得**能夠模組化;擴充套件**模組,實現**重用;2. 介面重用:為了類在繼承和派生的時候,保證使用家族中任一類的例項的某一屬性時的正確呼叫。

8. new delete 與malloc free 的聯絡與區別?

都是在堆(heap)上進行動態的記憶體操作。用malloc函式需要指定記憶體分配的位元組數並且不能初始化物件,new 會自動呼叫物件的建構函式。delete 會呼叫物件的destructor,而free 不會呼叫物件的destructor.

9.class和struct做型別定義時只有兩點區別:

(一)預設繼承許可權。如果不明確指定,來自class的繼承按照private繼承處理,來自struct的繼承按照public繼承處理;

(二)成員的預設訪問許可權。class的成員預設是private許可權,struct預設是public許可權。

10.當乙個類a 中沒有生命任何成員變數與成員函式,這時sizeof(a)的值是多少,如果不是零,請解釋一下編譯器為什麼沒有讓它為零。(autodesk)

答案:肯定不是零。舉個反例,如果是零的話,宣告乙個class a[10]物件陣列,而每乙個物件占用的空間是零,這時就沒辦法區分a[0],a[1]…了。

11.sizeof()與strlen()的區別

兩者的主要區別是前者是計算占用記憶體大小,後者是計算字串的長度,所以後者只能用char*作為引數,而且到\0就停止計算.

前者是乙個算符,後者是乙個函式.

12.stl中容器的概述

序列容器: vector     動態陣列、記憶體連續存放,支援【】符號

deque    佇列、記憶體連續存放、支援【】符號

list          鍊錶、記憶體不連續、不支援【】符號

關聯容器     set\multiset         紅黑樹、傳進的值已排列

map\multimap   紅黑樹、有乙個鍵值

介面卡:由容器實現的容器,沒有迭代器,而且一次不允許插入或刪除多個元素

stack      堆疊,預設由vector實現,也可以由deque和list實現

queue    佇列,預設由deque實現,也可以由list和vector實現

priority_queue    有優先順序的佇列,預設先訪問頭乙個(即優先順序最高)元素,當元素優先順序相同時才用先進先出。元素按有序順序排列,預設用vector實現,也可以                                                 用deque,但是不能用list,因為list不能快速訪問元素,而priority_queue要求對元素進行快速訪問以便排序。

注:priority_queue預設以大頂堆的形式存放資料,如果要以小頂堆的形式存放則要另外定義,如下:

priority_queue

<

int, vector

<

int>

, greater

<

int>

>

q;詳細用法看我的另一篇文章

ATL中值得注意的C 技術

1.多重繼承中的名字衝突問題。class father class mother class baby public father,public mother virtual int mother faint 錯誤,無法區別father faint和mother faint。既然father和bab...

轉貼 Unix C語言值得注意的地方

盡量的把函式弄的通用點,行少點,乙個函式只完成乙個簡單的功能,一眼就能看出來此函式有沒有 錯誤,每個函式都是健壯的,那麼你的程式就是健壯的。要少 完成乙個功能的時候在邏輯清楚的情況下 越少越好,千萬不要比 誰寫的多啊。演算法要好 在 完成乙個功能的時候要考慮效率,目前計算機的記憶體很大,所以記憶體已...

golang 值得注意的地方(2則)

golang 的語法和使用方式都非常簡單明瞭,沒有花哨的語法糖,也沒有多餘的關鍵字。但是即使是這麼簡潔的語言,仍然有一些不那麼直白,需要注意的地方,比如下面2點。package main import bytes fmt io func main f b func f out io.writer e...