ZERO 筆試

1.大多考到了 計算機網絡 tcpip  和  操做系統 多線程的知識  直接 懵逼html

2.  考到了 遞歸的全排列ios

#include<iostream>  
using namespace std;  
  
void swap(int &a,int &b)  
{  
      int temp ;  
      temp=a;  
      a=b;  
      b=temp;  
}  
void show(int a[],int n) //顯示所有數組    
{  
                for(int i=0;i<n;i++ )  
           {  
               cout<<a[i]<<"  ";  
           }  
           cout<<endl;  
}  
void prim(int a[],int k, int n)  //n是這個a[]中有多少個元素 ,k是a[]須要全排列的的坐下標  
{   
     if(k==n-1)//不是隻有一個元素 而是全排列到最後一個數字時   終止遞歸的條件  
     {  
           show(a,n);  
     }  
     else   
     {  
         for(int i=k;i<n;i++)  //從k開始時保證交換和遞歸次數     
         {  
                  swap(a[i],a[k]);   //第一次 本身和本身交換即本身是最前單一前綴   交換單一前綴和後綴中的每個元素 ,讓每個元素均可以作前綴  
              prim(a,k+1,n);  
              swap(a[i],a[k]);  //回溯以後  仍然恢復交換之前的順序  
         }  
     }  
}  
  
int main(int argc, char* argv[])  
{  
        int  a[3]={1,2,3};  
        prim(a,0,3);  
    system("PAUSE");  
    return 0;  
}  

  若是 只有兩個  [1,2]的話 我是看懂了  c++

3.多態  繼承  和 封裝算法

http://blog.csdn.net/ruyue_ruyue/article/details/8211809編程

C++封裝繼承多態總結數組

面向對象的三個基本特徵網絡

面向對象的三個基本特徵是:封裝、繼承、多態。其中,封裝能夠隱藏實現細節,使得代碼模塊化;繼承能夠擴展已存在的代碼模塊(類);它們的目的都是爲了——代碼重用。而多態則是爲了實現另外一個目的——接口重用!數據結構

 

封裝                                                                                                                                                                   多線程

什麼是封裝?tcp

封裝能夠隱藏實現細節,使得代碼模塊化;封裝是把過程和數據包圍起來,對數據的訪問只能經過已定義的界面。面向對象計算始於這個基本概念,即現實世界能夠被描繪成一系列徹底自治、封裝的對象,這些對象經過一個受保護的接口訪問其餘對象。在面向對象編程上可理解爲:把客觀事物封裝成抽象的類,而且類能夠把本身的數據和方法只讓可信的類或者對象操做,對不可信的進行信息隱藏。

繼承                                                                                                                                                                      

什麼是繼承?

繼承是指這樣一種能力:它可使用現有類的全部功能,並在無需從新編寫原來的類的狀況下對這些功能進行擴展。其繼承的過程,就是從通常到特殊的過程。

經過繼承建立的新類稱爲「子類」或「派生類」。被繼承的類稱爲「基類」、「父類」或「超類」。要實現繼承,能夠經過「繼承」(Inheritance)和「組合」(Composition)來實現。在某些 OOP 語言中,一個子類能夠繼承多個基類。可是通常狀況下,一個子類只能有一個基類,要實現多重繼承,能夠經過多級繼承來實現。

繼承的實現方式?

繼承概念的實現方式有三類:實現繼承、接口繼承和可視繼承。

1. 實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;

2. 接口繼承是指僅使用屬性和方法的名稱、可是子類必須提供實現的能力;

3. 可視繼承是指子窗體(類)使用基窗體(類)的外觀和實現代碼的能力。

多態                                                                                                                                             

什麼是多態?

多態性(polymorphisn)是容許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值以後,父對象就能夠根據當前賦值給它的子對象的特性以不一樣的方式運做。簡單的說,就是一句話:容許將子類類型的指針賦值給父類類型的指針。

例子:(2012某**軟件公司筆試題)

請按順序寫出下面代碼的輸出結果:

 

答案:call child func

call ~child

call ~base

