430 likes | 674 Views
C++ 基础 教学目的:通过本节课的学习,掌握 c++ 的基础知识,会编写简单的 c++ 程序 教学重难点:函数的重载和引用. 1.1 C++ 程序的结构特性. 例 1 一个简单的 C++ 示例程序 [ 例 1.1] 两数相加 /* //最简单的方式 #include <iostream.h> void main() { int a,b,sum; cin>>a>>b; sum=a+b; cout<<"a与b的和为"<<sum<<endl; } */. 1.2 C++ 程序的结构特性. 类的声明部分 面向对象程序
E N D
C++基础 教学目的:通过本节课的学习,掌握c++的基础知识,会编写简单的c++程序 教学重难点:函数的重载和引用
1.1 C++程序的结构特性 例1 一个简单的C++示例程序 [例1.1] 两数相加 /* //最简单的方式 #include <iostream.h> void main() { int a,b,sum; cin>>a>>b; sum=a+b; cout<<"a与b的和为"<<sum<<endl; } */
1.2 C++程序的结构特性 类的声明部分 面向对象程序 类的使用部分
例1.2 典型的C++程序结构 #include<iostream.h> // 类的声明部分 class A{ int x,y,z; //类A的数据成员声明 … fun(){ … } //类A的成员函数声明 … }; // 类的使用部分 int main() { A a; // 创建一个类A的对象a … a.fun(); // 给对象a发消息,调用成员函数fun() return 0; }
1.3 C++程序的编辑、编译和运行 C++语言是一种高级程序设计语言,它的开发过程与其他高级语言程序开发过程类似,一般要经过四个步骤: • 编辑 • 编译 • 链接 • 执行
编辑 是指把按照C++语法规则编写的程序代码通过编辑器(Borland C++,Visual ,Turbo C0)输入计算机,并存盘。在存盘时,C++源文件的扩展名为.CPP。 在Windos下,常用Visual C++开发环境,来编辑、编译和运行C++程序。 • 编译 将编辑好的C++源程序通过编译器转换为目标文件(OBJ文件)。即生成该源文件的目标代码。
链接 将用户程序生成的多个目标代码文件(.obj)和系统提供的库文件(.lib)中的某些代码连接在一起,生成一个可执行文件(.exe)。 • 执行 把生成的可执行文件运行,在屏幕上显示运行结果。用户可以根据运行结果来判断程序是否出错。
C++程序的构成 C++语言程序由以下基本部分组成。 1. 函数 一个C++程序是由若干个函数构成的。函数分为库函数(标准函数)和自定义函数。库函数一般是由系统提供的。一个完整的C++语言程序只有一个主函数。 2. 预处理命令 预处理命令以位于行首的符号“#”开始,C++提供的预处理有宏定义命令、文件包含命令和条件编译命令三种。
3. 程序语句 一条完整的语句必须以分号“;”结束。程序语句有如下几类: (1)说明语句 用来说明变量的类型和初值。 如下面语句是把变量说明为浮点数。 float a,b,c; 又如下面语句是把变量sum说明为整型变量,并赋初值为零。 int sum=0;
(2)表达式语句 由一个表达式构成一个语句,用以描述算术运算、逻辑运算、或产生某种特定动作,在任何表达式最后加一个分号“;”就构成了一个语句。 (3)程序控制语句 用来描述语句的执行条件与执行顺序的语句,C++语言的控制语句有9种,如下页所示。其语句中的括号( )表示其中是条件,~表示内嵌的语句。 (4)复合语句 复合语句是一种十分重要的语句,由大括号{和}把一些说明和语句组合在一起,使它们在语法上等价于一个简单语句;可由若干简单语句或复合语句组成。
(5)函数调用语句 函数调用语句是由一次函数调用加一个分号而构成的一个语句。 例如: max(x,y); (6)空语句 空语句: ; 即只有分号“;”的语句,什么也不做。
1.3.2 输入输出流 • 在程序中必须嵌入头文件: iostream.h • Cin为输入,和“>>”配套使用,Cout为输出和“<<”配套使用 • “Cin>>x”用户从键盘中输入的数值自动转换为变量x的类型,并存入变量x内; • 允许“cin>>a>>b>>c” 的写法,它按书写顺序从键盘上提取所要求的数据,并存入对应的变量。两个数据间用空白符(空格、回车或Tab键分开); • Cout 和cin输出输入数据时使用缺省的格式,也可以对输入和输出进行控制。 • Cout的输出中可以用“\n”和“<<endl”作为换行控制符。
1.3.2 输入输出流 [例] #include <iostream.h> void write (char *); void main() { char name[20]; cout<<"请输入你的姓名: "; cin>>name; cout<<name<<'\n'; //操作符dec/hex/oct的使用 int x=25; cout<<hex<<x<<'\n'<<dec<<\ x<<'\n'<<oct<<x<<endl; //函数原型的说明 write ("how are you"); } void write (char * s) { cout<<s;}
1.3.3 灵活的变量说明 C++中变量声明比较灵活,允许在代码块中任何地方说明,因此可以在需要时才声明.但仍然要符合”先定义后使用”的规定. float fun(int x,int y) // 对形参直接进行说明 { for (int i=0;i<10;i++) // 对循环变量i进行说明 { int sum=0; // 循环体内也可对变量sum进行说明 sum=sum+i; cout<<"sum="<<sum; } int z=0; // 使用变量z时才说明它 z=x+y; }
1.3.4 结构、联合和枚举名 例如: enum boole{FALSE,TRUE}; struct string{ char * str; int length; }; union number{ int i; float f; }; C++在中, 定义变量时,可以说明为: boole done; string str; number x;
2.3.5 函数原型 • 必须为每一个函数建立原型,说明函数的名称、参数类型与个数,以及函数返回值的类型。 • 目的是让C++编译程序进行类型检查(即形参与实参的类型匹配检查),以及返回值是否与原型相符,维护程序的正确性。 • 语法:返回类型 函数名(参数表); • 函数的原型必须出现在函数的调用语句前。 [例]函数原型的说明。 #include <iostream.h> void write(char *s); // 函数原型的说明 void main() {write("Hello,world!");} void write(char *s) { cout<<s; }
1.3.6 const修饰符 C++中一般用const取代C中的#define ,消除#define的不安全性 例1.6 #define的不安全性 #include<iostream.h> main() { int a=1; #define T1 a+a #define T2 T1-T1 cout <<"T2 is "<<T2<<endl; return 0; }
例1.7 用const取代#define。 #include<iostream.h> int main() { int a=1; const T1=a+a; const T2=T1-T1; cout <<"T2 is"<<T2<<endl; return 0; } 输出:T2 is 0
(1) 指向常量的指针是指:一个指向常量的指针变量。例如: const char* pc="abcd"; // 声明指向常量的指针 (2) 常指针是指:把指针本身,而不是它指向的对象声明为常量。例如: char* const pc="abcd"; // 常指针 (3) 指向常量的常指针是指:这个指针本身不能改变,它所指向的值也不能改变。要声明一个指向常量的常指针,二者都要声明为const。例如: const char* const pc="abcd";//指向常量的常指针
1.3.7 void型指针 • Void作为指针的类型时表示不确定的类型 • 可以声明void类型指针,但不能声明void类型的变量 • Void型指针是一种通用指针,任何类型的指针值可以赋给void类型的指针变量;已获值的void型指针,如果要使用(如输出),则必须再进行类型转换.(如下例) 例1.8 void型指针的使用。 #include<iostream.h> void main() { void* pc; int i=456; char c='a'; pc=&i; cout<<*(int* )pc<<endl;// 对PC进行转换 pc=&c; cout<<*(char*)pc<<endl; }
1.3.8 内联函数 • Inline 标志 • 当程序调用带inline的函数时,编译器将函数体插入到调用该函数的语句之前,程序运行时不再进行函数调用. • 内联函数可消除函数调用时的系统开销,提高运行速度 例1.9内联函数的使用 #include <iostream.h> inline double circle(double r) // 内联函数 { return 3.1416*r*r; } int main() { for (int i=1;i<=3;i++) cout<<"r="<<i<<" area= "<<circle(i)<<endl; return 0; }
1.3.8 内联函数 关于内联函数的几点说明: • 内联函数在第一次调用之前必须进行声明和定义(函数前一定要加inline) • 内联函数体一般不能有循环语句和开关语句 • 类结构中所在在类说明体内定义的函数都是内联函数. • 内联是用空间换时间,因此一般只将较短的函数定义为内联函数
1.3.9 带有缺省参数值的函数 C++允许实参个数与形参个数不同 例如有一函数原型说明为: int init(int x=5,int y=10); //要求在函数原型或函数定义中为参数指定缺省值. 则x与y的缺省值分别为5与10。 以下的函数调用都是允许的: init(100,80); // x=100,y=80 init(25); // x=25,y=10 //调用函数时,省略实参,C++自动以缺省值作为相应参数的值 init(); // x=5,y=10
1.3.9 带有缺省参数值的函数 说明: • 在函数原型中,所有取缺省值的参数都必须出现在不取缺少值的参数的右边,如: Int fun(int I,int j=5,int k); Int fun(int I,int k,j=5); 函数调用时,或省略某个参数时,则其后的参数都应省略,采用缺省值,不允许某个参数省略后再给其后的参数指定参数值,如: Init(,20);
1.3.10 函数重载 在C++中, 只要函数参数的类型不同,或者参数的个数不同,或者二者兼而有之,两个或者两个以上的函数可以使用相同的函数名。 求绝对值的函数: int iabs(int I); long labs(long l); double fabs(double d); C++用同一个函数名 abs( )实现上面,用函数参数来区别到底调用哪个函数。所以把同一作用域内名字相同,但参数不同的函数称为重载函数。这得益于函数原型不仅给出函数名,而且指出了参数类型。 为了保证编译器根据参数类型识别重载函数,必须保证重载函数的参数不同。
以下几种可能出现二义性: 1、同名函数,仅返回值类型不同,但参数相同; 2、两同名函数,仅用const或引用使参数类型有所不同; ex 10. int print (const int & ); int print (int ); 3、加修饰符使参数有所不同,取决于实参的具体类型; ex 11. void print (unsigned int ); void print (int ); //… print (1l); //出错 print (1u); //正确 4、缺省参数有时也能导致二义性; ex 12. void print ( int a, int b=1 ); void print (int a); //… print(1); //二义性
例1.13参数类型不同的重载函数 #include<iostream.h> int cube(int i) { return i*i*i; } float cube(float f) { return f*f*f; } double cube(double d) { return d*d*d;} void main() { int i=12; float f=3.4; double d=5.67; cout<<i<<'*'<<i<<'*'<<i<<'='<<cube(i)<<endl; cout<<f<<'*'<<f<<'*'<<f<<'='<<cube(f)<<endl; cout<<d<<'*'<<d<<'*'<<d<<'='<<cube(d)<<endl; }
1.3.11 作用域标识符∷ 例1.16 使用作用域标识符的情况。 #include<iostream.h> int avar; main() {//局部变量具有较高的优先权 int avar; avar=25; // 局部变量avar ::avar=10; // 全局变量avar cout<<"local avar ="<<avar<<endl; cout<<"global avar ="<<::avar<<endl; return 0; } 程序运行结果如下: local avar=25 global avar=10
1.3.12 无名联合 #include<iostream.h> void main() { union { int i; float f; }; i=20;//无名联合可通过使用其中数据项名字直接存取 cout<<i<<endl; } 在此无名联合中,声明了变量i和f具有相同的存储地址。
1.3.13 强制类型转换 C++类型转换支持两种方式: int i=10; float x=float(i); 或 float x=(float)i;
1.3.14 new和delete • 运算符new用于内存分配,语法为: 指针变量 = new 类型名; • 运算符delete释放new分配的存储空间,语法式为: delete 指针变量; • 关于New /delete与malloc/free • new 是个操作符,和“+”,“-”,“=”地位相等.而malloc是分配内存的函数,需要调用; • new是保留字,不需要头文件支持,malloc需要头文件库函数支持; • new 建立的是一个对象,malloc分配的是一块内存. • new建立的对象可以把它当成一个普通的对象,用成员函数访问,不要直接访问它的地址空, new和malloc有的区别,就好像是"飞机和汽车有什么分别“,除了都是交通工具,其他的特征全是分别...
关于new和delete的几点说明 • 用new分配的,使用结束后只能用delete显式释放,否则这部分空间只能变成不能回收的死空间 • 使用new分配内存时,若内存不够,new将返回空指针(null),如: # include <iostream.h> void main() { int *p; p=new int; if (!p) cout<<"allocation failure"<<endl; *p=10; cout<<*p; delete p; }
关于new和delete的几点说明 • 使用new可以为数组动态分配内存空间,此时需要在类型名后面缀上数组大小.语法: 指针变量=new 类型名[下标表达式] 如 int *p=new int[10] • 释放动态分配的数组存储区时,使用delete.语法: delete[]指针变量 如: delete[] pi;或delete[10] pi; • New可在为简单变量分配内存空间时进行初始化.语法: 指针变量=new 类型名(初始值) 如 int *p=new int(100)//动态分配内存并为其赋初始值99
关于new和delete的几点说明 • 使用new可以为数组动态分配内存空间,此时需要在类型名后面缀上数组大小.语法: 指针变量=new 类型名[下标表达式] 如 int *p=new int[10] • 释放动态分配的数组存储区时,使用delete.语法: delete[]指针变量 如: delete[] pi;或delete[10] pi; • New可在为简单变量分配内存空间时进行初始化.语法: 指针变量=new 类型名(初始值) 如 int *p=new int(100)//动态分配内存并为其赋初始值99
# include <iostream.h> void main() { //new 为简单变量分配内存空间的同时进行初始化 int *p=new int (99); if (!p) cout<<"allocation failure"<<endl; cout<<*p<<endl; delete p; //给数组动态分配内存空间 int * A=new int[10]; if (!A) cout<<"allocation failure"<<endl; for (int i=0;i<10;i++) { A[i]=2*i; cout<<A[i]<<" "; } delete[]A; }
1.3.15 引用 1. 引用的概念 引用通常被认为是某个变量的别名,声明一个引用的格式如下: 数据类型 & 引用名 = 已定义的变量名; 例如: int i=5; int& j=i; 其中j是一个整数类型的引用,用整型变量i对它进行初始化,j就可看作是变量i的别名 。i与j将同步更新,且使用内存的同一地址.
例1.22引用的使用 #include <iostream.h> void main() { int i; int &j=i; i=30; cout<<"i="<<i<<"j="<<j<<"\n"; j=80; cout<<"i="<<i<<"j="<<j<<"\n"; cout<<"Address of i"<<&i<<"\n"; cout <<"Address of j"<<&j<<"\n"; }
关于引用的几点说明 • 引用名除了作函数的参数或返回类型外,在声明引用时必须立即对其初始化 int i=5; int& j; j=i; • 引用名除了作函数的参数或返回类型外,在声明引用时必须立即对其初始化 错误的引用
2. 引用作函数参数 例1.25 采用“引用参数”传递函数参数 #include <iostream.h> void swap(int& m,int& n) { int temp; temp=m; m=n; n=temp; } main() { int a=5,b=10; cout<<"a="<<a<<" b="<<b<<endl; swap(a,b); cout<<"a="<<a<<" b="<<b<<endl; return 0; }
3. 用引用返回值 例1.27 用引用返回函数的值。 #include<iostream.h> int A[10]; int& array(int i); void main() { int i,number; A[0]=0; A[1]=1; cin>>number; for (i=2;i<number;i++) { array(i)=array(i-2)+array(i-1); cout<<"array("<<i<<")="<<array(i)<<endl; } } int& array(int i) { return A[i]; }