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++无法自动将Word指针变成另一指针类型,可显式转换 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中我们要声明一个局部变量,必须在块的开头任何语句前声明,在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 AbsD(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(); //错,这可参考一下前面"引用"的例子

|