C/C++知識重點

1 指針和引用的區別

①指針是一個變量,這個變量裏存放一個地址,指向內存的一個存儲單元,引用只是一個變量的別名;

②指針可以爲NULL,引用不可爲空必須初始化;

③指針的值初始化之後可以改變,引用初始化之後不可以改變;

④可以有多級指針不可以有多級引用;

⑤sizeof指針,得到指針本身自己的大小,32位系統是4,64位系統是8,sizeof引用,得到指向對象的大小。

(在學習C/C++或者想學習C/C++的同學可以加羣:231662552,大家一起學習交流謝謝各位觀衆姥爺們的支持)

2 靜態變量和普通變量的區別

①static全局變量只初始化一次,防止其他文件單元被引用;

②static局部變量只初始化一次,下一次依據上一次的結果值;而普通變量在下一次調用時還是用初始化的值;

③static函數在內存中只有一份,普通函數在每一次被調用中維持一份複製品。

4 阻塞和非阻塞

是把數據從用戶空間拷貝到內核空間緩衝區這段時間而言的。

⑴如果發送緩衝區剩餘空間> 想要發送data字節數

阻塞非阻塞都會將數據拷貝到內核,並且大小就是想要發送數據的大小;

⑵如果發送緩衝區剩餘空間< 想要發送data字節數

①阻塞模式

會阻塞,等到內核緩衝區有足夠的空閒空間,再繼續將數據拷貝到內核,直到拷貝完,返回值就是發送數據的數據量;

②非阻塞模式

當內核緩衝區被填滿後立即返回,返回值是已經拷貝到發送緩衝區的數據量。

5 static關鍵字的作用

⑴在面向過程的編程中

①隱藏。在變量或者函數前加上static,只是對本文件可見,對其他文件不可見。

②只初始化一次,並且默認初始化爲0

③如果作爲static局部變量在函數內定義,它的生存期爲整個源程序,但是其作用域是定義該變量的函數,只能在定義該變量的函數內使用該變量。退出該函數後,儘管該變量還繼續存在,但不能使用它。

⑵面向對象的編程

①類的靜態成員函數是屬於整個類而非類的對象,所以它沒有this指針,僅能訪問類的靜態數據和靜態成員函數。

②不能將靜態成員函數定義爲虛函數。

③在類中定義static相當於一個全局變量,但是一定在類外進行初始化,

int son::num=222;

④在不聲明類對象就能使用類中的變量和函數,只需要在前面加上作用域就可以;

6 const作用

①可以定義const常量,如const int Max = 100;

②便於進行類型檢查,保護被修飾的東西,防止意外的修改,如

void f(const int i){…}編譯器就會知道i是一個常量,不允許修改

③const定義的常量在程序運行過程中只有一份拷貝,

④修飾指針

const int *A; //const修飾指向的對象,A可變,A指向的對象不可變

int *const A; //const修飾指針A,A不可變,A指向的對象可變

const int *constA; //指針A和A指向的對象都不可變

⑤修飾引用

const double &A; //該引用所引用的對象不能被更新

⑥修飾函數的返回值

是返回值不可被改變,格式如下:constint Fun1();

⑦修飾類的成員變量

int Fun() const;這樣,函數Fun中不能修改類裏面的數據。

⑧在另一連接文件中引用const常量

extern const inti; //正確的引用

extern const int j =10;//錯誤,常量不可以被再次賦值

⑨提高了效率

編譯器通常不爲普通const常量分配存儲空間,而是將它們保存在符號表中,這使得它成爲一個編譯期間的常量,沒有了存儲與讀內存的操作,使得它的效率也很高。

(在學習C/C++或者想學習C/C++的同學可以加羣:231662552,大家一起學習交流謝謝各位觀衆姥爺們的支持)

7 斐波那契數列求時間複雜度

例T(n) = 2T(n/2)+1,其時間複雜度是O(n);

公式:T(n) = aT(n/b)+f(n); a遞歸調用次數

                         b數據規模

                         f(n)單次過程的時間複雜度

比較 和f(n) ① > f(n) 時間複雜度是:O()

               ② < f(n)              O()

8 break :跳出當前循環或者switch語句

Continue:結束當前循環,開始下一輪循環

9、斐波那契數列求第n項

注意只要用到後一項等於幾的情況都要考慮斐波那契數列。

①下一項等於前兩項的和

②下一項等於前(n-1)項的和

10、結構與聯合有和區別?

(1). 結構和聯合都是由多個不同的數據類型成員組成, 但在任何同一時刻, 聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間), 而結構的所有成員都存在(不同成員的存放地址不同)。

(2). 對於聯合的不同成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對於結構的不同成員賦值是互不影響的。

11、main 函數執行以前,還會執行什麼代碼?

答案:全局對象的構造函數會在main 函數之前執行。

12.分別寫出BOOL,int,float,指針類型的變量a 與“零”的比較語句。

BOOL : if ( !a ) or if(a)

Int : if ( a == 0)

float : const EXPRESSION EXP = 0.000001

if ( a < EXP && a >-EXP)

pointer : if ( a != NULL) or if(a == NULL)

13.const與 #define 的比較,const有什麼優點?

(1) const 常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對後者只進行字符替換,沒有類型安全檢查,並且在字符替換可能會產生意料不到的錯誤(邊際效應)。

(2) 有些集成化的調試工具可以對 const 常量進行調試,但是不能對宏常量進行調試。

(在學習C/C++或者想學習C/C++的同學可以加羣:231662552,大家一起學習交流謝謝各位觀衆姥爺們的支持)

14.全局變量和局部變量有什麼區別?是怎麼實現的?操作系統和編譯器是怎麼知道的?

①生命週期不同:

