c/c++學習理論部分1

1 bool、int、float、double變量與0值的比較

- bool
if(flag)或者if(!flag)

- int
if(value==0)

if(value!=0)

- float
const float EPSINON = 0.000001;
if ((x >= - EPSINON) && (x <= EPSINON)

- 指針

if (p == NULL)
if (p != NULL)

2 堆和棧

  • 棧:stack:
    棧是向低地址擴展的數據結構,是一塊連續的內存的區域,由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧;先進後出的性質的數學或數據結構。

  • 堆 heap
    一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閒內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。堆獲得的空間比較靈活,也比較大。先進先出

堆一般是編程序時用malloc,new這樣的函數申請的空間,然後程序用free,delete來釋放。

//main.cpp
int a = 0; 全局初始化區
char *p1; 全局未初始化區
main()
{
int b;char s[] = "abc";char *p2;char *p3 = "123456"; 123456在常量區,p3在棧上。
static int c =0; 全局(靜態)初始化區
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得來得1020字節的區域就在堆區。
strcpy(p1, "123456"); 123456放在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方。
}
  • 存取效率的比較
    char s1[] = “aaaaa”;//棧
    char *s2 = “bbbbb”;
    aaaaa是在運行時刻賦值的;而bbbbb是在編譯時就確定的;
    但是,在以後的存取中,在棧上的數組比指針所指向的字符串(例如堆)快。

3 信號與任務之間的通信、任務優先級的反轉

1、信號量是什麼?有什麼區別?使用信號量進行任務間通信有何優缺點?
信號量一是可以用來表示一個或多個事件的發生,二是用來對共享資源的訪問。

包括建立、請求、釋放的過程。

2、在多任務系統中, 常見的任務通訊機制或任務同步手段有哪些?

答:管道通信 信號通信 共享內存 消息隊列 信號量 。而在uC/OS中的通信機制有信號量、互斥信號量(對於互斥資源的發生)、標誌事件組(等待資源釋放的事件發生)、郵箱(郵箱是否有消息)、消息隊列(多個消息郵箱構成)。

3、互斥信號量與任務優先級的反轉

答:只能取值0或1,爲了防止優先級反轉,對互斥信號量採用了優先級繼承機制。
如當前任務優先級50,優先級3的任務請求互斥信號量因爲已被佔用而阻塞。而任務優先級20不請求互斥信號量所以運行,如果又有任務優先級30、40運行,那麼任務優先級50會一直不釋放信號量而導致任務優先級3一直得不到運行。這就發生了優先級反轉。
這時,需要將正得到信號量的優先級50提高爲優先級2就能保證它使用完資源任務執行完而釋放信號量。

const

  • 問題1
    有下面的函數聲明:
    double d() const;
    其中的“const“有什麼用?是什麼意思?請舉例說明下什麼時候用這種形式?
    答:
    非靜態成員函數後面加const(加到非成員函數或靜態成員後面會產生編譯錯誤),表示成員函數隱含傳入的this指針爲 const指針,決定了在該成員函數中,任意修改它所在的類的成員的操作都是不允許的(因爲隱含了對this指針的const引用);唯一的例外是對於 mutable修飾的成員。加了const的成員函數可以被非const對象和const對象調用,但不加const的成員函數只能被非const對象調 用。例如:
class A
{
    private:
        int m_a;
    public:
         A() : m_a(0) {}
         int getA() const { return m_a; //同return this->m_a;}
         int GetA() { return m_a; }
         int setA(int a) const
        {
                 m_a = a; //這裏產生編譯錯誤,如果把前面的成員定義int m_a;改爲mutable int m_a;就可以編譯通過。
        }
          int SetA(int a)
          { m_a = a; //同this->m_a = a;
       }
};
      A a1;
      const A a2;
       int t;
        t = a1.getA();
        t = a1.GetA();
        t = a2.getA();
        t = a2.GetA(); //a2是const對象,調用非const成員函數產生編譯錯誤。
const對象只能調用const成員函數。  
 const對象的值不能被修改,在const成員函數中修改const對象數據成員的值是語法錯誤  
 在const函數中調用非const成員函數是語法錯誤  

const數據成員只在某個對象生存期內是常量,而對於整個類而言卻是可變的。
因爲類可以創建多個對象,不同的對象其const數據成員的值可以不同。
所以不能在類聲明中初始化const數據成員,因爲類的對象未被創建時,
編譯器不知道const 數據成員的值是什麼。如

class A

{

 const int size = 100;    //錯誤

 int array[size];         //錯誤,未知的size

}

const int m1 = new int(10);
int
const m2 = new int(20);
名字叫法:從左到右叫。
在上面的兩個表達式中,最容易讓人迷惑的是const到底是修飾指針還是指針指向的內存區域?
其實,只要知道:const只對它左邊的東西起作用,唯一的例外就是const本身就是最左邊的修飾符,
那麼它纔會對右邊的東西起作用。根據這個規則來判斷,m1應該是常量指針(即,不能通過m1來修改它所指向的內容。);
而m2應該是指針常量(即,不能讓m2指向其他的內存模塊)

編程題

快速創建一個1G的文件,逆序讀取
答:
使用dd命令,
dd if=/dev/zero of=test bs=1M count=1024
在當前目錄下會生成一個1G的test文件,文件內容爲全0(因從/dev/zero中讀取,/dev/zero爲0源

#include <stdio.h>  
#include <stdlib.h> 
int main()
{

FILE *fp;
long int count,last;
system("dd if=/dev/zero of=test bs=1M count=1024"); //創建1GB的test文件
    if((fp =fopen("./test","rb")) == NULL)
    {
    printf("file is not existing\n");
    exit(1);
    }
 fseek(fp,0L,SEEK_END);
last=ftell(fp);
    for(count=1L;count<=last;count++)
    {          fseek(fp,-count,SEEK_END);         
           ch=getc(fp); //取一個字符                   
           putchar(ch);    
    }
fclose(fp);
return 0;
}

大小端

大端模式:數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中。

小端模式:數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中。
比如,32bit寬的數的十六進制表示爲 0x01234567

(地址從低位開始存放)

如果是小端模式,則存儲方式爲:0x67 0x45 0x23 0x01

如果是大端模式,則存儲方式爲:0x01 0x23 0x45 0x67

#include <stdio.h>

int check()

{

	int i = 1;

	i = *(char*)&i;	//取 i 的地址 強制類型轉換後解引用

	return i;

}

int main(void)

{

	if(check()==1)

		printf("小端模式存儲!\n");

	else			//check()==0

		printf("大端模式存儲!\n");

	return 0;

}

c語言關鍵字

auto break case char const continue default do
oouble else enum extern float for goto if
int long register short signed sizeof static return
struct switch typedef union unsigned void volatile while

在這裏插入圖片描述

  • IPv4把所有的IP地址分爲A,B,C,D,E五類.請寫出B類地址和C類地址的範圍和掩碼,D類地址的用途是什麼?
    答:
    A類IP地址用於大型網絡,B類IP地址用於中型網絡,C類用於小規模網絡,最多隻能連接256臺設備,D類IP地址用於多目的地址發送,E類則保留爲今後使用.
  1. A類地址
    ⑴ A類地址第1字節爲網絡地址,其它3個字節爲主機地址。
    ⑵ A類地址範圍:1.0.0.1—126.155.255.254
    ⑶ A類地址中的私有地址和保留地址:
    ① 10.X.X.X是私有地址(所謂的私有地址就是在互聯網上不使用,而被用在局域網絡中的地址)。
    ② 127.X.X.X是保留地址,用做循環測試用的。

  2. B類地址
    ⑴ B類地址第1字節和第2字節爲網絡地址,其它2個字節爲主機地址。
    ⑵ B類地址範圍:128.0.0.1—191.255.255.254。
    ⑶ B類地址的私有地址和保留地址
    ① 172.16.0.0—172.31.255.255是私有地址
    ② 169.254.X.X是保留地址。如果你的IP地址是自動獲取IP地址,而你在網絡上又沒有找到可用的DHCP服務器。就會得到其中一個IP。

  3. C類地址
    ⑴ C類地址第1字節、第2字節和第3個字節爲網絡地址,第4個個字節爲主機地址。另外第1個字節的前三位固定爲110。
    ⑵ C類地址範圍:192.0.0.1—223.255.255.254。
    ⑶ C類地址中的私有地址:
    192.168.X.X是私有地址。

  4. D類地址
    ⑴ D類地址不分網絡地址和主機地址,它的第1個字節的前四位固定爲1110。
    ⑵ D類地址範圍:224.0.0.1—239.255.255.254

  5. E類地址
    ⑴ E類地址也不分網絡地址和主機地址,它的第1個字節的前五位固定爲11110。
    ⑵ E類地址範圍:240.0.0.1—255.255.255.254

道必須掌握的C++面試題

問1:請用簡單的語言告訴我C++ 是什麼?
答:C++是在C語言的基礎上開發的一種面向對象編程語言,應用廣泛。C++支持多種編程範式 --面向對象編程、泛型編程和過程化編程。 其編程領域衆廣,常用於系統開發,引擎開發等應用領域,是最受廣大程序員受用的最強大編程語言之一,支持類:類、封裝、重載等特性!

問2:C和C++的區別?
答:c++在c的基礎上增添類,C是一個結構化語言,它的重點在於算法和數據結構。C程序的設計首要考慮的是如何通過一個過程,對輸入(或環境條件)進行運算處理得到輸出(或實現過程(事務)控制),而對於C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通過獲取對象的狀態信息得到輸出或實現過程(事務)控制。

問3:什麼是面向對象(OOP)?
答:面向對象是一種對現實世界理解和抽象的方法、思想,通過將需求要素轉化爲對象進行問題處理的一種思想。

問4:什麼是多態?
答:多態是指相同的操作或函數、過程可作用於多種類型的對象上並獲得不同的結果。不同的對象,收到同一消息可以產生不同的結果,這種現象稱爲多態。

問5:設計模式懂嘛,簡單舉個例子?
答:

設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

比如單例模式,保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

適用於:當類只能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時;當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個擴展的實例時。

比如工廠模式,定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。

適用於:當一個類不知道它所必須創建的對象的類的時候;當一個類希望由它的子類來指定它所創建的對象的時候;當類將創建對象的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一信息局部化的時候。

問6:STL庫用過嗎?常見的STL容器有哪些?算法用過哪幾個?
答:

STL包括兩部分內容:容器和算法。(重要的還有融合這二者的迭代器)

容器,即存放數據的地方。比如array等。

在STL中,容器分爲兩類:序列式容器和關聯式容器。

序列式容器,其中的元素不一定有序,但都可以被排序。如:vector、list、deque、stack、queue、heap、priority_queue、slist;

關聯式容器,內部結構基本上是一顆平衡二叉樹。所謂關聯,指每個元素都有一個鍵值和一個實值,元素按照一定的規則存放。如:RB-tree、set、map、multiset、multimap、hashtable、hash_set、hash_map、hash_multiset、hash_multimap。

下面各選取一個作爲說明。

vector:它是一個動態分配存儲空間的容器。區別於c++中的array,array分配的空間是靜態的,分配之後不能被改變,而vector會自動重分配(擴展)空間。

set:其內部元素會根據元素的鍵值自動被排序。區別於map,它的鍵值就是實值,而map可以同時擁有不同的鍵值和實值。

算法,如排序,複製……以及個容器特定的算法。這點不用過多介紹,主要看下面迭代器的內容。

迭代器是STL的精髓,我們這樣描述它:迭代器提供了一種方法,使它能夠按照順序訪問某個容器所含的各個元素,但無需暴露該容器的內部結構。它將容器和算法分開,好讓這二者獨立設計。

問7:數據結構會嗎?項目開發過程中主要用到那些?
答:數據結構中主要會用到數組,鏈表,樹(較少),也會用到棧和隊列的思想。

問8:const知道嗎?解釋其作用。
答:

1.const 修飾類的成員變量,表示成員常量,不能被修改。

2.const修飾函數承諾在本函數內部不會修改類內的數據成員,不會調用其它非 const 成員函數。

3.如果 const 構成函數重載,const 對象只能調用 const 函數,非 const 對象優先調用非 const 函數。

4.const 函數只能調用 const 函數。非 const 函數可以調用 const 函數。

5.類體外定義的 const 成員函數,在定義和聲明處都需要 const 修飾符。

問9:類的static變量在什麼時候初始化?函數的static變量在什麼時候初始化?
答:類的靜態成員變量在類實例化之前就已經存在了,並且分配了內存。函數的static變量在執行此函數時進行初始化。

問10:堆和棧的區別?堆和棧的生命週期?
答:

一、堆棧空間分配區別:

1、棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧;

2、堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。

二、堆棧緩存方式區別:

1、棧使用的是一級緩存, 他們通常都是被調用時處於存儲空間中,調用完畢立即釋放;

2、堆是存放在二級緩存中,生命週期由虛擬機的垃圾回收算法來決定(並不是一旦成爲孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。

三、堆棧數據結構區別:

堆(數據結構):堆可以被看成是一棵樹,如:堆排序;

棧(數據結構):一種先進後出的數據結構。

問11:C和C++的區別?
答:

C++在C的基礎上增添類

C是一個結構化語言,它的重點在於算法和數據結構。

C程序的設計首要考慮的是如何通過一個過程,對輸入(或環境條件)進行運算處理得到輸出(或實現過程(事務)控制),而對於C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通過獲取對象的狀態信息得到輸出或實現過程(事務)控制。

問12:解釋下封裝、繼承和多態?
答:

一、封裝:

封裝是實現面向對象程序設計的第一步,封裝就是將數據或函數等集合在一個個的單元中(我們稱之爲類)。

封裝的意義在於保護或者防止代碼(數據)被我們無意中破壞。

二、繼承:

繼承主要實現重用代碼,節省開發時間。

子類可以繼承父類的一些東西。

三、多態

多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。

問13:指針和引用的區別?
答:

  1. 指針是一個變量,只不過這個變量存儲的是一個地址,指向內存的一個存儲單元;而引用僅是個別名;

  2. 引用使用時無需解引用(*),指針需要解引用;

  3. 引用只能在定義時被初始化一次,之後不可變;指針可變;

  4. 引用沒有 const,指針有 const;

  5. 引用不能爲空,指針可以爲空;

  6. “sizeof 引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身的大小;

  7. 指針和引用的自增(++)運算意義不一樣;

  8. 指針可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)

9.從內存分配上看:程序爲指針變量分配內存區域,而引用不需要分配內存區域。

問14:什麼是內存泄漏?面對內存泄漏和指針越界,你有哪些方法?你通常採用哪些方法來避免和減少這類錯誤?
答:用動態存儲分配函數動態開闢的空間,在使用完畢後未釋放,結果導致一直佔據該內存單元即爲內存泄露。

使用的時候要記得指針的長度。

malloc的時候得確定在那裏free.

對指針賦值的時候應該注意被賦值指針需要不需要釋放.

動態分配內存的指針最好不要再次賦值.

問15:常用的排序算法有哪些?簡單描述幾個排序算法的優缺點?
答:選擇、冒泡、快速、希爾、歸併、堆排等。

1.快排:是冒泡排序的一種改進。

優點:快,數據移動少

缺點:穩定性不足

2.歸併:分治法排序,穩定的排序算法,一般用於對總體無序,但局部有序的數列。

優點:效率高O(n),穩定

缺點:比較佔用內存

問16:new和malloc的區別?
答:

1、malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。

2、對於非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。

3、由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。

4、C++程序經常要調用C函數,而C程序只能用malloc/free管理動態內存。

5、new可以認爲是malloc加構造函數的執行。new出來的指針是直接帶類型信息的。而malloc返回的都是void指針。

問17:TCP和UDP通信的差別?什麼是IOCP?
答:

1.TCP面向連接, UDP面向無連接的

2.TCP有保障的,UDP傳輸無保障的

3.TCP是效率低的,UDP效率高的

4.TCP是基於流的,UDP基於數據報文

5.TCP傳輸重要數據,UDP傳輸不重要的數據

IOCP全稱I/O Completion Port,中文譯爲I/O完成端口。

IOCP是一個異步I/O的API,它可以高效地將I/O事件通知給應用程序。

與使用select()或是其它異步方法不同的是,一個套接字[socket]與一個完成端口關聯了起來,然後就可繼續進行正常的Winsock操作了。然而,當一個事件發生的時候,此完成端口就將被操作系統加入一個隊列中。然後應用程序可以對核心層進行查詢以得到此完成端口。

問18:同步IO和異步IO的區別?
答:

A. 同步

所謂同步,就是在發出一個功能調用時,在沒有得到結果之前,該調用就不返回。

按照這個定義,其實絕大多數函數都是同步調用(例如sin isdigit等)。

但是一般而言,我們在說同步、異步的時候,特指那些需要其他部件協作或者需要一定時間完成的任務。

最常見的例子就是 SendMessage。

該函數發送一個消息給某個窗口,在對方處理完消息之前,這個函數不返回。

當對方處理完畢以後,該函數才把消息處理函數所返回的值返回給調用者。

B. 異步

異步的概念和同步相對。

當一個異步過程調用發出後,調用者不會立刻得到結果。

實際處理這個調用的部件是在調用發出後,通過狀態、通知來通知調用者,或通過回調函數處理這個調用。

問19:解釋C++中靜態函數和靜態變量?
答:

(1)類靜態數據成員在編譯時創建並初始化:在該類的任何對象建立之前就存在,不屬於任何對象,而非靜態類成員變量則是屬於對象所有的。類靜態數據成員只有一個拷貝,爲所有此類的對象所共享。

(2)類靜態成員函數屬於整個類,不屬於某個對象,由該類所有對象共享。

1、static 成員變量實現了同類對象間信息共享。

2、static 成員類外存儲,求類大小,並不包含在內。

3、static 成員是命名空間屬於類的全局變量,存儲在 data 區的rw段。

4、static 成員只能類外初始化。

5、可以通過類名訪問(無對象生成時亦可),也可以通過對象訪問。

問20:說下你對內存的瞭解?
答:

1.棧 - 由編譯器自動分配釋放

2.堆 - 一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收

3.全局區(靜態區),全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。- 程序結束釋放

4.另外還有一個專門放常量的地方。- 程序結束釋放

5 程序代碼區,存放2進制代碼。

在函數體中定義的變量通常是在棧上,用malloc, calloc, realloc等分配內存的函數分配得到的就是在堆上。在所有函數體外定義的是全局量,加了static修飾符後不管在哪裏都存放在全局區(靜態區),在所有函數體外定義的static變量表示在該文件中有效,不能extern到別的文件用,在函數體內定義的static表示只在該函數體內有效。另外,函數中的"adgfdf"這樣的字符串存放在常量區。

C++ 完全支持面向對象的程序設計,包括面向對象開發的四大特性:

封裝
數據隱藏
繼承
多態

C++ 標準模板庫的核心包括以下三個組件

容器(Containers) 容器是用來管理某一類對象的集合。C++ 提供了各種不同類型的容器,比如 deque、list、vector、map 等。
算法(Algorithms) 算法作用於容器。它們提供了執行各種操作的方式,包括對容器內容執行初始化、排序、搜索和轉換等操作。
迭代器(terators) 迭代器用於遍歷對象集合的元素。這些集合可能是容器,也可能是容器的子集。

容器,即存放數據的地方。比如array等。

在STL中,容器分爲兩類:序列式容器和關聯式容器。

序列式容器,其中的元素不一定有序,但都可以被排序。如:vector、list、deque、stack、queue、heap、priority_queue、slist;

關聯式容器,內部結構基本上是一顆平衡二叉樹。所謂關聯,指每個元素都有一個鍵值和一個實值,元素按照一定的規則存放。如:RB-tree、set、map、multiset、multimap、hashtable、hash_set、hash_map、hash_multiset、hash_multimap。

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