370 likes | 567 Views
预备知识. 基础: 已学过“ C 程序设计”这门课程,并掌握数据类型、表达式、基本控制结构(顺序、分支和循环)、数组、指针、函数、以及输入输出等内容。 数据结构课程需要扩充的知识: 1 C++ 的不同的表示 2 自定义数据类型(结构体、枚举类型、联合体) 3 复习函数,介绍函数重载 4 复习指针,介绍动态内存分配. 1 C++ 的不同的表示. ( 1 )输入输出语句 原来使用 scanf( ) 和 printf( ) 函数。
E N D
预备知识 基础: 已学过“C 程序设计”这门课程,并掌握数据类型、表达式、基本控制结构(顺序、分支和循环)、数组、指针、函数、以及输入输出等内容。 数据结构课程需要扩充的知识: 1 C++的不同的表示 2 自定义数据类型(结构体、枚举类型、联合体) 3 复习函数,介绍函数重载 4 复习指针,介绍动态内存分配
1 C++的不同的表示 (1)输入输出语句 原来使用scanf( )和printf( )函数。 现输出使用输出流对象 cout和插入符<<,例: cout << x; cout << “x+y=” << x+y; 输入使用输入流对象 cin和提取符>>,例: cin >> n; cin >> a >> b; 键盘输入时,两数之间用空格隔开。 注意:以上对象和符号在头文件iostream.h中定义,所以,需要在源代码文件的开始包含它。
1 C++的不同的表示 (2)简单的I/O格式控制 endl 插入换行符,并刷新流 setprecision(int) 设置浮点数的小数位数(包括小数点) setw(int) 设置域宽 例 cout << “请输入一个整数:” << endl; a = 3.1415926; cout << setprecision(3) << a << endl; name = “黄俊民”; cout << setw(12) << name;
1 C++的不同的表示 (3)嵌入的头文件 C程序若包含输入输出语句,需要在主函数的前面嵌入 #include “iostream.h” C++则需要 #include “iostream” using namespace std;
1 C++的不同的表示 (4)变量赋初值 int a = 3; 可以写成 int a(3);
2 自定义数据类型 2.1 typedef 声明 为一个数据类型定义一些有具体意义的别名,以后可将别名当作数据类型使用。 如: typedef double area, volume; area a; volume v; a和v还是浮点型数据,但程序可读性增强了。
2 自定义数据类型 2.2 枚举类型(enum) 这种类型也是为了程序的可读性。具体做法是将变量需要的取值一一列举出来,便构成了一个枚举类型。 枚举类型的声明形式如下: enum 枚举类型名 {变量值列表}; 例如: enum weekday {sun,mon,tue,wed,thu,fri,sat}; enum monyh {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
2.2 枚举类型(enum) 枚举类型(enum) 枚举类型应用说明: 对枚举元素按常量处理,不能对它们赋值。例如,不能写:sun=0; Jan=1; 枚举元素具有缺省值,它们依次为: 0,1,2,......。 也可以在声明时另行指定枚举元素的值,如: enum weekday {sun=7,mon=1,tue,wed,thu,fri,sat}; 枚举值可以进行关系运算。 整数值不能直接赋给枚举变量,如需要将整数赋值给枚举变量,应进行强制类型转换。
2.2 枚举类型(enum) 枚举类型(enum) 定义枚举类型变量: enum weekday day_id; enum month month_id; 也可 weekday day_id; month month_id;
枚举类型(enum)举例 口袋中有红、黄、蓝、白、黑五种颜色的球若干个。每次从口袋中取出3个不同颜色的球,问有多少种取法。 分析:由于球只能是五种颜色之一,故可用枚举类型表示球的颜色。设取出的球为i、j、k,根据题意,i、j、k分别可以有五种取值,且i≠j≠k。可以用穷举法,逐个检验每一种可能的组合,从中找出符合要求的组合并输出。
#include <iostream.h> void main( ) { enum color{red,yellow,blue,white,black}; //枚举类型 enum color pri; int n,loop,i,j,k; char c; n=0; for(i=red;i<=black;i++) for(j=red;j<=black;j++) if(i!=j) //前两个球不同 { for(k=red;k<=black;k++)
if((k!=i)&&(k!=j)) //第三个球不同于前两个 { n=n+1; cout<<n; for(loop=1;loop<=3;loop++) { switch(loop) { case 1: pri=(enum color)i; break; case 2: pri=(enum color)j; break; case 3: pri=(enum color)k; break; default: break; }
switch(pri) { case red: cout<<" red"; break; case yellow: cout<<" yellow"; break; case blue: cout<<" blue"; break; case white: cout<<" white"; break; case black: cout<<" black"; break; default: break; } } cout<<endl; } } cout<<"total:"<<n<<endl; }
2 自定义数据类型 2.3 结构类型 将数据对象组织在一起,成为一种组合的数据,对于程序设计十分有用。以前我们学习过“数组”,就是一种组合的数据类型。但是,组成数组的元素,它们的类型都是相同的。 结构类型是一种将不同类型的数据对象组织在一起的数据类型,具体元素及其组织由用户自己定义。
2.3 结构类型 定义结构类型 struct 结构名 { 数据类型 成员名 1; 数据类型 成员名 2; : 数据类型 成员名 n; }; 如 struct planet { char name [MAXSIZE]; float diameter, orbitrad; //星球直径和轨道半径 };
2.3 结构类型 定义结构类型数据 struct 结构名 数据名; 如 struct planet pln; 或者 typedef struct planet PLANET; PLANET pln; 使用结构类型数据 数据名•成员元素名 如 cout << “输入”<< pln.name <<“的数据:”<< endl; cin >> pln.diameter >> pln.orbitrad;
2.3 结构类型 定义指向结构类型数据的指针 struct 结构名 *指针名; 如 struct planet pln, *ppln; 或者 typedef struct planet PLANET; PLANET pln, *ppln; 使用结构类型数据 指针名->成员元素名 如果 ppln=&pln; 那么 cout << “输入”<<ppln->name <<“的数据:”<< endl; cin >> ppln->diameter >> ppln->orbitrad;
例 将月日数转换为年天数的C函数 static int day_tab[2][13]={ {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; struct date { //定义结构类型 int day, month, year; }; int day_of_year(struct date d) { //函数 int i, day, leap; day = d.day; leap=d.year%4==0&&d.year%100!=0||d.year%400==0; for(i=1; i<d.month; i++) day+=day_tab[leap][i]; return(day); }
例 将月日数转换为年天数的C函数 static int day_tab[2][13]={ {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; struct date { //定义结构类型 int day, month, year; }; int day_of_year(struct date *pd) { //函数 int i, day, leap; day = pd->day; leap=pd->year%4==0&&pd->year%100!=0||pd->year%400==0; for(i=1; i<pd->month; i++) day+=day_tab[leap][i]; return(day); }
2.4 联合(共同体) 几个不同类型的数据共用同一组内存单元,这种数据类型称为联合(union)。 联合的定义 union 联合名 { 数据类型1 成员1; 数据类型2 成员2; : : 数据类型n 成员n; }; 联合数据定义 union 联合名 数据变量名;
2.4 联合 联合数据变量的引用: 联合数据变量名•成员名 例 union data { int i; float f; char c; }; union data x; 数据变量x 有4个字节(它的最大成员空间为它的存储空间大小)。若使用x.i,则2个字节;若使用x.f,则4个字节;若使用x.c,则1个字节。
设计一个既能填入学生数据、又能用于教师的数据类型,并用于实际处理。 struct record{ int number; char name[20]; char job; // 学生 s;教师 t union{ int class; // 学生填班级号 char position[12]; //教师填职务 } category; } person[2];
程序中可使用下列形式的语句: int n, i; for(i=0; i<2; i++) { cin >> person[i].number >> person[i].name >> person[i].job; if(person[i].job==‘s’) cin >> person[i].category.class; else if(person[i].job==‘t’) cin >> person[i].category.position; else cout << “input error” << endl; }
3 . 复习函数,介绍函数重载 (1) 函数的定义 函数返回值类型 函数名(形式参数表) { 语句序列 } 其中: ——若无返回值,函数类型为void; ——若无形式参数,形式参数表为void; 否则,形式参数表为: type1 name1, type2 name2, ┅,typen namen
(1) 函数的定义 假如是main()函数,也可有形式参数和返回值。 其中,返回值将被传递给操作系统;而带有形式参数的主函数,具体写成: main(int argc, char *argv[ ]) { 语句序列 } argc表示参数个数 argv[i] /* 0≤i ≤argc-1 */ 指向存储参数的字符串 注意:c语言中的main()函数,常用void来定义类型。但在c++中,则使用int 来定义类型,对于运行正常,能够执行到程序的逻辑结尾处,则return 0;
(2)函数的调用 调用其他函数的函数,称为主调函数;被其他函数调用的函数,称为被调函数。 在调用函数前,需声明函数原形,然后方可调用。函数原形的形式: 函数返回值类型 被调函数名(形式参数表) 函数调用: 函数名(实际参数表) 其中:实际参数表中的参数个数与函数原形的形参个数相同,类型相符,并用逗号分隔。 假若被调函数有返回值,它可出现在表达式中。
(3) 函数的参数传递 ——值调用 函数调用时,给被调函数的形参分配空间,将实参的值传递给形参。被调函数执行完毕,形参的值不影响实参。 ——指针作为函数参数 主调函数的实参指针和被调函数的形参指针指向共同的数据内存空间,被调函数直接处理主调函数的数据,主调函数直接得到被调函数的结果。这样实现参数双向传递。
(3) 函数的参数传递 ——引用调用 引用名是某个变量的别名。在被调函数中,将引用作为形参。主调函数的变量名和被调函数的引用名在调用时实现对应,它们表示的是相同存储空间(存放变量值)的符号地址。 在被调函数中任何对引用的操作,实际上就是对那个存储空间中的值的操作。最后都将在主调函数的实参上反映出来。 具体格式: 返回类型 函数名(参数类型& 引用名,…)
例 两个变量的值互换(1)指针参数(2)引用参数 #include <iostream.h> void swap (int *p1, int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; } int main( ) { int i=3, j=5; swap(&i, &j); cout << i << “,” << j << endl; return 0; }
#include <iostream.h> void swap (int &a, int &b) { int temp; temp=a; a=b; b=temp; } int main( ) { int i=3, j=5; swap(i, j); cout << i << “,” << j << endl; return 0; }
(4) 函数重载 两个以上的函数,使用相同的函数名,但是它们的形式参数的个数或者类型不同。当调用函数时,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用某一个函数,这就是函数的重载。 例如 int add(int x, int y); float add (float x, float y); int add ( int x, int y, int z);
4 复习指针,介绍动态内存分配 (1) 指针变量的定义 指针变量用于存放内存单元的地址。定义指针变量的形式: 数据类型 *指针变量名; 例 int a = 3, b = 2, c; int *pa, *pb; (2)与地址有关的运算符“*”和“&” * 表示取指针所指向的变量的值 & 表示取变量的存储单元的地址 例 pa = &a; pb = &b; c= *pa + *pb;
4 复习指针,介绍动态内存分配 指针与数组 例 int array[10]; int *pa, *pb, x, i; pa = array; // pa 指向 array[0], *pa 就是array[0] pb = pa + 3; // pb指向 array[3], *pb就是array[3] x = *pa + *pb; // 即x= array[0]+ array[3];
4 复习指针,介绍动态内存分配 动态内存分配 在定义数组时, C或C++要求明确元素的个数。但是,在一些具体问题上,元素个数往往难以确定。因此需要在程序执行过程中动态地给变量分配内存。 在C中有这样的函数: ——动态存储分配函数 void *malloc(size) ——动态内存释放函数 void free(void *memblock) 例 int *pi; pi=(int *)malloc(sizeof(int)); free(pi);
(3) 动态内存分配 相应地,在C++中动态内存分配将更加简单。它使用两个运算符 new 和 delete。 new 的功能是动态分配内存;delete 的功能是释放指定的内存空间。 例 int *pi; pi = new int; // pi 指向存放int类型值的存储单元 以上两行可写成一句: int * pi = new int; 释放内存为: delete pi; // 释放pi所指的存储单元
(3) 动态内存分配 new和delete可用来动态地创建一维数组,例 int *pa; pa = new int[10]; //pa指向整型数组的首元素 这个数组有10个元素 delete [ ] pa; // 释放整个数组的存储空间
(3) 动态内存分配 例 void main ( ) { int * pa = new int[2]; *pa = 30; * (pa + 1) = 50; cout << *pa << endl; cout << *(pa+1) << endl; delete [ ] pa; }