全局變量隨主程序創建而創建,隨主程序銷燬而銷燬;

局部變量在局部函數內部,甚至局部循環體等內部存在,退出就不存在;

②使用方式不同:

通過聲明後全局變量程序的各個部分都可以用到;

局部變量只能在局部使用;分配在棧區。

③操作系統和編譯器通過內存分配的位置來知道的,全局變量分配在全局數據段並且在程序開始運行的時候被加載。局部變量則分配在堆棧裏面。

  1. 什麼時候需要“引用”?

流操作符<<和>>、賦值操作符=的返回值、拷貝構造函數的參數、賦值操作符=的參數、其它情況都推薦使用引用。
以上 2-8 參考:http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx

  1. extern “C”

在C++ 程序中調用被C 編譯器編譯後的函數,爲什麼要加extern “C”?

⑴extern是C/C++語言中表明函數和全局變量作用範圍的關鍵字,該關鍵字告訴編譯器, 其聲明的函數和變量可以在本模塊或其它模塊中使用。

⑵使用的時候,是在模塊的頭文件中,對本模塊提供給其它模塊引用的函數和全局變量以關鍵字extern聲明。

例如,如果模塊B欲引用該模塊A中定義的全局變量和函數時,需要在A的頭文件中把B想要引用的A的全局變量和函數前面加上extern,而B在使用的時候只需包含模塊A的頭文件即可。

⑶extern "C"用於C++要使用C的變量和函數的時候,是連接申明,被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的。

C++支持函數重載,而過程式語言C則不支持。

例如,假設某個函數的原型爲: voidfoo( int x, int y );
  該函數被C編譯器編譯後在符號庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int這樣的名字包含了函數名、函數參數數量及類型信息,C++就是靠這種機制來實現函數重載的。

例如,在C++中,函數void foo( int x,int y )與void foo( int x,float y )編譯生成的符號是不相同的,後者爲_foo_int_float。

實現C++與C及其它語言的混合編程。  
明白了C++中extern"C"的設立動機,我們下面來具體分析extern "C"通常的使用技巧:
extern “C"的慣用法
(1)在C++中引用C語言中的函數和變量,在包含C語言頭文件(假設爲cExample.h)時,需進行下列處理:
extern “C”
{
#i nclude"cExample.h”
}
而在C語言的頭文件中,對其外部函數只能指定爲extern類型,C語言中不支持extern"C"聲明,在.c文件中包含了extern “C"時會出現編譯語法錯誤。
C++引用C函數例子工程中包含的三個文件的源代碼如下:
/* c語言頭文件:cExample.h /
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/
c語言實現文件:cExample.c /
#i nclude"cExample.h"
int add( int x, int y )
{
return x + y;
}
// c++實現文件,調用add:cppFile.cpp
extern “C”
{
#i nclude"cExample.h"
}
int main(int argc, char
argv[])
{
add(2,3);
return 0;
}
如果C++調用一個C語言編寫的.DLL時,當包括.DLL的頭文件或聲明接口函數時,應加extern"C” { }。

(在學習C/C++或者想學習C/C++的同學可以加羣:231662552,大家一起學習交流謝謝各位觀衆姥爺們的支持)

(2)在C中引用C++語言中的函數和變量時,C++的頭文件需添加extern"C",但是在C語言中不能直接引用聲明瞭extern "C"的該頭文件,應該僅將C文件中將C++中定義的extern “C"函數聲明爲extern類型。
C引用C++函數例子工程中包含的三個文件的源代碼如下:
//C++頭文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern “C” int add( int x, int y );
#endif
//C++實現文件 cppExample.cpp
#i nclude"cppExample.h”
int add( int x, int y )
{
return x + y;
}
/* C實現文件 cFile.c
/* 這樣會編譯出錯:#i nclude “cExample.h” /
extern int add( int x, int y );
int main( int argc, char
argv[] )
{
add( 2, 3 );
return 0;
}

17 面向對象和麪向過程的區別?

面向對象的三個特點是封裝,繼承和多態。

①封裝性上

面向對象的封裝:將一系列的數據和方法封裝在類中;

面向過程的封裝:數據用struct封裝,方法不封裝,方法和數據是分離的。

②代碼複用上

面向對象:利用繼承的方式服用;

面向過程:只能以普通的函數複用。

18 map,set的底層實現?

 Map和set都是STL中的關聯容器,內部採用的就是一種非常高效的平衡檢索二叉樹:紅黑樹來實現的;

  Map內部自建一顆紅黑樹,這棵樹具有對數據自動排序的功能,所以map內部所有的數據都是有序的;一個map是一鍵值對序列,

  紅黑樹是結合了鏈表添加刪除方便;和數組查找效率高的優點,所以map應用起來方便高效。

19 map,set的區別?

vector封裝數組,list封裝了鏈表,map和set封裝了二叉樹等

      ①Map和set都是屬於STL中的關聯容器,

MAP的節點是一對數據.;使用關鍵值Key來唯一標識每一個成員 map可以重複;

SET的節點是一個數據,set是一個集合 。
只不過,map的形式 map<type1, type2> mymap;
set的形式 set myset;

②map是映射集合中的元素不能重複,set可以進行集合的各種操作(交併補等),當然set一般是用平衡樹或哈西表實現的。

(在學習C/C++或者想學習C/C++的同學可以加羣:231662552,大家一起學習交流謝謝各位觀衆姥爺們的支持)

List特點:元素有放入順序,元素可重複
Map特點:元素按鍵值對存儲,無放入順序
Set特點:元素無放入順序,元素不可重複(注意:元素雖然無放入順序,但是元素在 set中的位置是有該元素的HashCode決定的,其位置其實是固定的)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章