多態的實現方式分析?

實現多態,有二種方式,覆蓋,重載。覆蓋:是指子類從新定義父類的虛函數的作法。重載:是指容許存在多個同名函數,而這些函數的參數表不一樣(或許參數個數不一樣,或許參數類型不一樣,或許二者都不一樣)。

分析:

「重載」是指在同一個類中相同的返回類型和方法名,可是參數的個數和類型能夠不一樣

「覆蓋\重寫」是在不一樣的類中。

其實,重載的概念並不屬於「面向對象編程」,重載的實現是:編譯器根據函數不一樣的參數表,對同名函數的名稱作修飾,而後這些同名函數就成了不一樣的函數(至少對於編譯器來講是這樣的)。如,有兩個同名函數:function func(p:integer):integer;和function func(p:string):integer;。那麼編譯器作過修飾後的函數名稱多是這樣的:int_func、str_func。對於這兩個函數的調用,在編譯器間就已經肯定了,是靜態的(記住:是靜態)。也就是說,它們的地址在編譯期就綁定了(早綁定),所以,重載和多態無關!真正和多態相關的是「覆蓋」。當子類從新定義了父類的虛函數後,父類指針根據賦給它的不一樣的子類指針,動態(記住:是動態!)的調用屬於子類的該函數,這樣的函數調用在編譯期間是沒法肯定的(調用的子類的虛函數的地址沒法給出)。所以,這樣的函數地址是在運行期綁定的(晚邦定)。結論就是:重載只是一種語言特性,與多態無關,與面向對象也無關!引用一句Bruce Eckel的話:「不要犯傻,若是它不是晚邦定,它就不是多態。」

C++多態機制的實現:

該部分轉自:http://blog.chinaunix.net/uid-7396260-id-2056657.html

一、c++實現多態的方法

面向對象有了一個重要的概念就是對象的實例,對象的實例表明一個具體的對象,故其確定有一個數據結構保存這實例的數據,這一數據包括對象成員變量,若是對象有虛函數方法或存在虛繼承的話,則還有相應的虛函數或虛表指針,其餘函數指針不包括。

虛函數在c++中的實現機制就是用虛表和虛指針,可是具體是怎樣的呢?從more effecive c++其中一篇文章裏面能夠知道:是每一個類用了一個虛表,每一個類的對象用了一個虛指針。要講虛函數機制,必須講繼承,由於只有繼承纔有虛函數的動態綁定功能,先講下c++繼承對象實例內存分配基礎知識:

從more effecive c++其中一篇文章裏面能夠知道:是每一個類用了一個虛表,每一個類的對象用了一個虛指針。具體的用法以下:
class A
{public:
    virtual void f();
    virtual void g();
private:
    int a
};

class B : public A
{
public:
    void g();
private:
    int b;
};
//A,B的實現省略
由於A有virtual void f(),和g(),因此編譯器爲A類準備了一個虛表vtableA,內容以下:

 

A::f 的地址

A::g 的地址

B由於繼承了A,因此編譯器也爲B準備了一個虛表vtableB,內容以下:

A::f 的地址

B::g 的地址

注意:由於B::g是重寫了的,因此B的虛表的g放的是B::g的入口地址,可是f是從上面的A繼承下來的,因此f的地址是A::f的入口地址。而後某處有語句 B bB;的時候,編譯器分配空間時,除了A的int a,B的成員int b;之外,還分配了一個虛指針vptr,指向B的虛表vtableB,bB的佈局以下:

vptr : 指向B的虛表vtableB

int a: 繼承A的成員

int b: B成員


當以下語句的時候:
A *pa = &bB;
pa的結構就是A的佈局(就是說用pa只能訪問的到bB對象的前兩項,訪問不到第三項int b)
那麼pa->g()中,編譯器知道的是,g是一個聲明爲virtual的成員函數,並且其入口地址放在表格(不管是vtalbeA表仍是vtalbeB表)的第2項,那麼編譯器編譯這條語句的時候就如是轉換:call *(pa->vptr)[1](C語言的數組索引從0開始哈~)。
這一項放的是B::g()的入口地址,則就實現了多態。(注意bB的vptr指向的是B的虛表vtableB)
另外要注意的是,如上的實現並非惟一的,C++標準只要求用這種機制實現多態,至於虛指針vptr到底放在一個對象佈局的哪裏,標準沒有要求,每一個編譯器本身決定。我以上的結果是根據g++ 4.3.4通過反彙編分析出來的。
二、兩種多態實現機制及其優缺點

