1.在C++ 程式中調用被C 編譯器編譯後的函數,為什麼要加extern “C”?答:首先,extern是C/C++語言中表明函數和全局變數作用範圍的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變數可以在本模塊或其它模塊中使用。通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數和全局變數以關鍵字e ...
1.在C++ 程式中調用被C 編譯器編譯後的函數,為什麼要加extern “C”?
答:首先,extern是C/C++語言中表明函數和全局變數作用範圍的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變數可以在本模塊或其它模塊中使用。
通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數和全局變數以關鍵字extern聲明。extern "C"是連接申明(linkage declaration),被extern "C"修飾的變數和函數是按照C語言方式編譯和連接的。作為一種面向對象的語言,C++支持函數重載,而過程式語言C則不支持。函數被C++編譯後在符號庫中的名字與C語言的不同。例如,假設某個函數的原型為:void foo( int x, int y );該函數被C編譯器編譯後在符號庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字。這樣的名字包含了函數名、函數參數數量及類型信息,C++就是靠這種機制來實現函數重載的。
所以,可以用一句話概括extern “C”這個聲明的真實目的:解決名字匹配問題,實現C++與C的混合編程。
2.頭文件中的ifndef/define/endif有什麼作用?
答:這是C++預編譯頭文件保護符,保證即使文件被多次包含,頭文件也只定義一次。
3. #include<file.h> 與 #include "file.h"的區別?
答:前者是從標準庫路徑尋找和引用file.h,而後者是從當前工作路徑搜尋並引用file.h。
4.評價一下C/C++各自的特點
答:C語言是一種結構化語言,面向過程,基於演算法和數據結構,所考慮的是如何通過一個過程或者函數從輸入得到輸出;
C++是面向對象,基於類、對象和繼承,所考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題,通過獲取對象的狀態信息得到輸出或實現過程式控制制。
5.const 有什麼用途?
答:在C/C++中,(1)可以定義const常量,(2)修飾函數的返回值和形參;
在C++中,還可以修飾函數的定義體,定義類的const成員函數。被const修飾的東西受到強制保護,可以預防意外的變動,提高了程式的健壯性。
6.const和#define有什麼區別?
答:(1)const和#define都可以定義常量,但是const用途更廣。
(2)const 常量有數據類型,而巨集常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對後者只進行字元替換,沒有類型安全檢查,並且在字元替換可能會產生意料不到的錯誤。
(3) 有些集成化的調試工具可以對const 常量進行調試,但是不能對巨集常量進行調試。
7.關於sizeof小結的。
答:sizeof計算的是在棧中分配的記憶體大小。
(1) sizeof不計算static變數占得記憶體;
(2) 指針的大小一定是4個位元組,而不管是什麼類型的指針;
(3) char型占1個位元組,int占4個位元組,short int占2個位元組
long int占4個位元組,float占4位元組,double占48位元組,string占4位元組
一個空類占1個位元組,單一繼承的空類占1個位元組,虛繼承涉及到虛指針所以占4個位元組
(4) 數組的長度:
若指定了數組長度,則不看元素個數,總位元組數=數組長度*sizeof(元素類型)
若沒有指定長度,則按實際元素個數類確定
Ps:若是字元數組,則應考慮末尾的空字元。
http://hovertree.com/h/bjaf/hg4nhf1w.htm
(5) 結構體對象的長度
在預設情況下,為方便對結構體內元素的訪問和管理,當結構體內元素長度小於處理器位數的時候,便以結構體內最長的數據元素的長度為對齊單位,即為其整數倍。若結構體內元素長度大於處理器位數則以處理器位數為單位對齊。
(6) unsigned影響的只是最高位的意義,數據長度不會改變,所以sizeof(unsigned int)=4
(7) 自定義類型的sizeof取值等於它的類型原型取sizeof
(8) 對函數使用sizeof,在編譯階段會被函數的返回值的類型代替
(9) sizeof後如果是類型名則必須加括弧,如果是變數名可以不加括弧,這是因為sizeof是運算符
(10) 當使用結構類型或者變數時,sizeof返回實際的大小。當使用靜態數組時返回數組的全部大小,sizeof不能返回動態數組或者外部數組的尺寸
8.sizeof與strlen的區別?
答: (1)sizeof的返回值類型為size_t(unsigned int);
(2)sizeof是運算符,而strlen是函數;
(3)sizeof可以用類型做參數,其參數可以是任意類型的或者是變數、函數,而strlen只能用char*做參數,且必須是以’\0’結尾;
(4)數組作sizeof的參數時不會退化為指針,而傳遞給strlen是就退化為指針;
(5)sizeo是編譯時的常量,而strlen要到運行時才會計算出來,且是字元串中字元的個數而不是記憶體大小;
9.指針和引用的區別?
答:指針和引用都提供了間接操作對象的功能。
(1) 指針定義時可以不初始化,而引用在定義時就要初始化,和一個對象綁定,而且一經綁定,只要引用存在,就會一直保持和該對象的綁定;
(2) 賦值行為的差異:指針賦值是將指針重新指向另外一個對象,而引用賦值則是修改對象本身;
(3) 指針之間存在類型轉換,而引用分const引用和非const應用,非const引用只能和同類型的對象綁定,const引用可以綁定到不同但相關類型的對象或者右值
10.數組和指針的區別?
答:(1)數組要麼在全局數據區被創建,要麼在棧上被創建;指針可以隨時指向任意類型的記憶體塊;
(2)修改內容上的差別:
char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 註意p 指向常量字元串
p[0] = ‘X’; // 編譯器不能發現該錯誤,運行時錯誤
(3)用運算符sizeof 可以計算出數組的容量(位元組數)。sizeof(p),p 為指針得到的是一個指針變數的位元組數,而不是p 所指的記憶體容量。C++/C 語言沒有辦法知道指針所指的記憶體容量,除非在申請記憶體時記住它。註意當數組作為函數的參數進行傳遞時,該數組自動退化為同類型的指針。
11.空指針和懸垂指針的區別?
答:空指針是指被賦值為NULL的指針;delete指向動態分配對象的指針將會產生懸垂指針。
(1) 空指針可以被多次delete,而懸垂指針再次刪除時程式會變得非常不穩定;
(2) 使用空指針和懸垂指針都是非法的,而且有可能造成程式崩潰,如果指針是空指針,儘管同樣是崩潰,但和懸垂指針相比是一種可預料的崩潰。
12.C++中有malloc/free,為什麼還有new/delete?
答:malloc/free是C/C++標準庫函數,new/delete是C++運算符。他們都可以用於動態申請和釋放記憶體。
對於內置類型數據而言,二者沒有多大區別。malloc申請記憶體的時候要制定分配記憶體的位元組數,而且不會做初始化;new申請的時候有預設的初始化,同時可以指定初始化;
對於類類型的對象而言,用malloc/free無法滿足要求的。對象在創建的時候要自動執行構造函數,消亡之前要調用析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制之內,不能把執行構造函數和析構函數的任務強加給它,因此,C++還需要new/delete。
13.什麼是智能指針?
答:當類中有指針成員時,一般有兩種方式來管理指針成員:一是採用值型的方式管理,每個類對象都保留一份指針指向的對象的拷貝;另一種更優雅的方式是使用智能指針,從而實現指針指向的對象的共用。
智能指針的一種通用實現技術是使用引用計數。智能指針類將一個計數器與類指向的對象相關聯,引用計數跟蹤該類有多少個對象共用同一指針。
每次創建類的新對象時,初始化指針並將引用計數置為1;當對象作為另一對象的副本而創建時,拷貝構造函數拷貝指針並增加與之相應的引用計數;對一個對象進行賦值時,賦值操作符減少左操作數所指對象的引用計數(如果引用計數為減至0,則刪除對象),並增加右操作數所指對象的引用計數;調用析構函數時,構造函數減少引用計數(如果引用計數減至0,則刪除基礎對象)。
14.面向對象技術的基本概念是什麼,三個基本特征是什麼?
答:基本概念:類、對象、繼承; 基本特征:封裝、繼承、多態。
封裝:將低層次的元素組合起來形成新的、更高實體的技術;
繼承:廣義的繼承有三種實現形式:實現繼承、可視繼承、介面繼承。
多態:允許將子類類型的指針賦值給父類類型的指針
15.C++空類預設有哪些成員函數?
答:預設構造函數、析構函數、複製構造函數、賦值函數
16.哪一種成員變數可以在一個類的實例之間共用?
答:static靜態成員變數
17.繼承層次中,為什麼基類析構函數是虛函數?
答:編譯器總是根據類型來調用類成員函數。但是一個派生類的指針可以安全地轉化為一個基類的指針。這樣刪除一個基類的指針的時候,C++不管這個指針指向一個基類對象還是一個派生類的對象,調用的都是基類的析構函數而不是派生類的。如果你依賴於派生類的析構函數的代碼來釋放資源,而沒有重載析構函數,那麼會有資源泄漏。
18.為什麼構造函數不能為虛函數?
答:虛函數採用一種虛調用的方法。需調用是一種可以在只有部分信息的情況下工作的機制。如果創建一個對象,則需要知道對象的準確類型,因此構造函數不能為虛函數。
19.如果虛函數是有效的,那為什麼不把所有函數設為虛函數?
答:不行。首先,虛函數是有代價的,由於每個虛函數的對象都要維護一個虛函數表,因此在使用虛函數的時候都會產生一定的系統開銷,這是沒有必要的。
20.構造函數可以是內聯函數
21.什麼是多態?多態有什麼作用?
答:多態就是將基類類型的指針或者引用指向派生類型的對象。多態通過虛函數機制實現。
多態的作用是介面重用。
22.重載和覆蓋有什麼區別?
答:虛函數是基類希望派生類重新定義的函數,派生類重新定義基類虛函數的做法叫做覆蓋;
重載就在允許在相同作用域中存在多個同名的函數,這些函數的參數表不同。重載的概念不屬於面向對象編程,編譯器根據函數不同的形參表對同名函數的名稱做修飾,然後這些同名函數就成了不同的函數。
重載的確定是在編譯時確定,是靜態的;虛函數則是在運行時動態確定。
23.公有繼承、受保護繼承、私有繼承
答:(1)公有繼承時,派生類對象可以訪問基類中的公有成員,派生類的成員函數可以訪問基類中的公有和受保護成員;
(2)私有繼承時,基類的成員只能被直接派生類的成員訪問,無法再往下繼承;
(3)受保護繼承時,基類的成員也只被直接派生類的成員訪問,無法再往下繼承。
24.公有繼承時基類受保護的成員,可以通過派生類對象訪問但不能修改。
25.有哪幾種情況只能用構造函數初始化列表而不能用賦值初始化?
答:const成員,引用成員
26.什麼是虛指針?
答:虛指針或虛函數指針是虛函數的實現細節。帶有虛函數的每一個對象都有一個虛指針指向該類的虛函數表。
27.C++如何阻止一個類被實例化?一般在什麼時候將構造函數聲明為private?
答:(1)將類定義為抽象基類或者將構造函數聲明為private;
(2)不允許類外部創建類對象,只能在類內部創建對象
28.main函數執行之前會執行什麼?執行之後還能執行代碼嗎?
答:(1)全局對象的構造函數會在main函數之前執行;
(2)可以,可以用_onexit 註冊一個函數,它會在main 之後執行;
如果你需要加入一段在main退出後執行的代碼,可以使用atexit()函數,註冊一個函數。
語法:
#include <stdlib.h>
#include <stdio.h>
int atexit(void (*function")(void));
void fn1( void ), fn2( void ), fn3( void );
int main( void )
{
atexit(fn1);
atexit( fn2 );
printf( "This is executed first.\n" );
}
void fn1()
{
printf( " This is\n" );
}
void fn2()
{
printf( " executed next." );
}
結果:
This is executed first.
This is executed next.
29.請描述進程和線程的區別?
答:(1)進程是程式的一次執行,線程是進程中的執行單元;
(2)進程間是獨立的,這表現在記憶體空間、上下文環境上,線程運行在進程中;
(3)一般來講,進程無法突破進程邊界存取其他進程內的存儲空間;而同一進程所產生的線程共用記憶體空間;
(4)同一進程中的兩段代碼不能同時執行,除非引入多線程。
30.進程間如何通信?
答:信號、信號量、消息隊列、共用記憶體
31.在網路編程中涉及併發伺服器,使用多進程與多線程的區別?
答:(1)線程執行開銷小,但不利於資源管理和保護;進程則相反,進程可跨越機器遷移。
(2)多進程時每個進程都有自己的記憶體空間,而多線程間共用記憶體空間;
(3)線程產生的速度快,線程間通信快、切換快;
(4)線程的資源利用率比較好;
(5)線程使用公共變數或者資源時需要同步機制。
32.說一下TCP 3次握手、4次揮手的全過程。
33.TCP和UDP有什麼區別。
答:
TCP——傳輸控制協議,提供的是面向連接、可靠的位元組流服務。
當客戶和伺服器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之後才能傳輸數據。TCP提供超時重發,丟棄重覆數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。
UDP——用戶數據報協議,是一個簡單的面向數據報的傳輸層協議。UDP不提供可靠性,它只是把應用程式傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和伺服器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快.
TCP協議和UDP協議的一些特性區別如下:
1.TCP協議在傳送數據段的時候要給段標號;UDP 協議不需要。
2.TCP協議可靠;UDP協議不可靠。
3.TCP協議是面向連接;UDP協議採用無連接。
4.TCP協議負載較高,採用虛電路;UDP協議低負載。
5.TCP協議的發送方要確認接受方是否收到數據段(3次握手協議)。
6.TCP協議採用視窗技術和流控制。
34.如何編寫套接字?
35.調用函數時要進行參數壓棧,一般情況下順序是從最右邊參數往左壓棧。
36.經常要操作的記憶體分為那幾個類別?
答:(1)棧區:由編譯器自動分配和釋放,存放函數的參數值、局部變數的值等;
(2)堆:一般由程式員分配和釋放,存放動態分配的變數;
(3)全局區(靜態區):全局變數和靜態變數存放在這一塊,初始化的和未初始化的分開放;
(4)文字常量區:常量字元串就放在這裡,程式結束自動釋放;
(5)程式代碼區:參訪函數體的二進位代碼。
37.請講述堆和棧的區別。
答:(1)申請方式不同。棧上有系統自動分配和釋放;堆上有程式員自己申請並指明大小;
(2)棧是向低地址擴展的數據結構,大小很有限;堆是向高地址擴展,是不連續的記憶體區域,空間相對大且靈活;
(3)棧由系統分配和釋放速度快;堆由程式員控制,一般較慢,且容易產生碎片;
38.全局變數放在數據段,內部變數static int count;放在數據段,內部變數char *p=“AAA”,p的位置在堆棧上,指向的空間的位置數據段,內部變數char *p=new char;p的位置堆,指向的空間的位置數據段
39.字元數組與字元串的比較:最明顯的區別是字元串會在末尾自動添加空字元。
40.函數指針相關概念(C++學習筆記)
41.類使用static成員的優點,如何訪問?
答:優點:
(1)static 成員的名字是在類的作用域中,因此可以避免與其他類的成員或全局對象名字衝突;
(2)可以實施封裝。static 成員可以是私有成員,而全局對象不可以;
(3) static 成員是與特定類關聯的,可清晰地顯示程式員的意圖。
static 數據成員必須在類定義體的外部定義(正好一次),static 關鍵字只能用於類定義體內部的聲明中,定義不能標示為static. 不像普通數據成員,static成員不是通過類構造函數進行初始化,也不能在類的聲明中初始化,而是應該在定義時進行初始化.保證對象正好定義一次的最好辦法,就是將static 數據成員的定義放在包含類非內聯成員函數定義的文件中。
靜態數據成員初始化的格式為:
<數據類型><類名>::<靜態數據成員名>=<值>
類的靜態數據成員有兩種訪問形式:
<類對象名>.<靜態數據成員名> 或 <類類型名>::<靜態數據成員名>
42. static數據成員和static成員函數
答:(1)static數據成員:
static數據成員獨立於該類的任意對象而存在;每個static數據成員是與類關聯的對象,並不與該類的對象相關聯。Static數據成員(const static數據成員除外)必須在類定義體的外部定義。不像普通數據成員,static成員不是通過類的構造函數進行初始化,而是應該在定義時進行初始化。
(2)static成員函數:
Static成員函數沒有this形參,它可以直接訪問所屬類的static成員,不能直接使用非static成員。因為static成員不是任何對象的組成部分,所以static成員不能被聲明為const。同時,static成員函數也不能被聲明為虛函數。
43.static成員變數定義放在cpp文件中,不能放在初始化列表中。Const static成員可就地初始化。
44.如何引用一個已經定義過的全局變數?
答:可以用引用頭文件的方式,也可以用extern關鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變數,假定你將那個變數寫錯了,那麼在編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那麼在編譯期間不會報錯,而在連接期間報錯。
44.static關鍵字的作用。
答:static總是使得變數或對象的存儲形式變成靜態存儲,連接方式變成內部連接,對於局部變數(已經是內部連接了),它僅改變其存儲方式;對於全局變數(已經是靜態存儲了),它僅改變其連接類型。
45.奈奎斯特定理
46.香農定理
47.多態類中的虛函數表是 Compile-Time,還是 Run-Time時建立的?
答案:虛擬函數表是在編譯期就建立了,各個虛擬函數這時被組織成了一個虛擬函數的入口地址的數組。而對象的隱藏成員--虛擬函數表指針是在運行期--也就是構造函數被調用時進行初始化的,這是實現多態的關鍵。
48. 一個父類寫了一個 virtual 函數,如果子類覆蓋它的函數不加 virtual ,也能實現多態?
在子類的空間里,有沒有父類的這個函數,或者父類的私有變數? (華為筆試題)
答案:只要基類在定義成員函數時已經聲明瞭 virtue關鍵字,在派生類實現的時候覆蓋該函數時,virtue關鍵字可加可不加,不影響多態的實現。子類的空間里有父類的所有變數(static除外)。
49. 完成字元串拷貝可以使用 sprintf、strcpy 及 memcpy 函數,請問這些函數有什麼區別
,你喜歡使用哪個,為什麼?
答案:這些函數的區別在於 實現功能以及操作對象不同。
(1)strcpy 函數操作的對象是字元串,完成從源字元串到目的字元串的拷貝功能。
(2)sprintf 函數操作的對象不限於字元串:雖然目的對象是字元串,但是源對象可以是字元串、也可以是任意基本類型的數據。這個函數主要用來實現(字元串或基本數據類型)向字元串的轉換功能。如果源對象是字元串,並且指定 %s 格式符,也可實現字元串拷貝功能。
(3)memcpy 函數顧名思義就是記憶體拷貝,實現將一個記憶體塊的內容複製到另一個記憶體塊這一功能。記憶體塊由其首地址以及長度確定。程式中出現的實體對象,不論是什麼類型,其最終表現就是在記憶體中占據一席之地(一個記憶體區間或塊)。因此,memcpy 的操作對象不局限於某一類數據類型,或者說可適用於任意數據類型,只要能給出對象的起始地址和記憶體長度信息、並且對象具有可操作性即可。鑒於memcpy 函數等長拷貝的特點以及數據類型代表的物理意義,memcpy 函數通常限於同種類型數據或對象之間的拷貝,其中當然也包括字元串拷貝以及基本數據類型的拷貝。
對於字元串拷貝來說,用上述三個函數都可以實現,但是其實現的效率和使用的方便程度不同:
• strcpy 無疑是最合適的選擇:效率高且調用方便。
• sprintf 要額外指定格式符並且進行格式轉化,麻煩且效率不高。
• memcpy 雖然高效,但是需要額外提供拷貝的記憶體長度這一參數,易錯且使用不便;並且如果長度指定過大的話(最優長度是源字元串長度 + 1),還會帶來性能的下降。其實 strcpy 函數一般是在內部調用 memcpy 函數或者用彙編直接實現的,以達到高效的目的。因此,使用 memcpy 和 strcpy 拷貝字元串在性能上應該沒有什麼大的差別。
對於非字元串類型的數據的複製來說,strcpy 和 snprintf 一般就無能為力了,可是對 memcpy 卻沒有什麼影響。但是,對於基本數據類型來說,儘管可以用 memcpy 進行拷貝,由於有賦值運算符可以方便且高效地進行同種或相容類型的數據之間的拷貝,所以這種情況下 memcpy 幾乎不被使用 。memcpy 的長處是用來實現(通常是內部實現居多)對結構或者數組的拷貝,其目的是或者高效,或者使用方便,甚或兩者兼有。
50. 應用程式在運行時的記憶體包括代碼區和數據區,其中數據區又包括哪些部分?
答:對於一個進程的記憶體空間而言,可以在邏輯上分成 3個部份:代碼區,靜態數據區和動態數據區。
動態數據區一般就是“堆棧”。 棧是一種線性結構,堆是一種鏈式結構。進程的每個線程都有私有的“棧”。
全局變數和靜態變數分配在靜態數據區,本地變數分配在動態數據區,即堆棧中。程式通過堆棧的基地址和偏移量來訪問本地變數。
51. C++函數中值的傳遞方式有哪幾種?
答:三種傳遞方式為:值傳遞、指針傳遞和引用傳遞。
推擠:http://www.cnblogs.com/roucheng/p/3456005.html
52. C++裡面是不是所有的動作都是main()引起的?如果不是,請舉例.
比如全局變數的初始化,就不是由main函數引起的
舉例: class A{};
A a; //a的構造函數限執行
int main() {}
53. 下列哪兩個是等同的
int b;
A const int* a = &b;
B const* int a = &b;
C const int* const a = &b;
D int const* const a = &b;
54. 內聯函數在編譯時是否做參數類型檢查?
答:內聯函數要做參數類型檢查, 這是內聯函數跟巨集相比的優勢。
55. 全局變數和局部變數有什麼區別?實怎麼實現的?操作系統和編譯器是怎麼知道的?
(1)生命周期不同:
全局變數隨主程式創建和創建,隨主程式銷毀而銷毀
局部變數在局部函數內部,甚至局部迴圈體等內部存在,退出就不存在; 記憶體中
分配在全局數據區
(2)使用方式不同:通過聲明後全局變數程式的各個部分都可以用到;局部變數只能在局部使用,分配在棧區
操作系統和編譯器通過記憶體分配的位置來知道的,全局變數分配在全局數據段並且在程式開始運行的時候被載入。局部變數則分配在堆棧裡面 。
56. 有 A 、 B 、 C 、 D 四個人,要在夜裡過一座橋。他們通過這座橋分別需要耗時 1 、 2 、 5 、 10 分鐘,只有一支手電筒,並且同時最多只能兩個人一起過橋。請問,如何安排,能夠在 17 分鐘內這四個人都過橋?
Solution:關鍵是時間最長的兩個人必須同時過橋
The First Time : A(1) 和 B(2) 過橋, A(1) 返回 Cost : 1+2
The Second Time : C(5) 和 D(10) 過橋, B(2) 返回 Cost : 10+2
The Third Time A(1) 和 B(2) 過橋 Cost : 2
Total Time Cost : (1+2)+(10+2)+2=17 minutes
57. static全局變數與普通的全局變數有什麼區別?static局部變數和普通局部變數有什麼區別?static函數與普通函數有什麼區別?
答:static全局變數與普通全局變數區別:static全局變數只初使化一次,防止在其他文件單元中被引用;
static局部變數和普通局部變數區別:static局部變數只被初始化一次,下一次依據上一次結果值;
static函數與普通函數區別:static函數在記憶體中只有一份,普通函數在每個被調用中維持一份拷貝。
58. 程式的局部變數存在於(堆棧)中,全局變數存在於(靜態區 )中,動態申請數據存在於( 堆)中。
59. 對於一個頻繁使用的短小函數,在C語言中應用什麼實現,在C++中應用什麼實現?
c用巨集定義,c++用inline
60. 有1,2,....一直到n的無序數組,求排序演算法,並且要求時間複雜度為O(n),空間複雜度O(1),使用交換,而且一次只能交換兩個數。
#include<iostream.h> Using namespace std; int main(){ int a[] = {10,6,9,5,2,8,4,7,1,3}; int len = sizeof(a) / sizeof(int); int temp; for(int i = 0; i < len; ) { temp = a[a[i] - 1]; a[a[i] - 1] = a[i]; a[i] = temp; if ( a[i] == i + 1) i++; } for (int j = 0; j < len; j++) cout<<a[j]<<","; return 0; } // by 何問起 hovertree.com
轉自:http://hovertree.com/h/bjaf/cppmianshi.htm