C与C++之异同
C++在任何地方均可宣告变数 输出入方式改用cin与cout #include方式不加上.h 名称空间(namespace) C++存在预设的类别与物件 参考(reference) inline函数 函式预设参数 函式重载(overloading) 1-3 C与C++之异同 C++之动态记忆体配置使用new/delete C++提供例外处理 新的转型方法 新的资料型态bool 1-4 基本概念 语法 -所有C语言中之指令在C++ 均可使用 -C++为物件导向(object oriented)之程式语言 档名 -C语言的副档名为.c,而C++的副档名为.cpp 注解 -在C语言中注解系以/* 为开始,以*/为结束 -在C++中//之後一整行均为注解 1-5 宣告变数 C只能在区块开始时宣告变数 -例: for (i=1;i<=5; i++){ int x; } C++ 可在程式任何地方宣告变数 -例: for (int i=0;i -例: c=a+b; int x; x=a-b; 1-6 输入与输出 在C中常用的输出入指令为printf与scanf -在使用时需要#include -printf与scanf 在做变数输出入时必须搭配格式使用 在C++中常用的输出入指令为cout与cin -在使用时需要#include -新的C++语法为#include 搭配namespace std使 用 -cout与cin在输出时直接照输出入顺序使用 在C++中只需#include 则printf与scanf等C 语言函数亦可使用 1-7 C++之输出: cout 在C++中的输出使用cout,不必考虑变数的型态.直 接在cout後面加入<<再写上欲输出之值. 若有多个值要输出则连续用<<加上欲输出值即可 -例: cout << "value"; cout << x; cout << "Value" < cout << "Value" << x << ‘\n‘; cout << "Value" < 再写上欲输出之值. -例: cin >> answer; 若有多个值要输出则连续用>>加上欲输出值即可,且 变数间使用空白做隔开 -例: cin >> x >> y; 1-9 C++之输入: cin 输入一整行至一字串中 -cin.getline(字串,输入字串的最大长度) -cin.getline(str,80); 从键盘输入单一字元 -ch=cin.get(); 1-10 Program Hello // This program outputs the message // // Hello! // // to the screen #include using namespace std; int main() { cout <<"Hello!"<< endl; return 0; } 1-11 名称空间(namespace) namespace用途在於区分同名称之变数与函式,使其 均可存在并使用 语法 namespace 名称空间名称{ 变数与函式之宣告 } namespace与类别写法相类似但不需在最後加上分号 1-12 名称空间的使用 定义於名称空间之变数与函式一定要经过using 才可 使用.若不使用using则需直接指定 名称空间之使用 -using namespace 名称空间名称 单独using 一个变数或函式 using 名称空间:: 变数名称; using 名称空间:: 函式名称; 1-13 名称空间同时使用之问题 同时using 多个namespace 时其变数与函式不可重 复 -例: namespace X{ void f(){ cout<<" In X::f()\n";} } namespace Y{ void f(){ cout<<" In Y::f()\n";} } 不可在程式中同时使用 using namespace X; 与using namespace Y; 1-14 名称空间的例子 #include namespace X{ void f(){ cout<<" In X::f()\n"; } void g(){ cout<<" In X::g()\n"; } } namespace Y{ void f(){ cout<<" In Y::f()\n"; } } using namespace Y // 使用名称Y using X::g; // 单独using void main(){ f(); // 使用Y当中的f() g(); X::g(); // 直接指定 } 1-15 cin / cout 之四种写法 写法1:不使用namespace 的观念 #include cout <<"Hello\n"; 写法2:使用namespace std #include using namespace std; cout <<"Hello\n"; 1-16 cin / cout 之四种写法 写法3:只using cin 和cout #include using std::cin; using std::cout; using std::endl; cout <<"Hello\n"; 写法4:直接使用std::cin 与std::cout #include std::cout << "Hello\n"; 1-17 C++提供之类别与参数 C++语言本身提供内定之类别与物件 -类别 -字串类别string -输入档案类别ifstream -输出档案类别ofstream -物件 -输出物件cout -输入物件cin -错误讯息输出物件cerr 1-18 字串类别 C++语言本身提供内定之类别与物件 -类别 -字串类别string -输入档案类别ifstream -输出档案类别ofstream -物件 -输出物件cout -输入物件cin -错误讯息输出物件cerr 1-19 档案类别 档案类别(使用时必须#include ) -输入档之档案类别ifstream -输出档之档案类别ofstream 档案使用之顺序 -宣告物件ifstream afile("test.txt"); -开档afile.open(); -读写资料afile >> x; -关档afile.close(); 由ifstream与ofstream 宣告之物件可直接使用>>与<< 做输出入 1-20 参考(Reference) 宣告为参考时并不多占记忆体,只是与原有之变数占 同一块记忆体. 参考所宣告的只是一个名称,必须设定初值为现有之 变数 参考的语法 -type & identifier1=identifier2; -则identifier1与identifier2表相同的变数,有相同之记忆体位置 例: int a,b; int&alt=a; // alt 为a 之参考 alt=b; // 等於做a=b 的动作 alt++; // 等於做a++ 的动作 1-21 参数传递方式 程式语言的参数传递方式有 -传值呼叫(call by value) -传址呼叫(call by address) -传参考呼叫(call by reference) C语言提供传值呼叫与传址呼叫,而C++则多了传参 考呼叫 1-22 传值呼叫(call by value) 传值呼叫(call by value) -以「拷贝」的方式,主程式内的物件资料与副程式内的物件 资料分占不同的记忆体 缺点 -传递速度慢 -需要较多的记忆体空间 1-23 传值呼叫之实例(两数交换) #include using namespace std; void swap(int, int); // 传值呼叫 void main() { int i=7, j=-3; swap(i,j); cout << "i = " << i << endl; // 将输出i=7 << "j = " << j << endl; // 将输出j=-3,两者未交换 } void swap(int a, int b) { // 传值呼叫 int t; t = a; a = b; b = t; } 1-24 传址呼叫(call by address) 传址呼叫(call by address) -以类别物件指标来传递物件,主程式内的物件资料与副程式 内的物件资料占同一块的记忆体 优点 -传递速度快 -不占记忆体空间 缺点 -语法较为复杂 1-25 传址呼叫之实例(两数交换) #include using namespace std; void swap(int*, int*); // 传址呼叫 void main() { int i=7, j=-3; swap(&i,&j);// 传入i 与j 的位址 cout << "i = " << i << endl; // 将输出i=-3 << "j = " << j << endl; // 将输出j=7,成功地做数值交换 } void swap(int *a, int *b) { // 传址呼叫 int t; t = *a; *a = *b; *b = t; } 1-26 传参考呼叫(call by reference) 传参考呼叫(call by reference) -与传址呼叫(call by address)一样,主程式内的物件资料与副 程式内的物件资料占同一块的记忆体传 优点 -传递速度快 -不占记忆体空间 问题 -副程式中可以将主程式中的变数值改掉 -解决方式: 在副程式的参数列加const宣告 1-27 传参考呼叫之实例(两数交换) #include using namespace std; void swap(int&, int&); // 传参考呼叫 void main() { int i=7, j=-3; swap(i,j); cout << "i = " << i << endl; // 将输出i=-3 << "j = " << j << endl; // 将输出j=7 ,成功地做数值交换 } void swap(int &a, int &b) { // 传参考呼叫 int t; t = a; a = b; b = t; } 1-28 回传值之处理 一般的函数若有回传值,则会在函数呼叫处理完後於 呼叫处产生一个看不见的暂时变数 -函式 int add(int x, int y) { return x+y; } -呼叫方式 -型态1: add(a,b);//将暂时变数丢弃 -型态2: printf("gcd=%d\n",add(a,b));//将暂时变数印出来 -型态3: c=add(a,b);//将暂时变数拷贝到c 1-29 回传型态为参考 回传值型态为参考时,於呼叫并不会产生额外的变数 ,而是使用回传指令return 後的记忆体 回传值型态为参考时,return 不能使用当地变数与常 数 回传值为参考时,可写在等号之左边 例: int& mydata(int data[], int n){ return data[n]; } 则可写mydata(5)=2; 1-30 回传型态为参考之实例 #include using namespace std; int& access_data(int a[], int n){ return a[n-1]; } void main(){ int data[]={10,20,30,40,50}; cout << "The fourth data is "< for (int i=0; i<5; i++) cout<<"data["<必须改定义为 #define sq(x) (x)*(x) 1-32 inline函式 为解决#define 定义函式的缺点,在C++中可使用 inline 指令定义函数 inline传回值型态函式名称(参数列) { // 函数内容 } C++在程式中遇到呼叫inline函式时,会去检查其内的 参数型态与个数,并以列内函数展开 inline函式的优点: 执行速度比一般函式快,缺点: 无法 像一般函数精简执行档长度 1-33 inline 函式之实例 #include using namespace std; inline void swap(int&, int&); // 定义swap 函式为inline 函式 void main() { int i=7, j=-3; swap(i,j); cout <<"i = "<< i << endl <<"j = "<< j << endl; } void swap(int& a, int& b) { int t; t = a; a = b; b = t; } 1-34 参数预设值 在C++中,函数之参数可以有预设值.但只有在参数 列的尾部才可使用.如此一来,可以改变传入参数的 个数,毋需对每一个输入参数做设定 例: void abc(float k, int j, int i=5)// 对 void xyz(float k=1,int j, int i) // 错 void err_use(float k, int j=2, int i) // 错 则 abc(5,3) 与abc(2,4,1) 均可使用 1-35 函式预设参数之实例 #include using namespace std; void fo( int val, float f = 12.6, // f 的预设值为12.6 char c = ‘\n‘, // c 的预设值为‘\n‘ string msg = "Error" ) // msg 的预设值为"Eerror" { return; } void main() { fo( 14, 48.3f, ‘\t‘, "OK" ); fo( 14, 48.3f, ‘\t‘ ); fo( 14, 48.3f ); fo( 14 ); } 1-36 函式预设参数之实例(4个以下整数之相加) #include using namespace std; int add( int x, int y= 0, int z = 0, int w=0) { return x+y+z+w; } int main() { cout << " addition of 8,6,4,15 is "< cout << " addition of 8,6 is "<< add( 8, 6); cout << " addition of 8 is "<< add(8); return 0; } 1-37 重载(overloading) C++允许同一个名称的函数可拥有不同的参数型态, 由呼叫处之函式输入参数型态决定执行哪一个函式 对於同一名称之函式必须使得呼叫该函式者能唯一决 定 1-38 重载之实例(找最大值) #include #include using namespace std; int imax(int a, int b, int c=-INT_MAX, int d=-INT_MAX){ int max_one=(a>b) a:b; max_one=(max_one>c) max_one:c; max_one=(max_one>d) max_one:d; return max_one; } int imax(int a[],int n){ // 计算阵列中最大的元素 int max_one=a[0]; for (int i=1; imax_one) max_one=a[i]; return max_one; } 1-39 重载之实例(找最大值) void main(){ int x=120, y=500, z=320, w=2000; cout <<"Max of (x,y,z)="<< imax(x,y,z)< cout <<"Max of array a="<< imax(a,5)< 1-40 动态记忆体配置(dynamic memory allocation) 动态记忆体配置提供程式设计者依所需求取得与释回 系统之记忆体 在C中可使用的动态记忆体函数 -配置函式malloc, calloc, realloc(重新配置) -释回函式free -使用动态记忆体之函数时需加入#include 在C++中可使用的动态记忆体函数 -配置new -释回delete 1-41 new 的用法 new 可以从自由记忆体中分配一定量之记忆体,用法 如下: -用法一:记忆体指标= new 资料型态; 用於配置一个资料型态大小的记忆体 例: float *buf; buf=new float; // 配置1个单精准度浮点数 -用法二:记忆体指标= new 资料型态[阵列数目] ; 用於配置数个资料型态大小的记忆体 例:int*p; p=new int[20]; // 配置20个整数 1-42 delete 的用法 delete 可以释放一块由new所配置之记忆体,用法如 下 -用法一:delete 记忆体指标; 用於释回一个资料型态大小的记忆体 float *buf; delete buf; // 释回buf=new float 的记忆体 -用法二: delete [] 记忆体指标; 用於释回数个资料型态大小的记忆体 int *p; delete[] p; //释回p=new float[] 的记忆体 1-43 new与malloc的差别 malloc 与new 对於基本资料型态(如int, char, double, float)之配置,用途相同,仅语法不同 malloc 与free 为C之动态记忆体配置指令,在使用时 不会去执行建构(constructor )与解构(destructor) new 与delete 为C++之动态记忆体配置指令,在使用 时会去执行建构(constructor )与解构(destructor) new 与delete 指令对於阵列之配置或释回,会依据所 配置或释回之阵列元素个数而决定其建构 (construdctor)或解构子(destructor)之执行次数值 1-44 例外处理(exception handling) 程式在执行时,常会遇到一些问题使程式无法往下执 行 例外发生的情况有 -开启一个不存在的档案 -系统记忆体不够使用 -读写档案时硬碟毁损 -算术运算产生overflow或underflow 1-45 例外处理的语法 语法 try{ /* 要检查的exception */ } catch(例外之情形){ /* 处理例外的方法*/ } throw之用法 -丢出一个例外参数出来,让catch 去取得 1-46 例外处理之实例(配置动态记忆体) #include using namespace std; void main() { int *p; try{ p=new int; } catch (bad_alloc){ cerr<< "Memory allocation\n"; exit(1); } } 1-47 函式中之例外 在函式中要将例外往外丢,可在函数prototype中的参 数後面加上throw -例: double hmean(double a, double b) throw (char *); 往外丢出多个例外 -例: double multierr(double z) throw(char *,double); 不丢出例外 -例: double simple(double z) throw(); 可丢出例外,亦可不丢 -例: double simple(double z); 1-48 例外处理之实例(调和平均数) #include double hmean(double a, double b); int main(){ double x, y, z; cout <> x >> y) { try { z = hmean(x,y); } catch (char * s) { cout << s << "\n"; cout << "Enter a new pair of numbers: "; continue; } cout << "Harmonic mean of " << x << " and " << y<< " is " << z << "\n"; cout << "Enter next set of numbers : "; } 1-49 例外处理之实例(调和平均数) cout << "Bye!\n"; return 0; } double hmean(double a, double b){ if (a == -b) throw "bad arguments: a = -b not allowed"; // 在函式中丢出例外事件 return 2.0 * a * b / (a + b); } 1-50 转型 C++中提供两种型态转换的方式 -第一种: C语言之标准型态 -语法: (type) expression -例: y=(double)x; //将x转换成double型式传给y -第二种: 函数形式 -语法: type(expression) -例: y=double(x); //将x转换成double型式传给y 1-51 新的转型方式 C++提供四种新的转型方式 -static_cast -dynamic_cast -const_cast -reinterpret_cast 1-52 static_cast static_cast 於编译时作转型动作,dynamic_cast 於执 行时作转型动作 语法 static_cast(object to convert) 例 int z = 3; float x = static_cast(z); 1-53 const_cast const_cast 能够改变const 属性 例 const int* find(int val, const int t[], int n){ for (int i=0; i return 0; } 主程式 int* p; int a[]={2,4,6}; p=const_cast(find(4,a,3)); 1-54 reinterpret_cast reinterpret_cast 不理会记忆体之资料型态,直接依记 忆体内容做转型 例: int a; int *p; a=reinterpret_cast(p); 1-55 新的资料型态bool 传统C语言使用整数(int) 来代表布林值.当整数不等 於0时,布林值为『真』;等於0时布林值为『伪』 C++ 提供新的资料型态bool来代表布林值.使用bool 较int节省记忆体 bool使用保留字true 代表为『真』,使用保留字false 代表布林值为『伪』 bool 变数做输出时,无法直接输出true或false值,而 用1或0做取代 1-56 使用bool 之实例 #include using namespace std; void main(){ bool a[5]; // visual c, 1 bool = 1 byte int b[5]; // visual c , 1 int =4 byte a[0]=true; // 直接设成true a[1]=false; // 直接设成false int x; cout<>x; a[2]=(x>5); // 判断而决定为true 或false for (int i=0; i<3; i++) { if (a[i]) cout << "a["<<i<<"] is True, "; else cout<<"False, "; cout <} 1-57 使用bool 之实例 // 整数变数 b[0]=100; // 0 true b[1]=0; // =0 false b[2]=(x>5); for (i=0; i<3; i++){ if (b[i]) cout << "b["<<i<<"] is True, "; else cout<<"False, "; cout<} } |
|