除了c++的這種多態的實現機制以外,還有另一種實現機制,也是查表,不過是按名稱查表,是smalltalk等語言的實現機制。這兩種方法的優缺點以下:
(1)、按照絕對位置查表,這種方法因爲編譯階段已經作好了索引和表項(如上面的call *(pa->vptr[1]) ),因此運行速度比較快;缺點是:當A的virtual成員比較多(好比1000個),而B重寫的成員比較少(好比2個),這種時候,B的vtableB的剩下的998個表項都是放A中的virtual成員函數的指針,若是這個派生體系比較大的時候,就浪費了不少的空間。
好比:GUI庫,以MFC庫爲例,MFC有不少類,都是一個繼承體系;並且不少時候每一個類只是一、2個成員函數須要在派生類重寫,若是用C++的虛函數機制,每一個類有一個虛表,每一個表裏面有大量的重複,就會形成空間利用率不高。因而MFC的消息映射機制不用虛函數,而用第二種方法來實現多態,那就是:
(2)、按照函數名稱查表,這種方案能夠避免如上的問題;可是因爲要比較名稱,有時候要遍歷全部的繼承結構,時間效率性能不是很高。(關於MFC的消息映射的實現,看下一篇文章)
3、總結:
若是繼承體系的基類的virtual成員很少,並且在派生類要重寫的部分佔了其中的大多數時候,用C++的虛函數機制是比較好的;可是若是繼承體系的基類的virtual成員不少,或者是繼承體系比較龐大的時候,並且派生類中須要重寫的部分比較少,那就用名稱查找表,這樣效率會高一些,不少的GUI庫都是這樣的,好比MFC,QT
PS 其實,自從計算機出現以後,時間和空間就成了永恆的主題,由於二者在98%的狀況下都沒法協調,此長彼消;這個就是計算機科學中的根本瓶頸之所在。軟件科學和算法的發展,就看能不能突破這對時空權衡了。呵呵
何止計算機科學如此,整個宇宙又未嘗不是如此呢?最基本的宇宙之謎,仍是時間和空間~

 

16進制 轉 字符串數組  基本思路是這樣子的,也考到了

 

#include<iostream>
using namespace std;

int strOne(char * dest, char *src){
int x,y;
dest[0] = '0';
dest[1] = 'x';
x = (int)src[0] / 16;
y = (int)src[0] % 16;
dest[2] = (x>=10)?('A'+x-10):('0'+ x);
dest[3] = (y>=10)?('X'+y-10):('0'+ y);
}
int main(int argc, char* argv[])
{
char ss[2]={0x11,0x22};
char pp[100] = {0};
strOne(pp,ss);
cout<<pp<<endl;
system("PAUSE");
return 0;
}

在平常工做中經常要進行字符串的複製工做,而strcpy是你們經常使用的字符串複製函數,如今要詳細地說明這個函數可能帶來的錯誤,並給個人使用心得。

首先,看看MSDN怎麼說:

strcpy

      原型:char   *strcpy(char   *dest,char   *src);   

      用法:#include  <string.h>  

      功能:把src所指由NULL結束的字符串複製到dest所指的數組中。   

      說明:src和dest所指內存區域不能夠重疊且dest必須有足夠的空間來容納src的字符串。  

 返回指向dest的指針。

strcpy只是複製字符串,但不限制複製的數量。很容易形成緩衝溢出,也就是說,不過dest有沒有足夠的空間來容納src的字符串,它都會把src指向的字符串所有複製到從dest開始的內存,舉例說明:

容易形成的後果。

相關文章
相關標籤/搜索