《c++语言程序设计》授课教案
VC++集成开发环境
集成开发环境:程序编辑、编译、连接、调试及运行的环境。在这个环境中提供了软件代码自动生成和可视化的资源编辑功能以及强大的类(class)管理功能。
VC++最主要的特点是可视化的编程环境和支持面向对象的编程技术。 集成环境具体介绍: 集成环境示意: 项目工作区 工具栏: 菜单栏: 项目工作区:
集成开发环境的应用示例:利用APPWIZARD来创建一个简单的应用程序。 附:一个工程中的文件类型说明:
*.DSW 在VC中级别最高,称为项目工作区文件 *.DSP 每一个工程都有自己的DSP文件
*.OPT 工作区选项文件,存储本地计算机的有关配置信息 *.CLW 存放应用程序中用到的类和资源
README.TXT 每一个应用程序都有一个README.TXT *.H和*.CPP 头文件和源文件 *.RC 资源文件 *.RC2资源文件
*.ICO 以及*.BMP等 具体的资源文件
第一章 C++语言基础
一、基本概念
(一)面向对象计算的基本特征
1、对象:由信息和对它进行处理的描述所组成的包;或者说对象代表着正在创建的系统中的一个实体。对象通过消息与另一个对象传递信息。
2、类:是所有对象的共同的行为和不同状态的集合体。 3、类的继承:
4、消息:对某个对象进行处理的说明(对函数的调用)。
5、方法:对对象接受了某一个消息后所采取的操作的描述
6、类的封装:封装是把一类对象的状态(用数据表示)和方法(用函数表示)封闭起来,装入对象中,形成一个能动的实体。 7、类的多态:
(二)c++对面向对象程序设计方法的支持 1、c++支持数据封装
2、c++类中包含私有、公有、保护成员 3、c++中通过发送消息来处理对象 4、c++中允许友元破坏封装性 5、c++中允许函数和运算符重载 6、c++支持继承性 7、c++支持动态联编
一个简单的C++程序实例:
定义一个用来计算圆的面积的程序: #include public: int radius; double calculate_area() { return pi*radius*radius; } double calculate_perimeter() { return 2*pi*radius; } }; void main() { Circle theCircle; cout<<\"请输入圆半径: \"; cin>>theCircle.radius; cout<<\"圆面积为: \"< (四)、c++的词法规则 1、C++的标识符 标识符:在高级程序设计中,通常采用一定含义的名字来表示程序中的数据,以便能够按名字来访问数据, 这个名字叫标识符。 标识符的组成:有32个字符组成。(包括下划线,数字符号0—9,英文字母三种字符) 例如:name how_are_you Kill j78u l$op 2、注意事项: 1)标识符的第一个字符必须是英文字母或下划线 2)大小字母是不同的字符。 3)定义标识符时,要满足意义尽量明确的原则。 4)C++的关键字和保留字不能作为标识符(如INT、NEW、FOR、IF、CASE等) 附:C++的关键字如下: ASM CONTINUE FLOAT NEW SIGNED TRY AUTO DEFAULT FOR OPERATOR SIZEOF TYPEDEF CASE DE GOTO FRIEND PRIVATE STATIC UNION BREAK DELETE PROTECTED STRUCT UNSIGNED CATCH DOUBLE IF PUBLIC SWITCH VIRTUAL CHAR ELSE INLINE REGISTER TEMPLATE VOLATILE CONST CLASS ENUM RETURN THIS EXTERN LONG SHORT THROW WHILE 二、C++程序的编辑、编译、及运行 1、单击主菜单中的FILE----NEW,选择TEXT FILE 2、输入源程序 3、编译:单击编译菜单中的编译命令 4、连接:单击编译菜单中的连接命令 5、运行:单击编译菜单中的运行命令 第二章 C++的基本数据类型和表达式 一、C++的标识符 1、标识符:在高级程序设计中,通常采用一定含义的名字来表示程序中的数据,以便能够按名字来访问数据,这个名字叫标识符。 2、标识符的组成:有32个字符组成。(包括下划线,数字符号0—9,英文字母三种字符) 例如:name how_are_you Kill j78u l$op 3、注意事项: 1)、标识符的第一个字符必须是英文字母或下划线 2)、大小字母是不同的字符。 3)、C++的关键字和保留字不能作为标识符(如INT、NEW、FOR、IF、CASE等) 4)、给标识符命名时,要满足意义尽量明确的原则 5)、附:C++的关键字如下 ASM CONTINUE FLOAT NEW SIGNED TRY AUTO DEFAULT FOR OPERATOR SIZEOF TYPEDEF CASE DE GOTO FRIEND PRIVATE STATIC UNION BREAK DELETE PROTECTED STRUCT UNSIGNED CATCH DOUBLE IF PUBLIC SWITCH VIRTUAL CHAR ELSE INLINE REGISTER TEMPLATE VOLATILE CONST CLASS ENUM RETURN THIS EXTERN LONG SHORT THROW WHILE 二、C++中的数据类型: 1、基本类型包括:VOID无值型、CHAR字符型、INT整形、FLOAT浮点、DOUBLE双精度型,以及他们的各种变形形式SHORT、LONG、SIGNED有符号、UNSIGNED无符号等(注意:对于INT型数据如果其前面加上修饰符,则INT可以省略)。 2、派生类型包括:指针、引用、数组、枚举、函数、结构体、公用体和类等。 举例: //程序清单2.3 ex2-3.cpp #include int a; //定义整型变量 a; int year=2001; //定义整型变量 year,初始值为2001 float f1 = 3.1415; //定义浮点型变量 f1,初始值为3.1415 double d1,d2; //定义双精度型变量 d1和d2 char vchar = 'a'; //定义字符型变量vchar,初始值为'a' signed int a; short int b; unsigned int c; unsigned long int d „„ //程序其余部分 } 注意:1、CHAR 定义的变量只能存储单个字符,而不能存储字符串,如CHAR CHI=“CHINA”是错误的,若要存放字符串,在C++中常用字符数组。 2、无值型VOID:用于表达一种特殊的函数返回的数据类型。 三、常量: (一):整形常量 1、十进制数: 2、八进制数 3、十六进制数: (二)、浮点型常量 1、小数表示法: 2、科学表示法: 3、注意:单精度数据与双精度数据的区别。 (三)、字符常量 1、用该字符的图形字符来表示。(可打印字符) 2、转义序列表示法:(用 / 加字符的ASCII码来表示) (四)、字符串常量: 注意:1、所有的字符串常量系统都会自动地在其后面加上\\0作为其结尾标志。 2、字符常量与字符串常量的区别。 (五)、符号常量 1、常量的定义: CONST 类型 标识符=常量 例如:CONST INT F=0 CONST DOUBLE I=0.12 CONST FLOAT PI=3. 14 CONST CHAR VCH=‘A‘ 2、常量定义好了以后,可以用常量标识符代替常量 例如: #include int radius; cout<<\"请输入圆半径:\"; cin>>radius; out<<\"圆面积为:\"< int radius; cout<<\"请输入圆半径:\"; cin>>radius; cout<<\"圆面积为:\"< 含义 字符常量形式 \\n 换行符 \ 水平制表 \\v 垂直制表 \\b 退格 \\r 回车 \\f 走纸换页 \\a 响铃 \\\\ 反斜杠 \\? 问号 \\‘ 单引号 \\‖ 双引号 NULL字符 \\0 四、变量: 1、变量的定义 格式:数据类型 变量名 例如:INT A CHAR VCH FLOAT P 2、变量的初始化: 格式:数据类型 变量名=常量 例如: INT A=2 CHAR VCH=‘J’ FLOAT P=2.1 注意:1)、初始化只能对一个变量进行, 例如:FLOAT X,Y,Z=12.34 2)、先定义,后使用。 3)、注意各种数据类型变量的默认值情况。 数组 一、一维数组 1、定义: 格式:数据类型 数组名[常量表达式] 例如:int a[100] float b[10] 2、元素组成:有一个定义好的数组a[n],它的元素分别可以用a[0], a[1], a[2], a[n-1]来表示。 注意:a.数组的下标只能用方括号表示,并且它的值是丛 0开始的。 b.常量表达式中只能包括常量,不能包括变量,例如 int n=10 int a[n]是错误的。 c、在一维数组中数组名是该数组在内存中首地址。 3、引用 格式:数组名 [下标表达式] 例如: int a[100],I=5 a[5]=32 f=b [I*3+8] +3.2 注意:一次只能引用单个数组元素,不能引用整个数组。 4、举例 用一维数组编写程序,计算用户输入的10个数的和。 #include const n=10; void main() { int i,sum=0; int a[n]; for (i=0;i for (i=0;i int i,temp; int a[n]; cout<<\"请输入\"< cout<<\"\\n\"; for (i=0;i 格式:类型 数组名 [常量表达式] [常量表达式] 例如: float a[2] [3] 在二维数组中,元素的排列顺序是按行排列的。例如数组a[2][3]的元素的排列顺序为: a[0][0]---a[0][1]---a[0][2]-- a[1][0]---a[1][1]---a[1][2] 2、多维数组的初始化 1)将数组的初始值写在一对大括弧内,按照数组元素的排放次序依次向数组元素赋初值。例如: int a[4][2]={0,1,2,3,4,5,6,7} 注意:1、初始值的个数也可以小于数组元素的个数,剩余的数组元素的值将取0 2、初始化时,数组元素的个数要大于初始值表中数据的个数。否则将出现编译错误。 2)按行给二维数组赋值。例如: a[4][2]={{0,1},{2,3},{4,5},{6,7}} 3、多维数组的引用 格式:数组名 [下标表达式] [下标表达式] 例如:a[4] [5]=34 注意:在使用数组元素时,数组的下标的值应在预定义的大小范围内。例如:int a[4] [4] a[4] [4]=5是错误的。 4、三维数组(略) 5、例: 使用二维数组编写一个程序,从键盘接收由用户输入的5*5距阵,并把这个距阵打印出来 #include int i,j; int a[n][n]; cout<<\"请输入5*5矩阵的值:\\n\"; for (i=0;i cout<<\"打印5*5矩阵如下:\\n\"; for (i=0;i int i,j; int a[n][n]; for (i=0;i 定义:格式:CHAR 数组名 [常量表达式] 例如:CHAR A[10] 2、初始化: a、一般在定义时,就完成初始化。 例如:CHAR A[4]={‘G’,‘C’,‘’,‘F’} b、通过字符串常量来初始化。 例如CHAR A[5]={“abcd”} 3、举例:在程序中初始化字符串,然后输出。 #include char a[12] = {'G', 'o', 'o', 'd', ' ', 'm', 'o', 'r', 'n', 'i', 'n', 'g'}; int i; cout<<\"输出字符串:\"; for (i=0;i<12;i++) { cout<cout<<\"\\n\"; } 四、字符串的处理 字符串:是一组字符数据,它和字符数组的区别在于,它一般作为整体来引用,在C++中,没有专门提供字符串类型,而是将字符串存放在字符数组中来使用。 字符数组的初始化可以通过字符串常量来赋值。 例如: char a[ ]={―good morning!‖}或 char a[ ]=―good morning!‖ 注意: 1、系统要求每个字符串后面都以‘\\0’为结束标记。所以字符数组的初始化通过字符串常量来赋值与前面的初始化是有区别的。 2、一维字符数组可以存放一个字符串,多维字符数组可以存放多个字符串。 Char ss[2][4]={{‗a‘, ‗b‘, ‗c‘, ‗\\0‘},{‗b‘, ‗d‘, ‗v‘, ‗\\0‘}} 附:字符串的处理函数: 1、s t r c a t (字符数组1,字符数组2):连接两个字符数组中的字符串,并把结果放到字符数组1中。例如: char a[ ]={―today is ―} char b[ ]={―Monday‖} strcat (a , b) 执行完后,字符数组1的内容为: today is monday 2、s t r c p y (字符数组1 , 字符串2 ,整数n ):字符串拷贝函数,将字符串2的前n个字符拷贝到字符数组1 中,若省略n,则拷贝所有字符。例如: char fake[20] strcpy (fake , ―I love this game!‖); 3、s t r c m p(字符串1 , 字符串2):比较两个字符串的大小。比较的规则如下:对两个字符串自左向右逐个字符相比,直到遇到不同的字符或字符串的结束标记为止。 s t r c m p的返回值的情况如下: 字符串1=字符串2 , 返回0 字符串1>字符串2 , 返回值为正整数 ,该整数是两个字符串中第一个不同字符的ASCⅡ码的差值。 字符串1<字符串2 , 返回值为负整数 ,该整数是两个字符串中第一个不同字符的ASCⅡ码的差值。 4、s t r l e n(字符数组):计算字符串的长度,长度不包括字符串的结束标记。 Char fake[20]; Strcpy (fake , ―I love this game!‖); Cout < { } char a[50],b[50]; cout<<\"请输入字符串1:\"; cin>>a; cout<<\"\\n\"; cout<<\"请输入字符串2:\"; cin>>b; cout<<\"\\n\"; strcat(a,b); cout<<\"合并字符串:\"<cout<<\"合并字符串长度:\"< 一、枚举是一种构造的数据类型,它是若干个有名字的整形常量的集合。 二、枚举类型(模式)的定义: 1、格式: enum [枚举名] { [枚举表] }; enum day {sum ,mon ,tue ,wed ,thu ,fri ,sat} 2、上述格式中的每个枚举符是一个用标识符表示的整形常量。 3、枚举符的赋值: 可以直接赋值,但在默认情况下,最前面一个为0,接着一个为1,后一个总是前一个的值加1。 Enum day { sum=3 , mon=5 , tue , wed , thu , fri} 三、枚举型变量的定义: 1、格式: enum [枚举名] [枚举变量表]; enum day di , d2 ,d3; 四、枚举变量的赋值: 1、枚举变量的值是该枚举变量所属的枚举模式的枚举表的某个枚举符。 enum day di , d2 ,d3; d1=mon; d2=sat; 2、注意不能直接把整形数值赋给枚举变量。 D3=7; 指针与引用 一、 指针的概念: 指针:是用来存放某个变量的地址值的一种变量。 指针变量:用来专门存放其他变量的地址的变量。 二、 指针变量的定义: 1、格式: 数据类型 * 变量; 例如: int *p1, *p2; 2、注意: 1).指针变量中只能存放地址(指针),不要将一个整形变量(或其他非地址类型的数据)赋给一个指针变量。 int *p1, *p2; p1=3; 2).指针变量里存放的哪个变量的地址值,就说指针指向哪个变量(分析)。 Int a=5 , *p; *p=&a; 3).指针的类型是它所指向的变量的类型,而不是指针本身数据值的类型(指针指向的数据类型有多种)。 int *p1, *p2; int (*p1)[6] int (*p1)() int * *p1 float *p1 4).在定义一个指针后,系统会给指针分配一个内存单元,各种不同类型的指针所被分配的内存空间的大小是相同的。 三、 指针的赋值 任何一种类型的指针所赋的值都只能是内存的地址值。但是不同类型的指针的内存地址值是不尽相同的。 1、一般变量、数组元素等其地址值都表示为变量名前加运算符&。 Int a , b[10]; Int *p1 , *p2; p1=&a; p2=b[4]; 2、数组的地址值使用该数组的数组名来表示。 1)、Int a , b[10]; Int *p1; P1=b; //表示p1指向数组b的首元素。 2)、 int b[5][6]; int (*P) [6]; P=b; //表示p指向数组b的第0行。 3)、三维数组的情况。 3、函数的地址值可用该函数的名字来表示。 Int xinguan (int xx); Int (*p) ( ); P=xinguan; //表示p指向函数xinguan在内存中的入口地址。 注意:1)、在c++中,指针必须赋值以后才能引用。 2)、一个暂时不用的指针,为了安全,可以将0值赋给该指针,是它称为空指针。 四、 指针的运算符 与指针有关的运算符: & 取地址运算符 * 指针运算符 例如:&a为变量a的地址,*p为指针变量p所指向的变量。 例如:采用调整地址的方法,输入两个整数。 #include 格式:如果定义好了一个数组a[n],那么它的元素可以用*(a+I)I=0,1,2,3………n-1来表示。 2、二维数组元素 格式:如果定义好了一个数组a[n] [m],那么它的元素可以用(*(a+I)+j) I=0,1,2,3………n-1,j=0,1,2,3………m-1来表示。 3、三维数组元素 (二)举例: 1、#include int a[5] = {5, 4 , 3 , 2 , 1}; int I , j; I=a[0]+a[4]; J=*(a+2)+*(a+4); cout<2、#include char s2[ 5] = {'G', 'o', 'o', 'd', '\\0 '}; char s1[] = ―abcde‖; char *p=s1; cout< int b[ ][3] = {{1,2,3} , {4} ,{5,6}}: b[0][2]=7; b[1][2]=8; cout<<* *b<<‖\‖<<* *(b+1)<<‖\‖<<*(*(b+1)+2)< 1、定义:变量的别名 使用格式:<类型> & <引用名> (<变量名>)或 <类型> & <引用名>= <变量名> 如:int a=3; int &m=a; 引用定义好了以后,所有在引用上所施加的操作,实质上就是在被引用者上的操作。并且也可以将一个引用赋给某个变量。 2、注意:引用在使用之前,必须先初始化。 运算符与表达式 一、运算符与表达式 1、表达式:用运算符和括号将操作数连接起来的、符合C++规则的式子,叫做C++表达式. 2、举例: //程序清单 ex2-4.cpp #include void main() { double i,j; int a; i = sqrt(3.0); j = sin(0.5); a = (5*5)%3; cout<<\"计算结果如下:\"<<\"\\n\"; cout<<\"i = \"<3、C++的运算符总结: 运算符 作用 运算符 作用 运算符 作用 :: 作用域分辨 DELETE 撤消 > . 成员选择 DELETE[] 撤消数组 >= -> 成员选择 (数据类型) 强制转换 = = [] 下标 .* 成员节 != () 函数调用及值结构 ->* 成员节 & SIZEOF 对象及类型大小 * 乘 ^ -- 前或后减量 / 除 | ~ 取补 % 取模 && ! 非 + 加 || - 单目减 - 减 ?: + 单目加 << 左移位 = & 取地址 >> 右移位 *= * 指针 < /= NEW 创建 <= %= += >>=和<<= &= |= ^= , 二、运算符的具体介绍: 1、二元算术运算符(* / + - % ) 注意:余数=<操作数1> - <操作数2> * <整商> (1)、例如:5%3= 3%5= 3%3= 6%3= 2、算术运算符与赋值语句组合使用形成的复合运算符的使用: 复合运算符有:+= 作用:a+=b 相当于 a=a+b 例如:复合运算符的应用: #include int a,b; a=3;b=2; cout<<‖a=‖<3、注意++I , - - I 与I++ , I- - 的区别: #include — = *= /= %= void main() { int i=5; cout<<\"计算结果如下:\"<<\"\\n\"; cout<<\"i++ = \"<cout<<\"++i = \"<<++i<<\"\\n\"; } 4、关系运算符 关系运算符:> >= < <= = = != 优先级;前四种运算符优先级相同,但高于后两种,六种关系运算符的优先级低于算术运算符,高于赋值运算符 例如: a>b!=c 等效于 c>a+b 等效于 a= =b 逻辑运算符:&& || ! 优先级:|| 和&&的优先级低于关系运算符,而!的优先级高于关系运算符,同时高于算术运算符,其中逻辑运算符的优先级为:!---&&----|| 例如:(a>b)&&(x>y) 在实际应用中,可以用逻辑表达式来表达复杂的条件。 6、条件运算符与条件表达式 格式:表达式1 ? 表达式2 :表达式3 操作:如果表达式1为真,则条件表达式的值为表达式2的值,如果表达式1为假,则条件表达式的值为表达式1的值。 例如:a>0 ? 1:(a<0? –1:0) max=(a>b) ? a : b 优先级:条件运算符的优先级高于赋值运算符,但比关系运算符和算术运算符都低。 具体应用: #include char ch; cin>>ch; ch=(ch>=‘A‘&&ch<=‘Z‘)? (ch+32):ch; cout< 1、隐式转换:在双目运算中,要求两个操作数的类型一致,如果不一致,则转换成高精度的类型。 2、强制转换 1)、显式强制转换 格式:(类型标识符)或者 类型标识符(表达式) 例:int (3.5) 注意:a、此种方式是不安全的 double a=6.33; int b; b=(int ) a; b、此种方式是一次性的 int a (3) , m double f; f=5.33+ (double) a; m=a + f; 2)、隐式强制转换 a、在赋值语句中,一律将右边的值强制赋给左边的值 b、在函数有返回值的调用中,总是将return后面的表达式的类型强制转换为该函数的的类型。 四、类型定义 (一)通过关键字typedef来实现 1、格式: typedef <已有类型名> <新类型名表>; typedef double wage ,bonus; wage weekly; bonus monthly; 新定义的类型名可以出现在标准类型名所能出现的任何位置。 (二)通过类型表达式来实现 1、类型表达式是由数据类型名与类型修饰符*或[ ]或&或( )所构成的式子。 2、类型表达式中符号的优先级 [ ]和( ) *和& 数据类型名 例如: int * a[5]; //a为新的类型名,其类型为int * [5] int * d (double) 第三章 预处理和语句 一、预处理功能 1、文件包含命令 1)、格式:#include <文件名>或#include ”文件名” 其中:前种格式是指那些由系统提供的并放在指定子目录中的头文件;后种格式是指那些由用户自定义的并放当前目录或其他子目录中的头文件或其他源文件。 2)、一条文件包含命令只能包含一个文件,并且文件包含命令可以嵌套使用。 2、条件编译命令 1)、条件编译命令是用来定义某些编译内容要在满足一定条件下才参与编译的命令。 2)、格式: (1)、#ifdef <标识符> <程序段1> #else <程序段2> #endif 附录:判断标识符是否被定义的方法: defined (<标识符>) 结果为非0则已经定义 (2)、#ifndef <标识符> <程序段1> #else <程序段2> #endif (3)、#if <常量表达式1> <程序段1> #eif <常量表达式1 > <程序段2> #eif <常量表达式1 > <程序段3> …….. #else <程序段n+1> #endif 例1、#include #if A>0 cout<<\"a>0‖< 例2、可以用条件编译命令来方便的跟踪、调试程序运行。 #define A 10 …….. #if A= =10 cout<<\"a>0‖< b、在c++中可以使用此种格式来定义符号常量。但请注意与const定义的区别。 c、标识符被宏定义之后,在取消之前不允许重新对它进行宏定义。 d、取消宏定义的方法: #udef <标识符> (2)#define <宏名>(<参数表>) <宏体> 注意:a、在替换时,用参数表中的实参代替宏体中的字符。 #define ADD(x,y) x+Y …….. s=ADD(5,6); 实际上s被替换成:s=5+3; b、在定义时,宏名与左括号之间不能出现空格。 #define ADD (x+y) x+Y 例1、#include int x(5) , y(7) , s; s=ADD(x+1 , y-2); cout<<―s=―< int b(5) ; #define b 2 #define f(x) b*(x) int y(3); cout< 每一种控制都有赖于一种特定的程序结构来实现,因此也就有三种基本程序结构:顺序结构、条件分支结 构和循环结构。 (一)、顺序结构 顺序结构:通过安排顺序来决定程序流程的程序结构。如下图:由于―语句1‖在―语句2‖的前面因此先执行―语句1‖,后执行―语句2‖。 (二)、条件结构 1、if语句 格式:if(条件) 语句 1 else 语句 2 由格式可以看出,―else 语句 2‖部分可以没有。 格式含义是:如果条件成立就执行―语句1‖,否则就执行else后的―语句2‖,如图1所示;如果if语句中不包含―else语句2‖部分,则在条件不成立时什么也不做,如下图。(其中语句1和语句2不仅可以是一条语句,而且可以是复合语句)。 例1:输入一个年份判断是否闰年 #include bool IsLeapYear; cout<<\"Enter the year:\"; cin>>year; IsLeapYear = ((year %4 = = 0 && year %100! = 0)||(year %400 = = 0)); if (IsLeapYear) cout< if 语句格式中的―语句1‖和―语句2‖本身也可以是 if 语句,从而构成嵌套的 if 语句。 格式:if (条件 1) if (条件 2) 语句 1 else 语句2 else (条件 3) 语句3 注意:语句1、2、3、4可以是复合语句;每层的if 要与 else 配对,如果省略某一个 else ,便要用{ } 括起该层的 if 语句来确定层次关系。 例2: 比较两个数的大小 #include int x,y; cout<<\"Enter x and y :\"; cin>>x>>y; if(x! =y) if(x>y) cout<<\"x>y\"< 格式:if (条件1) 语句1 else if (条件2) 语句2 else if (条件3) 语句3 „ else if (条件n) 语句n 〖else 语句n+1〗 原理:首先检测条件1,若满足则执行语句1;否则检测条件2,若满足则执行语句2;否则检测条件3,若满足则执行语句3„„如果所有的条件都不满足,则执行最后一个else后的语句(语句n+1),若没有该语句则什么也不做,如图。 例3:输入一个0~100分范围内的一个成绩,显示相应的等级:90~100——优;80~89——良;70~79——中;60~69——及格;60分以下——不及格。 源程序:#include float score; cout<<\"请输入成绩:\"; cin>>score; if(score<0 || score>100) cout<<\"成绩必须在0~100之间!\"; else if(score<60) cout<<\"不及格\"< switch语句的格式: switch(整型表达式) { case整型表达式1:语句序列1 case整型表达式2:语句序列2 … case整型表达式n:语句序列n 〖default:语句序列n+1〗 } 例4:输入一个0~6的整数,转换成星期输出 源程序: #include case 0: cout<<\"Sunday\"< for语句的格式: for(循环初始化;循环条件;循环参数调整)循环体 其中的循环条件应当是一个逻辑表达式,而循环初始化和循环参数调整都应当是具有副作用的表达式,其中循环参数还应当是一个能够影响循环条件的表达式。 说明:1、括号内的三项都可以省略,但分号不能省略。 2、循环条件如果省略,循环将无终止的进行下去。 例5:输入一个整数,求出它的所有因子 源程序: #include int n,k; cout<<\"Enter a positive integer:\"; cin>>n; cout<<\"Number \"< while语句的格式: while (循环条件) 循环体 由于这种结构先判断后执行,因此如果一开始循环条件就不成立的话,起循环体就一次也不执行。While语句更具一般性,一切用for语句实现的循环也可以用while语句实现。 do„while循环 do„while语句的一般格式: do 循环体 while (循环条件) 由于这种结构先执行后判断,因此其循环体至少执行一次。 例6: 源程序: #include int i(1),a(0); for(;i<=5;i++) { do{ i++; a++; }while(i<3); i++; } cout<第四章 函数 函数是c++的基本特征,在c++编程中,常常把一个程序分成多个函数来实现。这样将有利于数据共享,节省开发时间,增强程序的可靠性和便于管理等。 一、函数的定义: 1、无参数函数的定义 格式: 类型标识符 函数名 ( ) //函数头 { 说明部分和语句部分 //函数体 } 例如: void display () { cout<<‖this is a display message‖; } 2、有参数函数的定义 格式: 类型标识符 函数名 (形式参数表 ) { 说明部分和语句部分 } 举例: int sum (int x,int y, int z) { return(x+y+z) } 注意:c++允许有“空函数”,例如: 类型标识符 函数名 (形式参数表 ) { } 二、函数的说明方法: 1、在c++中,函数的说明原则如下:如果一个函数定义在先,调用在后,调用前可以不必说明;如果一个函数调用在先定义在后,调用前必须说明。 2、说明的格式: < 类型 > < 函数名> (<参数表>); 3、#include cout<<‖it is main‖< cout<<‖it is in fun1‖< cout<<‖it is in fun2‖< cout<<‖it is in fun3‖< 实参的个数由形式参数的个数决定,实参是用来在调用函数时给形参初始化的。因此要求在函数调用时,实参的个数和类型要与形参的个数和类型是一致的。当然,参数可有可无,但小括号不能省。 2、按照函数在程序中的位置,调用形式可以分为: 把函数调用作为一个独立的语句。 如 PISPLAY() 函数出现在表达式中。 如AVERGE=SUM(A,B,C)/3 函数调用本身作为另一个函数的实际参数。如 M=AVERGE(SUM(A,B,C),N) 3、函数的调用注意: 如果使用标准函数或库函数,应用预处理指令先定义 函数调用是一种表达式,其表达式的值是函数的返回值。 函数的返回值是通过函数中的 RETURN语句获得的。其格式如下: ret u r n <表达式> 或ret u r n < > 四、调用方式: 1)、传值调用:在此种方式中,调用函数的实参用常量、变量值或表达式值,被调用函数的形参用变量。传值调用的实现机制是系统将实参拷贝一个副本给形参。传值调用的特点是形参值的改变不影响实参。 #include void swap1 (int x , int y) { int temp; temp=x; x=y; y=temp; cout<<‖x=‖< int a(5),b(9); swap1(a , b); cout<<‖a=‖<形参指针所指向的实参值来间接改变实参值。其特点是形参的改变影响实参。 #include int temp; temp=*x; *x=*y; *y=temp; cout<<\"x=\"<<*x<<\"y=\"<<*y< int a(5),b(9); swap1(&a,&b); cout<<\"a=\"< void swap1 (int &x , int &y) { int temp; temp=x; x=y; y=temp; cout<<‖x=‖< int a(5),b(9); swap1(a , b); cout<<‖a=‖<提问:设计一个函数:exchange(x , y , z),当调用exchange(a ,b ,c)时,将a的内容设置给b,b的内容设置给c,c的内容设置给a。要求使用两种方法实现。 举例:用函数形式编写程序显示杨辉三角形: #include int i,j; int a[n][n]; for (i=0;i cout<<\"打印杨辉三角形如下:\"<<\"\\n\"; triangle(); } 五、函数的参数 1、函数参数的求值顺序:在c++中没有规定在函数调用时实参的求值顺序,由编译器自行决定。在一般情况下,参数的求值顺序对程序的运行结果没有影响。但有时也会有影响。此时只需改变程序的书写顺序就可以去掉其二义性。 #include return x+y; } void main () { int x(4),y(6); int z=add_int(++x,x+y); cout< …………… int x(4),y(6); int t=++x; int z=add_int(t,x+y); cout< 在c++语言中,允许在函数的说明或定义时给一个或多个参数指定默认值。但是要求在一个指定了默认值的参数的右边,不能出现没有指定默认值的参数。在函数调用时,当实参数目不足时,编译器将按同样的顺序用说明或定义中的默认值来补足所缺少的实参。 注意:当形参指定的默认值和实参指定的值同时存在时,实参的优先级高,但它们都低于全局变量的优先级。 #include int add_int(int x ,int y=7 , int z=m) { return x+y+z; } void main () { int x(5),y(15),z(20); int s=add_int(x,y); cout< #include for(int I=0;I int m=8; fun(a,m); cout<六、内联函数 引入内联函数主要是解决时间、空间的开销与程序运行效率的平衡问题。函数调用会增加时间上的开销。引入内联函数会增加空间上的开销。 1、内联函数的方法:只需在函数头前加关键字inline即可 例:求1~10的平方 #include return x*x; } void main( ) { for (int I=1;I<=10;I++) { int p=fun(i); cout<2、注意事项: 1)、在内联函数中不允许用循环和开关语句 2)、内联函数的定义必须出现在内联函数第一次被调用之前。 七、函数重载 函数重载是指同一个函数名可以对应着多个函数的实现。每种实现对应一个函数体,这些函数的名字相同,但是函数的参数的类型或者参数的个数不同。调用函数在调用被调用函数时,根据参数的类型来确定具体调用哪个函数。 1、参数类型上不同的函数重载 #include double add(double ,double); void main( ) { cout< return x+y } double add(double x ,double y) { return x+y } 2、参数个数上不同的函数重载 #include int min(int a,int b,int c); int min(int a,int b,int c,int d); void main( ) { cout< return aint min(int a,int b,int c) { int t=min(a,b); return min(t,c); } int min(int a,int b,int c,int d) { int t1=min(a,b); int t2=min(c,d); return min(t1,t2); } 八、函数的嵌套调用 嵌套调用指的是在调用A函数的过程中,可以调用函数B,在调用B函数的过程中,还可以调用函数C…..。当C函数结束后返回到函数B,当B函数调用结束后返回到函数A。 例:#include int sum_of_power(int k,int n); int power(int m,int n); void main( ) { cout<<‖sum of‖< int sum=0; for(int I=1;I<=n;I++) sum+=power(I,k); return sum; } int power(int m,int n) { int I,pro=1; for(I=1;I<=n;I++) pro*=m; return pro; } 九、函数的递归调用 递归调用是指在调用一个函数的过程当中直接或间接的调用函数自身。(直接调用自身称为直接递归调用;间接调用自身称为间接递归调用) 1、递归调用的过程; 1)、递推阶段 2)、回归阶段 例:编程实现从键盘上输入一个数存入变量n中,求!。 #include int n; cout<<‖input a positive integer:‖; cin>>n; long fa=fac(n); cout< long int p; if(n= =0) p=1; else p=n*fac(n-1); return p; } 十、标识符的作用域(作用范围) 1、标识符的作用域的规则:标识符只能在说明它或定义它的范围是可见的,而在该范围之外是不可见的。 说明: 1)、可见是指可以进行存取或访问操作的,不可见是指不可以进行存取或访问操作的。 2)、大多数的标识符对它说明或定义是同一回事,只有少数的标识符对它说明和定义是两回事。例如:外部变量、函数和类等。 3)、标识符通常包括:常量名、变量名、类名、函数名、对象名、语句标号、数组名、指针名等等。 2、作用域的种类: 1)、程序级:a、组成:外部函数和外部变量 b、作用域:该程序的所有文件。 c、注意:此类标识符在操作之间一般都要先说明。 2)、文件级:a、组成:内部函数、外部静态变量和用宏定义的符号常量 b、作用域:定义它的文件内部。 3)、函数级:a、组成:函数参数、内部静态变量和在函数内定义的自动类变量。 b、作用域:定义它的函数内部。 c、注意:此类标识符不包括在函数里面的分程序、if、switch和循环语句内定义的变量。 4)、块级: a、组成:分程序、if、switch和循环语句内定义的自动类变量和内部静态变量。 b、作用域:相应结构内部。 3、关于重新定义标识符的作用域规定: 1)、在c++中,一般不允许在相同的作用域内定义同名的变量,但是在不同的作用域内可以定义同名的变量。 2)、重新定义标识符的作用域规定:在某个作用域范围内定义的标识符在该范围内的子范围内可以重新定义该标识符,这时原标识符在子范围内是不可见的,但是它还是存在的,只是被子范围内的同名标识符暂时隐藏起来,当子范围过去之后,原来的标识符又是可见的。 例1:#include int a=5,b=7,c=10; cout<int b=8; float c=8.8; cout<< a<<‖,‖<int c; c=b; cout<< a<<‖,‖<cout<< a<<‖,‖<cout<< a<<‖,‖<例2、#include int x=3; for (;x>0;x--) { int x=5; cout< A、组成:自动类变量、寄存器类变量、内部静态变量和函数的参数。 B、作用域:在所定义的函数体或分程序内部。 C、自动类变量:定义在函数体或分程序内的一种变量,定义时可加auto说明符,但其说明符也可省略。 D、寄存器类变量:定义在函数体或分程序内的一种变量,定义时前边加说明符rigester。 E、内部静态变量:定义在函数体或分程序内的一种变量,在定义时前边加static说明符,它的作用域与上述变量相同,但它的生存期更长(即在在定义它的作用域外,它虽然不可见,但是它仍然存在,它的值没有被释放,一旦它回到作用域后,仍然保留其原来的值。 例、#include int a=3; register int b=5; static int c; cout<<‖a=‖<void other( ) { int a=5; static int b=12; a+10; b+=20;例2、#include 3、使用数组作函数参数的情况(3种情况结果相同,只是调用方式不同,因为它们都是形参和实参共用内存中的同一个数组)。 1)、形参和实参都用数组 2)、形参和实参都用对应数组的指针或者它们当中任意一个是指针。 3)、实参用数组名形参用引用