從C轉入C++ (轉)
從C轉入C++ (轉)[@more@]
C++是C的超集(C的副檔名一般為.CPP),在大都分時候,C可在C++下執行,但有時會有問題,主要有以下幾點:
- 在C++中可用//表示該符號後面為註釋,如:
void main() //這是主 - 在C中以可用以下識別符號,但在C++中它們是關鍵字: asm bed_cast bad_typeid catch class const_cast delete dymanic_cast except finally friend inline namespace new operator private protected public reinterpret_cast static_cast template this throw try type_info typeid using virtual xalloc
- 在C中,可在前面無宣告和定義時,函式(雖會警告). 但在C++中,任何函式在呼叫前必須宣告或定義.
- 在C中宣告函式時,可不帶引數,如:
int FuncA();//實際可能有幾個引數
而在C++中這僅能中明無引數的函式。 - 在C中可用舊式的函式定義如:
int FuncA(x,y)
int x;
int y;
{
...
}
而在C++中這是不允許的. - 在C中可對任何指標賦void指標,下:
int a;
int *pint;
void *pvoid=&a
pint=pvoid; //C中可以,C++錯
C++會出錯,因C++無法自動將指標變成另一指標型別,可顯式轉換
pint=(int*)pvoid; - C中enum,srtuct,union可和同範圍內的typedef名一致,而在C++由於可只用名稱引用struct等結構,如:
struct TypeA
{
...
};
則可用 TypeA x;定義結構型變數x。
固不能與typedef同名,否則編譯器不清楚你到底想要定義什麼。 - 另sizeof()也有兩個不同點:在C中sizeof('x'),在C中相當於sizeof(int),而在C++中相當於sizeof(char)。另如有列舉
eumu E(x,y,z);
sizeof(x)在C中相當於sizeof(int),而在C++中為sizeof(E)。
/文件/c++001.htm#頁首">返回到頁首
- 區域性變數的宣告
在C中我們要宣告一個區域性變數,必須在塊的開頭任何語句前宣告,在C++中你可在程式任何一個位置宣告一個變數.因此一般你可在要用某個變數時才宣告它,這樣便於閱讀與維護(你甚至可在for語句中定義)如:
for(int i=0;i<100;i++) //在C中i必須定義在開始處
{
int c=12;
c*=12;
int a; //這在C中可是不行的
...
} - 範圍分解運算子
我們都知道:在C中,如在內部(如函式內)宣告一個與外部變數(如全域性)相同的變數時,內部的變數將掩蓋外部變數,(此時外部變數存在但不可見).而在C++中這個外部的變數也是可存取的,只要在該變數前加上"::"即可,如:
double a;
...
{
int a; //宣告一與外部浮點變數a相同的整型變數a
a=3; //這個a為內部變數,整型的
::a=3.5; //a為外部,浮點型
} - 內嵌函式(線上函式)
如在C++中用inline定義一個函式,如:
inline int FuncA(int a) { ...}
則統編譯器把對這個函式的呼叫換成實際的函式碼,和宏很類似,但有兩個重要的優勢:1.呼叫函式時,編譯器檢查引數型別,而宏不會.2.如果傳遞給函式,它只會求一次值.而在宏中它求兩次,這有可能帶來問題,如:
ABS(--i); 若ABS是內嵌函式它和我們想的一樣工作,而如ABS是宏,則i將被減兩次,這可能並不是我們希望的.
這類函式主要用在進行大的迴圈中,以加度,或在類中使用.它與一般函式的不同的是,如改變了它,則所有呼叫它的源都要重新編譯. - 過載函式(我不知為什麼有的書把過載稱為過載,怪彆扭的)
在C中如你要寫一個求浮點型和整型變數絕對值的函式據,那你必須寫兩個不同的函式(雖然它們內部非常的象)就象下面這樣:
int AbsI(int i) {...} //整型版的
double A(double i) {...} //浮點版
而在呼叫時,不能搞錯,而在C++中你可在同一程式中多次定義同一個函式(但它們不能有完全一樣的形式),則上例可定義成:
int Abs(int i) {...} //整型版的
double Abs(double i) {...} //浮點版
這樣在凋用時可用同一個函式名呼叫,程式會自動呼叫正確的版本,如:
Abs(3); //整型版
Abs(-3.5) //調浮點版
你也可能有時呼叫某函式,而每次用的引數個數不一樣,也可利用該功能完成. - 預設函式引數
C++可在宣告函式時定義預設引數值來減少一些工作,如:
void ShowText(char *text,int length=-1,int color=0);
這樣你可用如下的方法呼叫:
char *t="hello";
ShowText(t,6,3); //這和平時用法一樣
ShowText(t,6); //省去一個引數,此時 color=0
ShowText(t);//省了兩個引數, length=-1;color=0
呼叫時不能只省去中間的,如
ShowText(t,,4); //這是錯的
它在定義時,還要注意:不能在參數列中部定義一個預設變數,而它後面又是正常的變數,(要麼它後面全是預設變數,要麼把它放在最後)如:
void ShowText(chat *text,int length=-1;int color);//錯
預設變數一經定義不可在同一範圍內再定義(即使是一樣的)如
void ShowText(char *text,int length=-1,int color=0);//宣告
...
void ShowText(char *text,int length=-1,int color=0) //定義,這就是錯的
{...}
另:在用預設變數和過載函式時要注意它們可能造成執行時出錯(編譯時可能沒問題,如有以下定義:
void Display(char *buf);
void Display(char *buf,int length=30);
這看上去沒有任何問題,但如有以下的呼叫,則出錯;
Display("hello"); //多義呼叫,程式不知到底應調哪一個 - 引用型別
宣告為引用的變數其實是另一變數的別名,可用&定義一引用,如
int c;
int &b;
b=c;
此時b為c的別名,即c與b有同樣的地址,對b的操作和對c操作是一個效果.它與指標不同,它們是同樣的型別.不能將常量賦值給它:如 b=5;//錯
也可將函式引數或返回型別宣告為引用,如將引數設為引用,如下
int FuncA(int &a);
而有以下呼叫:
FuncA(b); //則如在函式內改變了a的值,則b的值也發生同樣的改變
當然此時不能有如下的呼叫(把常量賦給了變數)
Func(4);
這除了用於能改變引數的值之外,也常用於引數為結構時(此時不用將整個結構再複製一遍,有利於提高,此時最好也將之定義為常量(見後常量介紹)
函式的返回值也可定義為引用,此時函式必須返回一個適當的變數,如:
int a=0;
int &GetA() {return a}
void main()
{
int N;
N=GetA(); //N=0,注N並不是a的引用
GetA()=5; //a=5;相當與a=5
++GetA(); //a=6;相當於++a
}
由於函式的引用是在函式返回後用的,它不能返回已不存在的變數,特別是返回去自動變數,或是引數的引用,如下例是危險的;
int &aa()
{int a;
return a;}
int &bb(int b)
{return b}
這個程式並不產生編譯錯誤,但它們的結果是無法預料的.這類函式可的返回全域性變數,static,或動態變數(在下面的new/deldet中介紹) - new和delete
C++中一般用new和delete分配和回收塊,使用new時指定資料型別,由分配足以存放指定型別(可為各種型別)的記憶體塊,返回該塊地址作為該指定型別的指標,如:
int *cc;
char *ch;
cc=new int;
ch=new char[23]; //分配了一個 char型陣列(有23個項)
它們可由delete回收,如:
delete cc;
delete[] ch; //[]表示回收整個陣列,而不是單個元素. - 常量
可用const定義存放常量的變數,如
const a=100;
則a是一個常量,它不能在程式中改變,但常量並不象你想象的那麼簡單,它並不象#defind:
一.常量和指標:
這也有幾種:
1.將指標定義為常量,可隨時改變指標的值,但不能改變指標指向變數的值,(相當於只讀指標),如:
const int *PCI;
const int a=1;
int b=2;
PCI=&a; //OK!
*PCI=5; //錯,不可改動
PCI=&b; //OK!
2.將常量指標定義到非常量變數,此時指標為常量,必須在定義時初始化,此後不能再賦其它地址,但指標指向的變數可變,如:
int a=1;
int b=2;
int *const CPI=&a; //注意這行!
*CPI=5; //OK
CPI=&b; //ERROR,不能改變指標!
3.定義常量指標到常量物件.這時必須在定義指標時初始化,既不能改指標,也不能改指標指向的值.
4.不能將常量的地址賦於非常量的指標
二.常量與引用
可以定義常量物件的引用.它可用常量初始化:
const int a=1;
const int &RCA=a;
也可用變數初始化
int b;
const int &RCB=b;
無論如何都不能用引用改變所指變數的值.
三.常量和函式
定義函式的引數或返回型別為常量.
如將引數中的一般變數定義為常量,沒有什麼意義,如:
FuncA(const int a); //a本來就不能改變
我們知道若引數為指標或是引用,則這可改變這此變數的值,但有時,我們可能只對引數的值感興趣(而不想改變它們的值)這時,可用常量定義引數,保證變數的改變不會有什麼副作用,如:
funcA(const int *P);
funcB(const int &C); //無論函式如何對P,C操作,原來的值都不會改變.
另前面講過如函式的引數是引用,則不能用常數為引數呼叫該函式,但如定義為常量引用,則可以, 如:
void FuncA(const int &r);
void main()
{...
FuncA(5); //還記得前面說的麼,如它只是引用,這是錯的,而現在它沒問題
...}
如函式的返回值是一般變數,則定義返回為常量沒有什麼意義,但如是指標,或是引用,則使函式不能用返回值來改變指向或引用的變數.例:
const int *funcA()
{ static int p=1; //注意這的static,若為普通變數很危險,見前引用處
++p;
return &p}
const int &funcB()
{static int s=100;//同想請注意這個static
--s;
return s;}
void main()
{int N;
N=*funcA(); //OK,N為一複製
N=funcB(); //OK,N也為一複製
*funcA()=5; //錯,不可改變.
++funcB(); //錯,這可參考一下前面"引用"的例子
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987803/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++ 轉型C++
- The New C++ (轉)C++
- C# 和 C++ (轉)C#C++
- 總覽c & c++ (轉)C++
- C/C++ 通用 Makefile(轉)C++
- C++入門解惑(1)——淺析cout (轉)C++
- 【C++】C++之型別轉換C++型別
- c++經典(轉)C++
- C++簡介 (轉)C++
- Prefer C++ (二) (轉)C++
- Prefer C++(三) (轉)C++
- 轉享:從Java或C++角度看 Objective-C 語言JavaC++Object
- C++、C++學習之我見 (轉)C++
- C++入門解惑(2)——初探指標(上) (轉)C++指標
- C++入門解惑(3)——初探指標(下) (轉)C++指標
- 從C++的Return Value Optimization (RVO)到C#的value type (轉)C++C#
- C++型別轉換C++型別
- C++指標轉換C++指標
- Effective C++: Item 32 (轉)C++
- Effective C++: Item 21 (轉)C++
- Effective C++: Item 24 (轉)C++
- Automation In C++ Builder (轉)C++UI
- c++物件的放置 (轉)物件
- 依然熱戀C++ (轉)C++
- C++語言概述 (轉)C++
- C++ STL簡介 (轉)C++
- 讀《Efficient C++》疑惑 (轉)C++
- Learn c++ step by step (轉)C++
- 面試C++試題 (轉)面試
- c++ 型別轉換C++型別
- C/C++,我的至愛!!! (轉)C++
- C++、Java/C#之比較 (轉)C++JavaC#
- C++程式設計從零開始之語句(轉)C++程式設計
- 用DEF檔案從DLL中匯出C++類 (轉)C++
- C++圖片格式轉換:BMP轉JPEGC++
- C++/C:數字轉成字串, 字串轉成數字C++字串
- C++永久物件儲存 (Persistent Object Storage for C++) (轉)C++物件Object
- (轉貼) C++,C#,Java功能比較 (.NET) (C#) (C/C++)C++C#Java