写在前面 由于我也是第一次学习C++,很多概念我自己也不清楚,所以此处基本上用来记录我学习过程中写的代码 各类概念和知识点理论,则是想到多少学到多少记多少。
C++基础部分 输出helloworld代码 1 2 3 4 5 6 7 8 9 10 11 #include <iostream> using namespace std;int main () { cout << "hello world" << endl; system ("pause" ); return 0 ; }
第六行cout语句实现了输出的功能,除去第六行的语句,整体就是C++代码的基本框架 类似java中的类体+方法体
注释 C++的注释有以下几种
单行注释 //
多行注释 /**/ 同样的,编译器编译代码的时候,会忽略注释的内容。
C++基本 语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
变量和常量 变量基本介绍 变量存在的意义: 管理内存空间 变量创建语法:数据类型 变量名 = 变量初始值;
1 2 3 4 5 6 7 8 9 10 11 12 13 int a = 10 #include <iostream> using namespace std;int main () { int a = 1 ; cout << "a=" << a << endl; system ("pause" ); return 0 ;
常量 c++中和java中不一样 还存在常量,常量就是定义之后不可以发生改变的数据 可以看成java中用final修饰的变量 定义的两种方法 1、用#define定义在文件的上方 作为宏常量
2、用const修饰一个变量 const 数据类型 数据名 = 数据值 两种方法定义的常量都不可以发生改变 如果尝试在代码中改变就会报错
关于const:我认为的const本质:限定修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std;#define day 7 int main () { const int month = 12 ; cout << "a year have " << month << " months" << endl; cout << "a week have " << day << " days" << endl; system ("pause" ); return 0 ; }
基本数据类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 #include <iostream> using namespace std;#include <string> int main () { short num1 = 10 ; int num2 = 10 ; long num3 = 10 ; long long num4 = 10 ; cout << "num1 = " << num1 << endl; cout << "num2 = " << num2 << endl; cout << "num3 = " << num3 << endl; cout << "num4 = " << num4 << endl; cout << "num4 的大小: " <<sizeof (num4) << endl; cout << "short 的大小: " <<sizeof (short ) << endl; float f1 = 3.14f ; cout << "f1 = " << f1 << endl; cout << "f1 的大小: " << sizeof (f1) << endl; double d1 = 3.14 ; cout << "d1 = " << f1 << endl; cout << "d1 的大小: " << sizeof (d1) << endl; float f2 = 3e2 ; cout << "f2 = " << f2 << endl; cout << "f2 的大小: " << sizeof (f2) << endl; float f3 = 3e-2 ; cout << "f3 = " << f3 << endl; cout << "f3 的大小: " << sizeof (f3) << endl; char ch1 = 'a' ; cout << "ch1 = " << ch1 << endl; cout << "ch1 的大小: " << sizeof (ch1) << endl; cout << "ch1 " << ch1 << endl; cout << "转义字符\\ n " << "\n" << endl; cout << "hello\n world " << endl; cout << "转义字符\\ t " << "\t" << endl; cout << "转义字符\\ \ " << "\\" << endl; cout << "hello world \n" ; cout << "aaa\t hello world " << endl; cout << "aaaa\t hello world " << endl; cout << "aaaaa\t hello world " << endl; cout << "aaaaaa\t hello world " << endl; cout << "aaaaaaa\t hello world " << endl; char str1[] = "hello world" ; cout <<"str1:" << str1 << endl; string str2 = "hello world" ; cout << "str2:" << str2 << endl; bool bl1 = true ;; bool bl2 = false ;; cout << "bl1 = " << bl1 << endl; cout << "所占字节: " << sizeof (bl1) << endl; cout << "bl1 = " << bl2 << endl; cout << "所占字节 " << sizeof (bl1) << endl; system ("pause" ); return 0 ; }
数据的输入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <iostream> #include <string> using namespace std;int main () { int a1 = 0 ; cout << "请给整型变量a1赋值:" << endl; cin >> a1; cout << "现在a的值:" << a1<<endl; double a2 = 0.0 ; cout << "请给浮点型a2赋值:" << endl; cin >> a2; cout << "现在a2的值:" << a2 << endl; char a3 = '0' ; cout << "请给字符型a3赋值:" << endl; cin >> a3; cout << "现在a3的值:" << a3 << endl; string a4 = "0" ; cout << "请给字符串型a4赋值:" << endl; cin >> a4; cout << "现在a4的值:" << a4 << endl; bool a5 = 0 ; cout << "请给布尔型a5赋值:" << endl; cin >> a5; cout << "现在a5的值:" << a5 << endl; system ("pause" ); + return 0 ; }
基本运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 #include <iostream> #include <string> using namespace std;int main () { int n1 = 0 ; int n2 = 0 ; cout << "给 整型数据 n1赋值:" << endl; cin >> n1; cout << "给 整型数据 n2赋值:" << endl; cin >> n2; int n3 = n1; int n4 = n2; cout << "加:" << n1 + n2 << endl; cout << "减:" << n1 - n2 << endl; cout << "乘:" << n1 * n2 << endl; cout << "除:" << n1 / n2 << endl; cout << "取余:" << n1 % n2 << endl; n1 = ++n2; cout << "n1 = ++n2 " <<"n1:" <<n1<<"n2:" << n2 << endl; n1 = n3; n2 = n4; n1 = n2++; cout << "n1 =n2++ " << "n1:" << n1 << "n2:" << n2 << endl; n1 = n3; n2 = n4; n1 = --n2; cout << "n1 = --n2 " << "n1:" << n1 << "n2:" << n2 << endl; n1 = n3; n2 = n4; n1 = n2--; cout << "n1 = n2-- " << "n1:" << n1 << "n2:" << n2 << endl; int m1 = 10 ; float m2 = 3.14 ; float m3 = 3.1415926535f ; double m4 = 3.1415926535 ; cout << m1 / m2 << endl; cout << m3 << endl; cout << m4 << endl; int z1 = 10 ; int z2 = z1 += 1 ; cout << "z1+=1:" << z2 << endl; z2 = z1 -= 1 ; cout << "z1-=1:" << z2 << endl; n1 = 0 ; n2 = 1 ; cout << "n1 = " << n1 << "/n" << "n2 = " << n2 << endl; bool z3 = (n1 && n2); cout << "n1 && n2:" << z3 << endl; z3 = (n1 || n2); cout << "n1 || n2:" << z3 << endl; system ("pause" ); return 0 ; }
循环结构和分支结构 if分支 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream> #include <string> using namespace std;int main () { int score = 0 ; cout << "please enter a score" << endl; cin >> score; cout << "you score is:" <<score<< endl; if (score > 100 ) { cout << "you can go to the college!" << endl; } else if (score > 60 ) { cout << "Maybe next time" << endl; } else { cout << "stupid" << endl; } system ("pause" ); return 0 ; }
if循环练习 三只小猪称体重,找出最大的那一只
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <iostream> #include <string> using namespace std;int main () { int p1 = 0 ; int p2 = 0 ; int p3 = 0 ; cout << "请输入第一只小猪的体重 \n " ; cin >> p1; cout << "第一只小猪的体重是:" << p1 << endl; cout << "请输入第二只小猪的体重 \n " ; cin >> p2; cout << "第二只小猪的体重是:" << p2 << endl; cout << "请输入第三只小猪的体重 \n " ; cin >> p3; cout << "第三 只小猪的体重是:" << p3<< endl; if (p1 > p2) { if (p1 > p3) { cout << "最重的是第一只小猪,重量为:" << p1 << endl; } else { cout << "最重的是第三只小猪,重量为:" << p3 << endl; } } else { if (p2 > p3) { cout << "最重的是第二只小猪,重量为:" << p2 << endl; } else { cout << "最重的是第三只小猪,重量为:" << p3 << endl; } } system ("pause" ); return 0 ; }
三目运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> #include <string> using namespace std;int main () { int a = 10 ; int b = 20 ; int c = 0 ; c= (a > b ? a : b); cout << c << endl; (a > b ? a : b) = 100 ; cout <<"a:" << a << endl; cout <<"b:" << b << endl; system ("pause" ); return 0 ; }
switch和do while基本语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { short int a1 = 0 ; cout << "please enter your score:" << endl; a1 = 1 ; switch (a1) { case 10 : case 9 : cout << "经典" << endl; break ; case 8 : case 7 : cout << "非常好" << endl; break ; case 6 : case 5 : cout << "一般" << endl; break ; default : cout << "不行" << endl; break ; } int n1 = 0 ; while (n1 < 10 ) { cout << n1 << endl; n1++; } srand ((unsigned int )time (NULL )); int a2 = (rand () % 100 ) + 1 ; int b1 = (rand () % 100 ) + 1 ; cout << a2 << endl; cout << b1 << endl; int b2 = (rand () % 100 ) + 1 ; cout << b2 << endl; int a3 = 0 ; cout << "enter your guess:" << endl; cin >> a3; int a4 = 0 ; while (1 ) { if (a3 > a2) { cout << "a2 is smaller" << endl; cin >> a3; a4++; } else if (a3 < a2) { cout << "a2 is bigger" << endl; cin >> a3; a4++; } else { cout << "you god damn right" << endl; cout << "you guess " << a4 << " times" << endl; break ; } } int n2 = 0 ; do { cout << n2 << endl; n2++; } while (n2 < 10 ); system ("pause" ); return 0 ; }
水仙花数练习 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <string> using namespace std;int main () { int num = 100 ; do { int a1 = 0 ; int a2 = 0 ; int a3 = 0 ; a1 = num % 10 ; a2 = (num/10 )%10 ; a3 = num/100 ; int b1 = a1 * a1 * a1; int b2 = a2 * a2 * a2; int b3 = a3 * a3 * a3; int c1 = b1 + b2 + b3; if ( c1 == num ) { cout << num << endl; } num++; } while (num < 1000 ); system ("pause" ); return 0 ; }
for循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { for (int i = 0 ; i < 10 ; i++) { cout << i << endl; } int a = 0 ; for (; a < 10 ; a++) { cout << a << endl; } system ("pause" ); return 0 ; }
for循环练习案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { for (int i = 1 ; i < 100 ; i++) { int a = (i % 10 ); int b = i / 10 ; if (a == 7 ) { cout << "flap desk" << endl; } else if (b == 7 ){ cout << "flap desk" << endl; } else if (i % 7 ==0 ) { cout << "flap desk" << endl; } else { cout << i << endl; } } system ("pause" ); return 0 ; }
嵌套循环练习 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { for (int i = 0 ; i < 11 ; i++) { for (int j = 0 ;j<11 ; j++) { cout << " *" ; } cout << endl; } system ("pause" ); return 0 ; }
打印乘法口诀表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { for (int i = 1 ; i < 10 ; i++) { for (int j = 1 ; j <= i; j++) { cout << i << "x" << j << "=" << i * j << " " ; } cout << endl; } system ("pause" ); return 0 ; }
跳转语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { cout << "please choice level" << endl; cout << "1、easy" << endl; cout << "2、normal" << endl; cout << "3、difficult" << endl; int select = 0 ; cin >> select; switch (select) { case 1 : cout << "you choice easy mode" << endl; break ; case 2 : cout << "you choice normal mode" << endl; break ; case 3 : cout << "you choice difficult mode" << endl; break ; default : break ; } for (int i = 0 ; i < 10 ; i++) { if (i == 5 ) { break ; } cout << i << endl; } for (int i = 0 ; i < 11 ; i++) { for (int j = 0 ; j < 11 ;j++) { if (j==5 ) { break ; } cout << " *" ; } cout << endl; } system ("pause" ); return 0 ; }
数组 一维数组 一维数组定义的三种方法
数据类型 数据名 [数组长度]; 数据类型 数据名 [数组长度] = {值1,值2}; 数据类型 数据名 [] = {值1,值2};
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int arr1[5 ]; arr1[0 ] = 10 ; arr1[1 ] = 20 ; arr1[2 ] = 30 ; arr1[3 ] = 40 ; arr1[4 ] = 50 ; cout << arr1[0 ] << endl; int arr2[5 ] = { 10 ,20 ,30 ,40 ,50 }; for (int i = 0 ; i < 5 ; i++) { cout << arr2[i] << endl; } int arr3[5 ] = { 10 ,20 ,30 }; cout << arr3[4 ] << endl; int arr4[] = { 9 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1 }; for (int i = 0 ; i < 9 ; i++) { cout << arr4[i] << endl; } system ("pause" ); return 0 ; }
一维数名的用途 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int arr1[5 ] = { 10 ,20 ,30 ,40 ,50 }; cout << sizeof (arr1[0 ]) << endl; cout << sizeof (arr1) << endl; cout << sizeof (arr1)/ sizeof (arr1[0 ]) << endl; cout << arr1 << endl; cout << &arr1[0 ] << endl; cout << (int )arr1 << endl; cout << (int ) & arr1[0 ] << endl; cout << (int ) & arr1[1 ] << endl; arr1[0 ] = 20 ; cout << arr1[0 ] << endl; system ("pause" ); return 0 ; }
一维数组练习 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int pig[5 ] = { 100 ,300 ,500 ,200 ,400 }; int j = 0 ; for (int i = 0 ; i < 5 ; i++) { if (pig[i] > j) { j = pig[i]; } else { continue ; } } cout << j << endl; system ("pause" ); return 0 ; }
冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int arr1[] = { 4 ,9 ,8 ,0 ,5 ,7 ,1 ,3 ,2 }; int length = sizeof (arr1) / sizeof (arr1[0 ]); cout << "数组长度" << length << endl; int times = length - 1 ; int tempo = 0 ; for (int i = 0 ; i < times; i++) { for (int j = 0 ; j < times - i; j++) { if (arr1[j] > arr1[j+1 ]) { tempo = arr1[j]; arr1[j] = arr1[j + 1 ]; arr1[j + 1 ] = tempo; } } } cout << "冒泡排序 排序后" << endl; for (int i = 0 ; i < length; i++) { cout << arr1[i]; } cout << endl; system ("pause" ); return 0 ; }
二维数组 二维数组的四种定义方式
1 2 3 4 数据类型 数据名[行数][列数]; 数据类型 数据名[行数][列数]={{数据1,数据2},{数据3,数据4}}; 数据类型 数据名[行数][列数]={数据1,数据2,数据3,数据4}; 数据类型 数据名[][列数]={数据1,数据2,数据3,数据4}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int arr[2 ][3 ]; arr[0 ][0 ] = 1 ; arr[0 ][1 ] = 2 ; arr[0 ][2 ] = 3 ; arr[1 ][0 ] = 4 ; arr[1 ][1 ] = 5 ; arr[1 ][2 ] = 6 ; for (int i = 0 ; i < 2 ; i++) { for (int j = 0 ; j < 3 ; j++) { cout << arr[i][j]; }cout << endl; } int arr2[2 ][3 ] = { {1 ,2 ,3 }, {4 ,5 ,6 } }; for (int i = 0 ; i < 2 ; i++) { for (int j = 0 ; j < 3 ; j++) { cout << arr2[i][j]; }cout << endl; } int arr3[2 ][3 ] = {1 ,2 ,3 ,4 ,5 ,6 }; for (int i = 0 ; i < 2 ; i++) { for (int j = 0 ; j < 3 ; j++) { cout << arr3[i][j]; }cout << endl; } int arr4[][3 ] = { 1 ,2 ,3 ,4 ,5 ,6 }; for (int i = 0 ; i < 2 ; i++) { for (int j = 0 ; j < 3 ; j++) { cout << arr3[i][j]; }cout << endl; } system ("pause" ); return 0 ; }
二维数组名的用途 查看二维数组所占内存空间 获取二维数组首地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int arr1[2 ][3 ] = { {1 ,2 ,3 }, {4 ,5 ,6 } }; cout << "二维数组所占内存空间:" << sizeof (arr1) << endl; cout << "二维数组第一行所占内存 :" << sizeof (arr1[0 ]) << endl; cout << "二维数组第一个元素所占内存 :" << sizeof (arr1[0 ][0 ]) << endl; cout << "二维数组有多少行 :" << sizeof (arr1)/ sizeof (arr1[0 ]) << endl; cout << "二维数组有多少列 :" << sizeof (arr1[0 ]) / sizeof (arr1[0 ][0 ]) << endl; cout << "二维数组的首地址" << (int )arr1 << endl; cout << "二维数组第一行的首地址" << (int )arr1[0 ] << endl; cout << "二维数组第二行的首地址" << (int )arr1[1 ] << endl; system ("pause" ); return 0 ; }
二维数组应用案例 在一次考试中成绩分别如下表,请分别输出三名同学的总成绩
语文
数学
英语
张三
100
100
100
李四
90
50
100
王五
60
70
80
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { cout << "========自己写的==========" << endl; int score[3 ][3 ] = { {100 ,100 ,100 }, {90 ,50 ,100 }, {60 ,70 ,80 } }; int sum = 0 ; string name = "" ; for (int i = 0 ; i < 3 ; i++) { for (int j = 0 ; j < 3 ; j++) { sum += score[i][j]; } switch (i) { case 0 : name = "张三" ; break ; case 1 : name = "李四" ; break ; case 2 : name = "王五" ; break ; default : break ; } cout << name << "的总成绩:" << sum << endl; sum = 0 ; } cout << "========视频写的==========" << endl; int score2[3 ][3 ] = { {100 ,100 ,100 }, {90 ,50 ,100 }, {60 ,70 ,80 } }; string name1[3 ] = { "张三" ,"李四" ,"王五" }; for (int i = 0 ; i <3 ; i++) { int sum2 = 0 ; for (int j = 0 ; j < 3 ; j++) { sum2 += score2[i][j]; cout << score[i][j]<<" " ; } cout <<"\n" << name1[i] << "的总分为:" << sum2 << endl; } system ("pause" ); return 0 ; }
函数 概述 作用:将一段经常使用的代码封装起来,减少重复代码 一个较大的程序,一半分为若干个程序块,每个模块时下按特定的功能
函数的定义 函数的定义一般主要有五个步骤 1、返回值类型 2、函数名 3、参数列表 4、函数体语句 5、return表达式语法 :
1 2 3 4 5 返回值类型 函数名 (参数列表) { 函数体 return语句 }
定义一个加法函数,传入两个参数,相加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream> #include <string> #include <ctime> using namespace std;int add ( int num1,int num2 ) { int sum = num1 + num2; return sum; } int main () { int a1 = add (1 , 2 ); int a2 = 10 ; int a3 = 20 ; int a4 = add (a2, a3); int a5 = add (a1, a2); cout << add (1 , 2 ) << endl; cout << "a1:" <<a1 << endl; cout << "a4:" <<a4 << endl; cout << "a5:" <<a5 << endl; system ("pause" ); return 0 ; }
函数调用,形参和实参 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <string> using namespace std;int add (int num1, int num2) { int sum = num1 + num2; return sum; } int main () { int c = add (a, b); system ("pause" ); return 0 ; }
值传递 所谓值传递,就是函数调用时实参将数值传入给形参 值传递时,如果形参发生改变,并不会影响实参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <string> using namespace std;int add (int num1, int num2) { int sum = num1 + num2; return sum; } void swap (int n1, int n2) { cout << "before" << endl; cout << "n1=" << n1<< endl; cout << "n2=" << n2<< endl; int n3 = n1; n1 = n2; n2 = n3; cout << "after" << endl; cout << "n1=" << n1 << endl; cout << "n2=" << n2 << endl; } int main () { int a1 = 10 ; int a2 = 20 ; swap (a1, a2); cout << "a1=" << a1 << endl; cout << "a2=" << a2 << endl; system ( "pause" ); return 0 ; }
总结:值传递时,形参改变(修饰)不了实参
函数的常见样式 常见的函数样式有四种 1、无参无返 2、有参无返 3、无参有返 4、有参有返
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream> #include <string> using namespace std;void test01 () { cout << "this is test01" << endl; } void test02 (int a) { cout << "int a is :" << a << endl; } int test03 () { cout << "this is test03" << endl; return 1000 ; } int test04 (int a) { cout << "this is test04" << endl; return a; } int main () { test01 (); test02 (2 ); int a1 = test03 (); cout << "a1=" << a1 << endl; int a2 = test04 (10000 ); cout << "a2=" << a2 << endl; system ("pause" ); return 0 ; }
函数的声明 作用 :告诉编译器函数名称一集如何调用函数。函数的实际主体可以单独定义。 函数的什么可以多次,但是函数的定义只能有一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <string> using namespace std;int max (int a, int b) ;int main () { int a1 = 10 ; int a2 = 20 ; cout << max (a1, a2) << endl; } int max (int a, int b) { return a > b ? a : b; }
函数的分文件编写 作用 :让代码结构更加清晰 函数分文件编写一般有4个步骤 1、创建后缀名为.h的头文件 2、创建后缀名为.cpp的源文件 3、再头文件中写函数的声明 4、在源文件中写函数的定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 swap.h #pragma once #include <iostream> using namespace std;void swap (int a, int b) ;swap.cpp #include "swap.h" void swap (int a, int b) { int tempo = a; a = b; b = tempo; cout << "a = " << a << endl; cout << "b = " << b << endl; } test035. cpp #include <iostream> #include <string> #include <ctime> #include "swap.h" using namespace std;int main () { int a1 = 10 ; int a2 = 20 ; swap (a1, a2); system ("pause" ); return 0 ; }
指针 指针的基本概念 作用:通过指针间接访问内存
内存编号是从0开始记录的,一般用十六进制表示 可以利用指针变量保存地址
指针变量的定义和使用 指针变量定义语法:数据类型 *变量名;
为什么要写数据类型:定义指针时需要指定数据类型,是为了保证指针的正确行为,包括内存访问、数据解释以及指针算术操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream> using namespace std;int main () { int a = 10 ; int * p; p = &a; cout << "a的地址" << &a << endl; cout << "指针p为" << p << endl; *p = 1000 ; cout << "a的现在为" << a << endl; cout << "p现在为" << p << endl; cout << "*p现在为" << *p << endl; system ("pause" ); return 0 ; }
解引用 *p 表示 解引用操作,也就是通过指针 p 获取它所指向的地址,并操作该地址中的数据。 然后指针的定义中
功能上 ,int *p;、int * p; 和 int* p; 是等价的,指向 int 类型的指针。
空格的使用 完全是风格问题,取决于个人或团队的编码习惯。
指针所占内存空间 指针也是种数据类型,那么这种数据类型占用多少内存空间?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> using namespace std;int main () { int a = 10 ; int * p = &a; cout << "size of (int *)" << sizeof (int * ) << endl; cout << "size of (double *)" << sizeof (double * ) << endl; cout << "size of (p)" << sizeof (p) << endl; system ("pause" ); return 0 ; }
空指针和野指针 空指针 :指针变量指向内存中编号为0的空间用途 :初始化指针变量注意 :空指针指向的内存是不可以访问的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std;int main () { int *p = NULL ; system ("pause" ); return 0 ; }
野指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int * p = (int *)0x1100 ; system ("pause" ); return 0 ; }
空指针和野指针都不是我们申请的空间,因此不要访问。
const修饰指针 const 修饰指针有三种情况 const修饰指针 常量指针 const修饰常量 指针常量 const既修饰指针 又修饰常量
常量指针 特点:指针的指向可以修改,但是指针指向的值不可以改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int a = 10 ; int b = 10 ; int c = 20 ; int * p1 = &a; const int * p2 = &a; cout << "*p2 = " << *p2 << endl; p2 = &b; cout << "*p2 = " << *p2 << endl; p2 = &c; cout << "*p2 = " << *p2 << endl; system ("pause" ); return 0 ; }
指针常量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> using namespace std;int main () { int a = 10 ; int b = 10 ; int c = 20 ; int * p2 = &a; int * const p1 = &a; cout << "p1=" << p1 << endl; *p1 = 20 ; cout << "p1=" << p1 << endl; cout << "*p1 = " << *p1 << endl; cout << "a = " << a << endl; system ("pause" ); return 0 ; }
const既修饰指针,又修饰常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int a = 10 ; int b = 20 ; int c = 30 ; const int * const p1 = &a; int const * const p2 = &a; cout << " p1=" << p1 << endl; cout << " p2=" << p2 << endl; cout << " *p1=" << *p1 << endl; cout << " *p2=" << *p2 << endl; system ("pause" ); return 0 ; }
理解看法和总结 :
说一下这一块我整体的看法和总结,首先先来看指针的定义 指针定义过程中的int p = &xxx; 其中 代表他是一个指针,然后p实际上就是一个数字,用来存储内存地址 常量指针,常量作为一个形容词修饰指针,所以const 肯定在 的前面(无所谓在int前后) 所以他作为指针常量,只是指针的 部分被限制住了,在解引用的时候要用到,所以就没办法用了 说人话就是没办法用 p = 10;这种语句来修改内存地址中的数据了。这是常量指针 指针的部分被常量限制了。 然后是指针常量,指针常量在前面,首先是指针 然后才是常量 所以定义的方式是 int const p = &a;这样,然后p的部分本来存储的就是内存地址,被const修饰之后 内存地址就没办法更改了,但是 的部分功能还是正常的,也就是说我们可以解引用修改内存地址中的数据 但是没办法修改引用的内存地址了。 这 p永远都只能指向a 最后是第三种 const int * const p = &a 这种 情况下 既没办法修改地址 也没办法解引用修改值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int a = 10 ; int b = 20 ; int c = 30 ; const int * const p1 = &a; int const * const p2 = &a; cout << " p1=" << p1 << endl; cout << " p2=" << p2 << endl; cout << " *p1=" << *p1 << endl; cout << " *p2=" << *p2 << endl; const int * p3 = &a; p3 = &b; cout << "p3:" << p3 << endl; cout << "*p3:" << *p3 << endl; int * const p4 = &a; *p4 = 30 ; cout << "p4" <<p4<< endl; cout << "*p4" << *p4<< endl; cout << "a=" << a << endl; const int * const p5 = &a; cout << "p5" << p5 << endl; cout << "*p5" << *p5 << endl; system ("pause" ); return 0 ; }
指针和数组 作用 :利用指针访问数组中元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream> using namespace std;int main () { int arr1[10 ] = { 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }; cout << "第一个元素" << arr1[0 ] << endl; int * p = arr1; cout << "利用指针访问第一个元素:" << *p << endl; p++; cout << "P++元素:" << *p << endl; cout << "利用指针遍历数组" << endl; int * p2 = arr1; int length = sizeof (arr1) / sizeof (arr1[0 ]); for (int i = 0 ; i < length; i++) { cout << "第" << i << "个数是" << arr1[i] << endl; cout << *p2 << endl; p2++; } system ("pause" ); return 0 ; }
指针和函数 作用:利用指针做函数参数,可以改变实际参数的值 (引用传递)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> using namespace std;void swap01 (int n1, int n2) { cout << "交换前" << endl; cout << "swap01函数中n1:" << n1 << endl; cout << "swap01函数中n2:" << n2 << endl; int tempo = n1; n1 = n2; n2 = tempo; cout << "交换后" << endl; cout << "swap01函数中n1:" << n1 << endl; cout << "swap01函数中n2:" << n2 << endl; } void swap02 (int *p1 , int *p2) { int tempo = *p1; *p1 = *p2; *p2 = tempo; } int main () { int a = 10 ; int b = 20 ; swap01 (a, b); cout << "main函数中a:" << a << endl; cout << "main函数中b:" << b << endl; swap02 (&a, &b); cout << "地址传递后" << endl; cout << "main函数中a:" << a << endl; cout << "main函数中b:" << b << endl; system ("pause" ); return 0 ; }
指针、数组、函数 封装一个函数,利用冒泡排序,实现对整整形数组的升序排序 举例 int arr1[10]= {4,3,6,9,5,8,2,1,7,5} ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <iostream> #include <string> #include <ctime> using namespace std;void bubbleSort (int * p, int len) { for (int i = 0 ; i < len-1 ; i++) { for (int j = 0 ; j < len - 1 - i; j++) { if (p[j]>p[j+1 ]) { int tempo = p[j]; p[j] = p[j + 1 ]; p[j + 1 ] = tempo; } } } } void printArray (int * p, int len) { for (int i = 0 ; i < len; i++) { cout << p[i]; } } int main () { int arr1[10 ] = { 4 ,3 ,6 ,9 ,5 ,8 ,2 ,1 ,7 ,5 }; int len = sizeof (arr1) / sizeof (arr1[0 ]); printArray (arr1,len); cout << "\n" << "排序前如上" <<"\n" <<"排序后如下" << endl; bubbleSort (arr1, len); printArray (arr1, len); cout << endl; system ("pause" ); return 0 ; }
结构体() 结构体的基本概念 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型 我的感觉就是java中自定义的类,但是好像又不一样
结构体定义和使用 语法:struct 结构体名{结构体成员列表}; 通过结构体创建变量的方式有三种: struct 结构体名 变量名 struct 结构体名 变量名 = {成员值1,成员值2…} 定义结构体时顺便创造变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string name; int age; int score; }s3; void printStudent (Student p1) { cout << "name:" << p1. name << " age:" << p1. age << " score:" << p1. score << endl; } int main () { Student s1; s1. age = 18 ; s1. name = "jack" ; s1. score = 90 ; printStudent (s1); struct Student s2 = { "mike" ,20 ,90 }; printStudent (s2); s3. age = 20 ; s3. name = "fiona" ; s3. score = 95 ; printStudent (s3); system ("pause" ); return 0 ; }
总结 1、定义结构体的关键字是 struct 类似java中的class 不可省略 2、创建结构体变量的时候,关键字stcuct可以省略 3、结构体利用操作符”.”访问成员
结构体数组 作用 :将自定义的结构体放入数组中方便维护 我认为可能跟用java做 管理系统需要把自定义的类放入到arraylist差不多 语法: struct 结构体名 数组名[元素个数 ] = { {},{}…{} }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string name; int age; int score; }; void printStudent (Student p1) { cout << "name:" << p1. name << " age:" << p1. age << " score:" << p1. score << endl; } int main () { struct Student stuArr[3 ] = { {"mike" ,17 ,70 }, {"alice" ,18 ,80 }, {"john" ,19 ,90 } }; stuArr[2 ].name = "jack" ; int len = sizeof (stuArr) / sizeof (stuArr[0 ]); for (int i = 0 ; i < len; i++) { printStudent (stuArr[i]); } system ("pause" ); return 0 ; }
结构体指针 作用:通过指针访问结构体中的成员
利用操作符 - >可以通过结构体指针访问 结构体属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string name; int age; int score; }; void printStudent (Student *p1) { cout << "name:" << p1->name << " age:" << p1->age << " score:" << p1->score << endl; } int main () { Student s1 = { "jack" ,18 ,90 }; Student * p = &s1; printStudent (p); system ("pause" ); return 0 ; }
结构体嵌套结构体 作用 :结构体中的成员可以是另一个结构体例如 :每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string name; int age; int score; }; struct Teacher { int id; string name; int age; Student stu; }; void printTeacherInfo (const Teacher& t) { cout << "Teacher ID: " << t.id << "Teacher Name: " << t.name<< "Teacher Age: " << t.age << endl; cout << "Student Name: " << t.stu.name << "Student Age: " << t.stu.age << "Student Score: " << t.stu.score << endl; } int main () { Student s1 = {"jack" ,18 ,70 }; Student s2 = {"mike" ,19 ,80 }; Student s3 = {"lisa" ,20 ,90 }; Teacher t1 = {1 ,"white" ,40 ,s1}; Teacher t2 = {2 ,"greffin" ,46 ,s2}; Teacher t3 = {3 ,"park" ,38 ,s3}; printTeacherInfo (t1); printTeacherInfo (t2); printTeacherInfo (t3); system ("pause" ); return 0 ; }
结构体做函数参数 作用 :将结构体作为参数 向函数中传递 传递的方式有两种 值传递 地址传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string name; int age; int score; }; void printStudent01 (Student s1) { cout << "值传递函数内" << endl; s1. age = 100 ; cout << "name:" << s1. name << " age:" << s1. age << " score:" << s1. score << endl; } void printStudent02 (Student *p) { cout<<"引用传递函数内" << endl; p->age = 100 ; cout << "name:" << p->name << " age:" << p->age << " score:" << p->score << endl; } int main () { Student s1 = { "jack" ,18 ,70 }; Student s2 = { "mike" ,19 ,80 }; Student s3 = { "alice" ,20 ,90 }; cout << "name:" << s1. name << " age:" << s1. age << " score:" << s1. score << endl; printStudent01 (s1); cout << "值传递修改后" << endl; cout << "name:" << s1. name << " age:" << s1. age << " score:" << s1. score << endl; printStudent02 (&s1); cout << "地址传递修改后" << endl; cout << "name:" << s1. name << " age:" << s1. age << " score:" << s1. score << endl; system ("pause" ); return 0 ; }
结构体中const使用场景 作用 :用const防止误操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <string> using namespace std;struct Student { string name; int age; int score; }; void printStudent (Student s) { cout << "name:" << s.name << " age:" << s.age << " score:" << s.score << endl; } void printStudent02 (const Student* s) { cout << "name:" << s->name << " age:" << s->age << " score:" << s->score << endl; } int main () { Student s1 = { "jack" ,17 ,70 }; printStudent (s1); printStudent02 (&s1); system ("pause" ); return 0 ; }
结构体案例 案例1 案例描述: 学校正在做毕设项目,每名老师带领5个学生,总共有3名老师, 需求如下 设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值最终打印出老师数据以及老师所带的学生数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include <iostream> #include <string> #include <ctime> using namespace std;struct Student { string sname; int score; }; struct Teacher { string tname; Student stuArr[5 ]; }; void allocatSpace (Teacher tArr[], int len) { string nameSeed = "ABCDE" ; for (int i = 0 ; i < len; i++) { tArr[i].tname = "Teacher_" ; tArr[i].tname += nameSeed[i]; for (int j = 0 ; j < 5 ; j++) { tArr[i].stuArr[j].sname = "student_" ; tArr[i].stuArr[j].sname += nameSeed[j]; int random = rand () % 61 + 40 ; tArr[i].stuArr[j].score = random; } } } void printInfo (Teacher tArr[],int len) { for (int i = 0 ; i < len; i++) { cout << "teacher name:" << tArr[i].tname << endl; for (int j = 0 ; j < 5 ; j++) { cout << "\t student name:" << tArr[i].stuArr[j].sname << " score:" << tArr[i].stuArr[j].score << endl; } } } int main () { srand ((unsigned int )time (NULL )); Teacher tArr[3 ]; int len = sizeof (tArr) / sizeof (tArr[0 ]); allocatSpace (tArr, len); printInfo (tArr, len); system ("pause" ); return 0 ; }
案例2 设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。 通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
五名英雄信息如下
1 2 3 4 5 {"刘备" ,23 ,"男" }, {"关羽" ,22 ,"男" }, {"张飞" ,20 ,"男" }, {"赵云" ,21 ,"男" }, {"貂蝉" ,19 ,"女" }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #include <iostream> #include <string> #include <ctime> using namespace std;struct hero { string name; int age; string gender; }; void bubler (hero *p,int len) { for (int i = 0 ; i < len-1 ; i++) { for (int j = 0 ; j < len -1 - i; j++) { if (p[j].age > p[j + 1 ].age) { hero tempo = p[j]; p[j] = p[j + 1 ]; p[j + 1 ] = tempo; } } } } void show (hero* p, int len) { for (int i = 0 ; i < len; i++) { cout << "name:" << p[i].name << " age:" << p[i].age << " gender:" << p[i].gender << endl; } } int main () { hero HeroList[5 ] = { {"刘备" ,23 ,"男" }, {"关羽" ,22 ,"男" }, {"张飞" ,20 ,"男" }, {"赵云" ,21 ,"男" }, {"貂蝉" ,19 ,"女" } }; int len = sizeof (HeroList) / sizeof (HeroList[0 ]); bubler (HeroList, len); show (HeroList, len); system ("pause" ); return 0 ; }
第一大项目 尝试做通讯录管理系统 系统需求 通讯录是一个可以记录亲人、好友信息的工具。 本教程主要利用C++来实现一个通讯录管理系统系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人 显示联系人:显示通讯录中所有联系人信息 删除联系人:按照姓名进行删除指定联系人 查找联系人:按照姓名查看指定联系人信息 修改联系人:按照姓名重新修改指定联系人 清空联系人:清空通讯录中所有信息 退出通讯录:退出当前使用的通讯录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 #include <iostream> #include <string> #include <ctime> #define max 1000 using namespace std;struct Person { string m_name; int m_sex; int m_age; string m_phone; string m_addr; }; struct AddressBooks { struct Person PersonArray[max]; int m_size; }; void showMenu () { cout << "*************************" << endl; cout << "***** 1. 添加联系人 *****" << endl; cout << "***** 2. 显示联系人 *****" << endl; cout << "***** 3. 删除联系人 *****" << endl; cout << "***** 4. 查找联系人 *****" << endl; cout << "***** 5. 修改联系人 *****" << endl; cout << "***** 6. 清空联系人 *****" << endl; cout << "***** 0. 退出通讯录 *****" << endl; cout << "*************************" << endl; } void addPerson (AddressBooks * abs) { if (abs->m_size ==max) { cout << "通讯录已满,无法继续添加!" << endl; return ; } else { string name; cout << "请输入姓名" << endl; cin >> name; abs->PersonArray[abs->m_size].m_name = name; int gender = 0 ; cout << "请输入性别" << endl; cout << "1--男,2--女" << endl; while (true ) { cin >> gender; if (gender == 1 || gender == 2 ) { abs->PersonArray[abs->m_size].m_sex = gender; break ; } cout << "输入有误,请重新输入" << endl; } cout << "请输入年龄:" << endl; int age = 0 ; cin >> age; abs->PersonArray[abs->m_size].m_age = age; cout << "请输入联系电话:" << endl; string phone = "" ; cin >> phone; abs->PersonArray[abs->m_size].m_phone = phone; cout << "请输入住址:" << endl; string address = "" ; cin >> address; abs->PersonArray[abs->m_size].m_addr = address; abs->m_size++; cout << "添加成功" << endl; system ("pause" ); system ("cls" ); } } void showPerson (AddressBooks* abs) { if (abs->m_size == 0 ) { cout << "当前记录为空" << endl; } else { for (int i = 0 ; i < abs->m_size; i++) { cout << "姓名:" << abs->PersonArray[i].m_name << endl; cout << "性别:" << (abs->PersonArray[i].m_sex==1 ?"男" :"女" ) << endl; cout << "年龄:" << abs->PersonArray[i].m_age << endl; cout << "电话:" << abs->PersonArray[i].m_phone << endl; cout << "住址:" << abs->PersonArray[i].m_addr << endl; } } system ("pause" ); system ("cls" ); } int isExist (AddressBooks* abs, string name) { for (int i = 0 ; i < abs->m_size; i++) { if (abs->PersonArray[i].m_name == name) { return i; } } return -1 ; } void deletePerson (AddressBooks *abs) { cout << "请输入你要删除的联系人" << endl; string name; cin >> name; int ret = isExist (abs, name); if (ret != -1 ) { for (int i = ret; i < abs->m_size; i++) { abs->PersonArray[i] = abs->PersonArray[i + 1 ]; } abs->m_size--; cout << "delete complete!" << endl; }else { cout << "404 not found" << endl; } system ("pause" ); system ("cls" ); } void findPerson (AddressBooks * abs) { cout << "请输入您要查找的联系人" << endl; string name; cin >> name; int ret = isExist (abs, name); if (ret != -1 ) { cout << "姓名:" << abs->PersonArray[ret].m_name << endl; cout << "性别:" << (abs->PersonArray[ret].m_sex == 1 ? "男" : "女" ) << endl; cout << "年龄:" << abs->PersonArray[ret].m_age << endl; cout << "电话:" << abs->PersonArray[ret].m_phone << endl; cout << "住址:" << abs->PersonArray[ret].m_addr << endl; } else { cout << "查无此人" << endl; } system ("pause" ); system ("cls" ); } void modifyPerson (AddressBooks *abs) { cout << "请输入您要修改的联系人" << endl; string name; cin >> name; int ret = isExist (abs, name); if (ret != -1 ) { string name; cout << "请输入姓名" << endl; cin >> name; abs->PersonArray[ret].m_name = name; int gender = 0 ; cout << "请输入性别" << endl; cout << "1--男,2--女" << endl; while (true ) { cin >> gender; if (gender == 1 || gender == 2 ) { abs->PersonArray[ret].m_sex = gender; break ; } cout << "输入有误,请重新输入" << endl; } cout << "请输入年龄:" << endl; int age = 0 ; cin >> age; abs->PersonArray[ret].m_age = age; cout << "请输入联系电话:" << endl; string phone = "" ; cin >> phone; abs->PersonArray[ret].m_phone = phone; cout << "请输入住址:" << endl; string address = "" ; cin >> address; abs->PersonArray[ret].m_addr = address; cout << "修改成功" << endl; } else { cout << "查无此人" << endl; } system ("pause" ); system ("cls" ); } void claenPerson (AddressBooks* abs) { abs->m_size = 0 ; cout << "已清空" << endl; system ("pause" ); system ("cls" ); } int main () { AddressBooks abs; abs.m_size = 0 ; while (true ) { showMenu (); int select = 0 ; cin >> select; switch (select) { case 1 : addPerson (&abs); break ; case 2 : showPerson (&abs); break ; case 3 : deletePerson (&abs); break ; case 4 : findPerson (&abs); break ; case 5 : modifyPerson (&abs); break ; case 6 : claenPerson (&abs); break ; case 0 : cout << "byebye~" << endl; system ("pause" ); return 0 ; break ; default : break ; } } system ("pause" ); return 0 ; }
中途还是有很多问题 但是至此 通讯录管理系统完成
▲C++核心编程 主要是面向对象 技术的详解
内存的分区模型 C++程序在执行时,将内存大方向划分为四个区域 代码区:存放函数体的二进制代码,由操作系统进行管理(cout ,字符) 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
内存四区的意义:不同区域存放 的数据,赋予不同的生命周期,给我们更大的灵活编程。
程序运行前 在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域代码区 : 存放cpu执行的机器指令 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在 内存中有一份 代码即可 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令全局区 : 全局变量和静态变量存放于此 全局区还包含了常量区,字符串常量和其他常量也存放在此 该区域的数据在程序结束后由操作系统释放。
程序运行后 栈区 : 由编译器自动分配释放,存放函数的参数值,局部变量等 注意事项:不要反悔局部变量的地址,栈区开辟的数据由于编译器自动释放堆区 : 由于程序员分配释放,若程序员不释放,程序结束时由操作系统回收 在C++中主要利用new在堆区开辟内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 #include <iostream> #include <string> #include <ctime> using namespace std;int g_a = 10 ;int g_b = 10 ;const int cga = 10 ;const int cgb = 10 ;int * func (int b) { int a = 10 ; return &a; } int * func1 () { int * p = new int (10 ); return p; } int main () { int a = 10 ; int b = 10 ; cout << "局部变量a的地址:" << (int )&a << endl; cout << "局部变量b的地址:" << (int )&b << endl; cout << "全局变量g_a的地址:" << (int )&g_a << endl; cout << "全局变量g_b的地址:" << (int )&g_b << endl; static int s_a = 10 ; static int s_b = 10 ; cout << "静态变量s_a的地址:" << (int )&s_a << endl; cout << "静态变量s_b的地址:" << (int )&s_b << endl; cout << "字符串常量的地址" << (int )&"hello world" << endl; cout << "全局常量cga的地址:" << (int )&cga << endl; cout << "全局常量cgb的地址:" << (int )&cgb << endl; const int cla = 10 ; const int clb = 10 ; cout << "局部常量cla的地址:" << (int )&cla << endl; cout << "局部常量clb的地址:" << (int )&clb << endl; int * p = func1 (); cout << *p << endl; cout << *p << endl; system ("pause" ); return 0 ; }
new操作符(重点) C++中利用new操作符在堆区开辟数据 堆区开辟的数据,由程序员手动开辟,手动释放 ,释放利用操作符delete 语法:new 数据类型 利用new创建的数据,会返回该数据对应的类型的指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> #include <string> #include <ctime> using namespace std;int * func () { int * p =new int (10 ); return p; } void test01 () { int * p = func (); cout << *p << endl; cout << *p << endl; cout << *p << endl; delete p; } void test02 () { int * arr = new int [10 ]; for (int i = 0 ; i < 10 ; i++) { arr[i] = i + 100 ; } for (int i = 0 ; i < 10 ; i++) { cout << arr[i] << endl; } } int main () { test01 (); test02 (); system ("pause" ); return 0 ; }
引用 引用的基本使用 作用 :给变量起别名语法 : 数据类型 & 别名 = 原名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int a = 10 ; int & b = a; b = 20 ; cout << a << endl; system ("pause" ); return 0 ; }
引用的注意事项 引用必须初始化 引用初始化之后就不可以改变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> #include <string> #include <ctime> using namespace std;int main () { int a = 10 ; int c = 20 ; int & b = a; b = c; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c <<endl; system ("pause" ); return 0 ; }
引用作函数参数 作用 :函数传参时,可以利用引用的技术让形参修饰实参优点 :可以简化指针修改实参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <iostream> #include <string> #include <ctime> using namespace std;void myswap01 (int a, int b) { int tempo = a; a = b; b = tempo; } void myswap02 (int * a,int * b) { int tempo = *a; *a = *b; *b = tempo; } void mySwap03 (int & a, int & b) { int tempo = a; a = b; b = tempo; } int main () { int a = 10 ; int b = 20 ; myswap01 (a, b); cout << "a after myswap01:" << a << endl; cout << "b after myswap01:" << b << endl; myswap02 (&a, &b); cout << "a after myswap02:" << a << endl; cout << "b after myswap02:" << b << endl; a = 10 ; b = 20 ; mySwap03 (a, b); cout << "a after myswap03:" << a << endl; cout << "b after myswap03:" << b << endl; system ("pause" ); return 0 ; }
总结:通过引用参数产生的效果和地址传递是一样的。引用的语法更加简单清楚
▲引用做函数返回值 作用:引用是可以作为函数返回值存在的 注意:不要返回局部变量引用 用法:函数调用作为左值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream> #include <string> #include <ctime> using namespace std;int & test01 () { int a = 10 ; return a; } int & test02 () { static int a = 10 ; return a; } int main () { int & ref = test01 (); cout << "ref =" << ref << endl; int & ref2 = test02 (); cout << "ref2 =" << ref2 << endl; test02 () = 1000 ; cout << "ref2 =" << ref2 << endl; system ("pause" ); return 0 ; }
▲引用的本质 本质:引用的本质在C++内部实现是一个指针常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <string> #include <ctime> using namespace std;void func (int & ref) { ref = 100 ; } int main () { int a = 10 ; int & ref = a; ref = 20 ; cout << "a:" << a << endl; cout << "ref:" << ref << endl; func (a); system ("pause" ); return 0 ; }
结论:c++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了 后记:妈的,那老子学那么久的指针是为了什么,牛魔酬宾,把我的时间还给我!
常量引用 作用 :常量引用主要用来修饰形参,防止误操作 在函数形象 列表中,可以加const修饰形参,防止形参改变实参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream> #include <string> #include <ctime> using namespace std;void showValue (const int &val) { cout << "val=" << val << endl; } int main () { int a = 10 ; int & ref = a; const int & ref1 = 10 ; int a1 = 100 ; showValue (a1); cout << "a1=" << a1 << endl; system ("pause" ); return 0 ; }
函数提高(重要) 函数默认参数(重要) 在C++中,函数的形参列表中的形参是可以有默认值的 语法:返回值类型 函数名 (参数 = 默认值){}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <string> #include <ctime> using namespace std;int func (int a, int b = 20 , int c=30 ) { return a + b + c; } int func3 (int a = 11 , int b =10 ) ;int func3 (int a =10 , int b = 20 ) { return a + b; } int main () { cout << func (10 ) << endl; cout << func (10 , 30 , 30 ) << endl; system ("pause" ); return 0 ; }
函数占位参数 C++中的函数形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
现阶段函数的占位参数意义不大,但是据说后面会用到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> #include <string> #include <ctime> using namespace std;void func (int a, int =10 ) { cout << "this is func" << endl; } int main () { func (10 ); system ("pause" ); return 0 ; }
函数重载(重要) 函数重载 概述 作用 :函数名可以相同,提高服用性函数重载满足条件 : 同一个作用域下 函数名称相同 函数的参数 类型不同或个数不同或顺序不同
注意 :函数的返回值不可以作为函数重载的条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream> #include <string> #include <ctime> using namespace std;void func01 () { cout << "func的调用" << endl; } void func01 (int a ) { cout << "func(int a )的调用" << endl; } void func01 (double a) { cout << "func(double a )的调用" << endl; } void func01 (int a,double b) { cout << "func(int,double)的调用" << endl; } void func01 (double b, int a) { cout << "func(double,int)的调用" << endl; } int main () { func01 (); func01 (1 ); func01 (1.0 ); func01 (1 ,1.0 ); func01 (1.0 ,1 ); system ("pause" ); return 0 ; }
函数重载注意事项 引用作为重载条件 函数重载碰到函数默认参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <iostream> #include <string> #include <ctime> using namespace std;void func01 (int a,int b) { cout << "func01(int a ,int b)" << endl; } void func01 (int &a) { cout << "func01(int &a)" << endl; } void func01 (const int &a) { cout << "func01(const int a)" << endl; } void func2 (int a) { cout << "func2(int a)" << endl; } void func2 (int a,int b) { cout << "func2(int a,int b)" << endl; } int main () { int a = 1 ; func01 (a); func01 (10 ); system ("pause" ); func2 (a); return 0 ; }
类和对象 C++面向对象的三大特性为:封装、继承、多态 C++认为完事万物皆对象 ,对下昂 上有其属性和行为
例如: 人可以作为对象,属性有姓名、年龄、身高、体重…行为有走、跑、跳、吃饭、唱歌 车也可以作为对象,属性有轮胎、方向盘、车灯.,行为有载人、放音乐、放空调… 具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类,都可以作为地球上的东西一类
封装 封装的意义(重点) 封装是C++面向对象三大特性之一 封装的意义: 将属性和行为作为一个个整体,表现生活中的事物 讲过属性和行为加以权限控制
封装的意义一 : 在设计类的时候,属性和行为写在一起,表现事物语法 :
示例1:设计一个圆类,球圆的周长
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <string> #include <ctime> using namespace std;const double pi = 3.14 ;class Circle { public : int r; double length () { return 2 * pi * r; } }; int main () { Circle c1; c1. r = 10 ; cout << "圆的周长为:" << c1.l ength() << endl; system ("pause" ); return 0 ; }
示例2:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <iostream> #include <string> #include <ctime> using namespace std;class Student { public : string name; int id; void show () { cout << "name:" << name << " id:" << id << endl; } void setName (string sname) { name = sname; } void setId (int nid) { id = nid; } }; int main () { Student s1; s1. name = "jack" ; s1. id = 1 ; Student s2; s2. name = "fiona" ; s2. id = 2 ; s1. show (); s2. show (); s1. setName ("mike" ); s1. show (); s2. setId (3 ); s2. show (); system ("pause" ); return 0 ; }
封装的意义二 (重点):类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有三种: 1、public 公共权限 2、protected 保护权限 3、private 私有权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : string pname; protected : string pcar; private : string password; public : void setFunc () { pname = "jack" ; pcar = "BMW" ; password = "123321" ; } }; int main () { Person p1; p1. pname = "mike" ; system ("pause" ); return 0 ; }
struct和class区别 在c++中 struct和class 唯一的区别 就是默认的访问权限不同
区别 : struct默认权限为公共 class 默认权限为私有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream> #include <string> #include <ctime> using namespace std;class C1 { int a1; }; struct C2 { int a2; }; int main () { C1 obj1; C2 obj2; obj1. a1 = 1 ; obj2. a2 = 2 ; system ("pause" ); return 0 ; }
成员属性设置为私有 优点 1:将所有成员属性设置为私有,可以自己控制读写权限优点 2:对于写权限,我们可以检测数据的有效性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { private : string pname; int page = 18 ; string idol; public : void setName (string name) { pname = name; } string getName () { return pname; } int getAge () { return page; } void setIdol (string name) { idol = name; } void setAge (int a) { if (a<0 || a>150 ) { cout << "不合法字符" << endl; return ; } else { page = a; } } }; int main () { Person p1; p1. setName ("john" ); cout << p1. getName () << endl; p1. getAge (); cout << p1. getAge () << endl; p1. setIdol ("jackson" ); p1. setAge (160 ); cout << p1. getAge () << endl; p1. setAge (70 ); cout << p1. getAge () << endl; system ("pause" ); return 0 ; }
练习案例: 设计立方体类 设计立方体类(Cube) 求出立方体的面积和体积 分别用全局函数和成员函数判断两个立方体是否相等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 #include <iostream> #include <string> #include <ctime> using namespace std;class Cube { private : int length; int wideth; int height; public : int getLen () { return length; } void setLen (int a) { length = a; } int getwide () { return wideth; } void setwide (int a) { wideth = a; } int getHeig () { return height; } void setHeig (int a) { height = a; } int SurF () { int surface = (length * height + length * wideth + height * wideth) * 2 ; return surface; } int volume () { int volume = length * height *wideth; return volume; } bool JudgeInClass (Cube& a) { if (height == a.getHeig () && wideth == a.getwide () && length == a.getLen ()) { return true ; } else { return false ; } } }; bool Judge (Cube& c1, Cube& c2) { if (c1. getHeig () == c2. getHeig () && c1. getwide () == c2. getwide () && c1. getLen () == c2. getLen ()) { return true ; } else { return false ; } } int main () { Cube c1; c1. setLen (7 ); c1. setwide (8 ); c1. setHeig (9 ); cout << "c1 s surface is: " << c1. SurF () << endl; cout << "c1 s volume is: " << c1. volume () << endl; Cube c2; c2. setLen (7 ); c2. setwide (8 ); c2. setHeig (9 ); cout << "c2 s surface is: " << c2. SurF () << endl; cout << "c2 s volume is: " << c2. volume () << endl; bool ret = Judge (c1, c2); if (ret) { cout << "c1 and c2 is same" << endl; } else { cout << "c1 and c2 is not same" << endl; } bool ret1 = c1. JudgeInClass (c2); if (ret1) { cout << "c1 and c2 is same" << endl; } else { cout << "c1 and c2 is not same" << endl; } system ("pause" ); return 0 ; }
点和圆的关系 设计一个圆形类(Circle)和一个点类(Point)计算点和圆的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 #include <iostream> #include <string> #include <ctime> using namespace std; class Point { private : int p_x; int p_y; public : void setX (int x) { p_x = x; } void setY (int y) { p_y = y; } int getX () { return p_x; } int getY () { return p_y; } }; class Circle { private : int c_r; Point c_Center; public : void setR (int a) { c_r = a; } int getR () { return c_r; } void setCenter (Point center) { c_Center = center; } Point getCenter () { return c_Center; } }; void isInCircle (Circle& c, Point& p) { int distance = (c.getCenter ().getX () - p.getX ()) * (c.getCenter ().getX () - p.getX ()) + (c.getCenter ().getY () - p.getY ()) * (c.getCenter ().getY () - p.getY ()); int rad2 = c.getR ()* c.getR (); if (distance > rad2) { cout << "point is out of circle" << endl; } else if (distance == rad2) { cout << "point is on the circle" << endl; } else { cout << "point is in the circle" << endl; } } int main () { Circle c1; c1. setR (10 ); Point center; center.setX (10 ); center.setY (10 ); c1. setCenter (center); Point p1; p1. setX (10 ); p1. setY (20 ); isInCircle (c1, p1); system ("pause" ); return 0 ; }
对象的初始化和清理(重点) 生活中我们卖的电子产品都有出厂设置,在某一天我们不用之后也会删除一些自己的信息数据来保护隐私 C++中的面向对象来源于生活,每个对象也会有初始设置以及对象销毁前的清理数据的设置
构造函数和析构函数(重点) 对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知的 通过杨使用完一个对象或者变量,没有及时清理,也会造成一些安全问题
C+++利用了构造函数和析构函数 解决上述问题,这两个函数将会被自动编译器自动调用,完成对象初始化和清理工作。 对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供的构造和析构函数是空实现 (就是说一行代码都没有 里面是空的)
构造函数 :主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
构造函数语法啊:类名(){} 1.构造函数没有返回值也不写void 2.函数名称与类名相同 3.构造函数可以有参数,因此可以发生重载 4.程序在调用对香港时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数语法: ~类名(){} 1.析构函数,没有返回值也不写void 2..函数名称与类名相同,在名称前加上符号~ 3.析构哈桉树不可以有参数因此不可以发生重载 4.程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : Person () { cout << "构造函数的调用" << endl; } ~Person () { cout << "person 的析构 函数调用" << endl; } }; void test01 () { cout << "现在进入了test01" << endl; Person p; } int main () { Person p1; test01 (); system ("pause" ); return 0 ; }
构造函数的分类以及调用(重点) 两种分类方式: 按参数分:有参构造和无参构造 按类型分:普通构造和拷贝构造
三种调用方式: 括号法 显示法 隐式转换法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int age; public : Person () { cout << "Person构造函数调用" << endl; } Person (int a) { age = a; cout << "Person有参构造函数调用" << endl; } Person (const Person &p) { age = p.age; cout << "Person拷贝构造函数调用" << endl; } ~Person () { cout << "person 析构函数调用" << endl; } }; void test01 () { Person p; Person p2 (10 ) ; Person p3 (p2) ; cout << "age of p2: " << p2. age << endl; cout << "age of p3: " << p3. age << endl; Person p5; Person p6 = Person (10 ); Person p7 = Person (p6); Person (10 ); cout << "匿名对象的下一行" << endl; Person p8 = 10 ; Person p9 = p8; } int main () { test01 (); system ("pause" ); return 0 ; }
拷贝构造函数调用时机 C++中拷贝构造函数调用实际通常有三种情况 使用一个一集创建完毕的对象来初始化一个新对象 值传递的方式给函数参数传值 以值方式返回局部对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int age; Person () { cout << "person默认构造函数调用" << endl; } Person (int tage) { age = tage; cout << "person有参构造函数调用" << endl; } Person (const Person &p) { age = p.age; cout << "person拷贝构造函数调用" << endl; } ~Person () { cout << "person 析构函数调用" << endl; } }; void test01 () { Person p1 (20 ) ; Person p2 (p1) ; cout << "p2 age:" << p2. age << endl; } void doWord (Person p) { } void test02 () { Person p3; doWord (p3); } Person doWork2 () { Person p1; return p1; } void test03 () { Person p = doWork2 (); } int main () { test01 (); test02 (); test03 (); system ("pause" ); return 0 ; }
构造函数调用规则(重要) 默认情况想爱爱,c++的编译器至少给一个类添加三个函数 1、默认构造函数 无参 函数体为空 2、默认析构函数 无参 函数体为空 3、默认拷贝构造函数 对属性值进行拷贝
构造函数调用规则如下: 如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造 如果用户定义拷贝构造函数,c++不会再提供其他构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int Page; Person () { cout << "person 的默认函数调用" << endl; } Person (int age) { cout << "person的有参构造函数" << endl; Page = age; } Person (const Person& p) { Page = p.Page; cout << "Person的拷贝构造函数调用" << endl; } ~Person () { cout << "person 的析构函数调用" << endl; } }; void test01 () { Person p; p.Page = 18 ; Person p2 (p) ; cout << "p2的年龄为" << p2. Page << endl; } void test02 () { Person p1; } int main () { test01 (); system ("pause" ); return 0 ; }
总结 :定义了拷贝构造函数之后编译器不会自动生成任何其他函数。 定义了有参构造函数之后编译器不会自动生成无参构造函数,但是仍会生成拷贝构造函数
深浅拷贝 浅拷贝:简单的赋值拷贝操作(带来的问题 堆区重复释放 这个问题要用深拷贝解决) 深拷贝:在堆区重新申请空间,进行拷贝操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int age; int * pheight; Person () { cout << "调用无参构造函数" << endl; } Person (int a) { cout << "调用有参构造函数" << endl; } Person (int a,int h) { age = a; pheight = new int (h); cout << "调用有参构造函数" << endl; } Person (const Person& p) { age = p.age; cout << "调用拷贝构造函数" << endl; pheight = new int (*p.pheight); } ~Person () { if (pheight != NULL ) { delete pheight; pheight = NULL ; } cout << "调用析构函数" << endl; } }; void test01 () { Person p1 (18 , 160 ) ; cout << "age of p1" << p1. age << "height of p1:" << *p1. pheight << endl; Person p2 (p1) ; cout << "age of p2" << p2. age << "height of p2:" << *p2. pheight << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
总结:如果属性有再堆区开辟,那么一定要自己提供拷贝构造函数,防止浅的拷贝带来的问题
初始化列表 作用 : C++提供了初始化列表语法,用来初始化属性语法 :构造函数()属性1{值1},属性2{值2}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int a; int b; int c; Person ():a (10 ),b (20 ),c (30 ) { } Person (int a1,int b1,int c1) :a (a1), b (b1), c (c1) { } }; void test01 () { Person p1; cout << "p1 a: " << p1. a << endl; cout << "p1 b: " << p1. b << endl; cout << "p1 c: " << p1. c << endl; Person p2 (30 , 20 , 10 ) ; cout << "p2 a: " << p2. a << endl; cout << "p2 b: " << p2. b << endl; cout << "p2 c: " << p2. c << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
类对象作为类的成员 C++类中的成员可以是另一个类的对象
1 2 3 class A {}class B {A a1;}
B类中有对象A作为成员,A为对象成员 那么当创建B对象时,A与B的构造和析构的顺序是谁先谁后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include <iostream> #include <string> #include <ctime> using namespace std;class Phone { public : string brand; Phone (string name) { brand = name; cout << "phone的构造函数的调用" << endl; } ~Phone () { cout << "phone的析构函数的调用" << endl; } }; class Person { public : string Pname; Phone Pphone; Person (string name, string phone):Pname (name),Pphone (phone) { cout << "person构造函数的调用" << endl; } ~Person () { cout << "person 析构函数的调用" << endl; } }; void test01 () { Person p ("张三" , "苹果" ) ; cout << p.Pname << "拿着:" << p.Pphone.brand << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
静态成员(非常重要) 静态成员就是在成员变量和成员函数前加上关键字static 称为静态成员 静态成员分为:
静态成员变量 1 所有对象共享同一份数据 2 在编译阶段分配内存 3 类内声明,类外初始化 静态成员函数 1 所有对象共享同一个函数 2 静态成员函数只能访问静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : static int P_A; private : static int P_B; }; int Person::P_A = 100 ;int Person::P_B = 300 ;void test01 () { Person p; cout << p.P_A << endl; Person p2; p2. P_A = 200 ; cout << p.P_A << endl; } void test02 () { cout << "test02" << endl; Person p3; cout << p3. P_A << endl; cout << Person::P_A << endl; } int main () { test01 (); test02 (); system ("pause" ); return 0 ; }
静态成员函数 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : static int pa; int pb; static void func () { cout <<"func 中 修改前" << pa << endl; pa = 20 ; cout << "func 中 修改后" << pa << endl; cout << "static void func调用" << endl; } private : static void func2 () { cout << "调用func2" << endl; } public : void func3 () { func2 (); } }; int Person::pa = 10 ;void test01 () { Person p; p.func (); Person::func (); p.func3 (); } int main () { test01 (); system ("pause" ); return 0 ; }
C++对象模型和this指针 成员变量和成员函数分开存储 在c++中,类内的成员变量和成员函数分开存储只有静态成员变量才属于类的对象上 空对象的大小是1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { int pa; int pc; static int pb; void func () { } static void func () { } }; int Person::pb = 10 ;void test01 () { Person p; cout << "size of p " << sizeof (p) << endl; } void test02 () { Person p; cout << "size of p " << sizeof (p) << endl; } int main () { test02 (); system ("pause" ); return 0 ; }
this指针概念 通过3.2.1我们知道在C++中成员变量和成员函数是分开存储的 每一个非静态成员函数只会诞生一份函数实例,就是说多个同类型的对象会共用一块代码 那么问题是:这一块代码是如何区分哪个对象调用自己的呢?
C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象。
this指针式隐含每一个非静态成员函数内的一种指针 this指针不需要定义,直接使用即可
this指针的用途: 当形参和成员变量同名的时候,可用this指针来区分 在类型非静态成员你函数中返回对象本身,可使用return *this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int age; Person (int age) { this ->age = age; } Person& PersonAddAge (Person &p) { this ->age += p.age; return *this ; } void PersonAddAge1 () { this ->age += 1 ; } }; void test01 () { Person p1 (18 ) ; cout << "p1的年龄为" << p1. age << endl; } void test02 () { Person p2 (10 ) ; Person p3 (20 ) ; p2. PersonAddAge1 (); cout << "age of p2:" << p2. age << endl; p2. PersonAddAge (p3); cout << "age of p2:" << p2. age << endl; p2. PersonAddAge (p3).PersonAddAge (p3); cout << "age of p2:" << p2. age << endl; } int main () { test02 (); system ("pause" ); return 0 ; }
空指针访问成员函数 C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针
如果用到this指针,需要加以判断保证代码的健壮性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : void showClassName () { cout << "this is Person class" << endl; } int age; void showPersonAge () { if (this == NULL ) { return ; } cout << "age = " << this ->age << endl; } }; void test01 () { Person* p = NULL ; p->showClassName (); p->showPersonAge (); } int main () { test01 (); system ("pause" ); return 0 ; }
const 修饰成员函数 常函数 : 成员函数后加const后我们称为这个函数为常函数 常函数内不可以修改成员变量 成员属性声明时加关键字mutable后,再常函数中依然可以修改
常对象 : 声明对象前加const称该对象为常对象 常对象只能调用常函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : void showPerson () const { this ->b = 100 ; } void func () { } int a; mutable int b; }; void test01 () { Person p; p.showPerson (); } void test02 () { const Person p1; p1. b = 20 ; p1. showPerson (); } int main () { test01 (); system ("pause" ); return 0 ; }
友元(重要) 生活中你的家有客厅(public),有你的卧室(private) 客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去 但是呢,你也可以允许你的朋友进去
在程序里,有些私有属性,也想让类外特殊的一些函数或者类访问,就需要用到友元的技术
友元的木盾就是让一个函数或者类访问另一个类中私有成员
友元的关键字为friend
友元友三种实现 全局做友元 类做友元 成员函数做友元
友元单向不被继承
全局函数做友元 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <string> #include <ctime> using namespace std;class Building { friend void GoodBoy (Building& building) ; public : string LivingRoom; private : string bedroom; public : Building () { this ->LivingRoom = "客厅" ; this ->bedroom = "卧室" ; } }; void GoodBoy (Building & building) { cout << "好基友的全局函数 正在访问" << building.LivingRoom << endl; cout << "好基友的全局函数 正在访问" << building.bedroom << endl; } int main () { Building b1; GoodBoy (b1); system ("pause" ); return 0 ; }
类做友元 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <string> #include <ctime> using namespace std;class Building ;class Building { friend class GoodGay ; public : string LivingRoom; private : string BedRoom; public : Building (); }; class GoodGay { public : Building * building; void visit () ; GoodGay (); }; GoodGay::GoodGay () { building = new Building; } void GoodGay::visit () { cout << "好基友类正在访问" << building->LivingRoom << endl; cout << "好基友类正在访问" << building->BedRoom << endl; } Building::Building () { LivingRoom = "客厅" ; BedRoom = "卧室" ; } void test01 () { GoodGay g1; g1. visit (); } int main () { test01 (); system ("pause" ); return 0 ; }
成员函数做友元 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #include <iostream> #include <string> #include <ctime> using namespace std;class GoodGay ;class Building { friend void GoodGay::visit () ; public : string LivingRoom; private : string BedRoom; public : Building () { this ->LivingRoom = "客厅" ; this ->BedRoom = "卧室" ; } }; class GoodGay { public : GoodGay () { building = new Building; } Building* building; void visit () { cout << "visit函数正在访问: " << building->LivingRoom << endl; cout << "visit函数正在访问: " << building->BedRoom << endl; } void visit2 () { cout << "visit2函数正在访问: " << building->LivingRoom << endl; } }; int main () { GoodGay g1; g1. visit (); system ("pause" ); return 0 ; }
理论上可以访问 实际上代码出错 问题暂时还没有解决 下次可以问问老师
友元定义的三种方式
1 2 3 4 5 6 friend class GoodGay ;friend void GoodBoy (Building& building) ; friend void GoodGay::visit () ;
运算符重载 运算符重载概念:对已有的运算符重新定义,赋予其另一种功能,来适应不同的数据类型
加号运算符重载 作用:实现了两个自定义数据类型相加的运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #include <iostream> #include <string> #include <ctime> using namespace std;class Person { public : int a; int b; }; Person operator +(Person& p1, Person& p2) { Person temp; temp.a = p1. a + p2. a; temp.b = p1. b + p2. b; return temp; } Person operator +(Person& p1, int num) { Person temp; temp.a = p1. a + num; temp.b = p1. b + num; return temp; } void test01 () { Person p1; p1. a = 10 ; p1. b = 10 ; Person p2; p2. a = 10 ; p2. b = 10 ; Person p3 = p1 + p2; cout << "a of p3 = " << p3. a << endl; cout << "b of p3 = " << p3. b << endl; p3 = p3 + 10 ; cout << "a of p3 = " << p3. a << endl; cout << "b of p3 = " << p3. b << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
其他运算符的重载 这里就不展开多说了,基本上都是一样的 可以重载的运算符包括
1 2 3 4 5 左移运算符<<(左移运算符只能利用全局函数重载) 递增运算 ++ 赋值运算符 = 关系运算符 ><=!= 函数调用运算符 ()
继承 继承是面向对象三大特性之一 有些类和类之间存在特殊关系,例如下图中:
我们发现,定义这些类时,下级的成员除了拥有上一级的共性,还有自己的特性。 这个时候我们就可以考虑利用继承的技术,减少重复代码
继承的基本语法 例如我们看到很多网站中 ,都有公共的头部,公共的底部,甚至公共的左侧列表,只有中心内容不同,系欸下啊来我们分别利用普通写法和继承写法来实现页面中的内容,看一下继承存在的意义以及好处。
语法: class 子类名 :继承方式 父类名 子类也叫派生类 父类也叫基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 #include <iostream> #include <string> #include <ctime> using namespace std;class BasePage { public : void header () { cout << "首页、公开课、登陆(公共头部)" << endl; } void footer () { cout << "底部内容" << endl; } void left () { cout << "java python c++等连接(公共分类列表)" << endl; } }; class Java : public BasePage{ public : void content () { cout << "java学科视频" << endl; } }; class Python : public BasePage{ public : void content () { cout << "python学科视频" << endl; } }; void test01 () { cout << "java下载视频的页面如下" << endl; Java j1; j1. header (); j1. content (); j1.l eft(); j1.f ooter(); cout << "=======分割==========" << endl; Python p1; p1. header (); p1. content (); p1.l eft(); p1.f ooter(); } int main () { test01 (); system ("pause" ); return 0 ; }
总结 :
继承的好处:可以减少重复 的代码 class A : public B; A类称为子类或者派生类 B类称为父类或者基类
派生类中的成员,包含两大部分:
一类是从基类继承过来的,一类是自己增加的成员。 从基类继承过来的表现 出共性 自己新增的表现出个性
继承方式 继承的语法:class 子类 :继承方式 父类
继承方式一共有三种 公共继承 保护继承 私有继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 #include <iostream> #include <string> #include <ctime> using namespace std;class Base1 { public : int a; protected : int b; private : int c; }; class Son1 :public Base1{ public : void func () { a = 10 ; b = 10 ; } }; void test01 () { Son1 s1; s1. a = 100 ; } class Base2 :public Base1{ public : int a; protected : int b; private : int c; }; class Son2 :protected Base2{ public : void func () { a = 100 ; b = 100 ; } }; void test02 () { Son2 s2; } class Base3 { public : int a; protected : int b; private : int c; }; class Son3 :private Base3{ public : void func () { a = 100 ; b = 100 ; c = 100 ; } }; void test03 () { Son3 s3; } class GrandSon3 :public Son3{ public : void func () { } }; int main () { system ("pause" ); return 0 ; }
继承中的对象模型 问题 :从父亲继承过来的成员,那些属于子类对象中?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream> #include <string> #include <ctime> using namespace std;class Base { public : int a; protected : int b; private : int c; }; class Son :public Base{ public : int d; }; void test01 () { Son s1; cout << "size of s1: " << sizeof (s1) << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
继承中构造和析构函顺序 子类继承父类后,当创建子类对象,也会调用父类的构造函数
问题:父类和子类的构造和析构顺序是谁先谁后?
继承中的构造和析构顺序如下: 先构造父类,再构造子类,析构的顺序与构造的顺序相反 先进后出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> #include <string> #include <ctime> using namespace std;class Base { public : Base () { cout << "父类中的构造函数" << endl; } ~Base () { cout << "父类中的析构函数" << endl; } }; class Son : public Base{ public : Son () { cout << "子类中的构造函数" << endl; } ~Son () { cout << "子类中的析构函数" << endl; } }; void test01 () { Son s1; } int main () { test01 (); system ("pause" ); return 0 ; }
继承同名成员处理方式 问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或者父类中同名的数据?
访问子类同名成员 直接访问即可 访问父类同名成员 需要加作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream> #include <string> #include <ctime> using namespace std;class Base { public : int a; Base () { a = 100 ; } void func () { cout << "base下func" << endl; } }; class Son :public Base{ public : int a; Son () { a = 200 ; } void func () { cout << "son下func" << endl; } void func (int c) { cout << "son下func" << endl; } }; void test01 () { Son s; cout << "son 下的a= " << s.a << endl; cout << "base 下的a= " << s.Base::a << endl; s.func (); s.Base::func (); s.Base::func (1 ); } void test02 () {} int main () { test01 (); system ("pause" ); return 0 ; }
总结: 子类对象可以直接访问到子类中的同名成员 子类对象加作用域可以访问到父类同名成员 当子类和父类拥有同名成员函数,子类会隐藏掉父类中同名成员函数,加作用域可以访问到父类中同名函数
继承同名静态成员能处理方式 问题:继承中同名的静态成员再子类对象上如何进行访问?
静态成员和非静态成员出现同名,处理方式一致
访问子类同名成员,直接访问即可 访问父类同名成员 需加作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <iostream> #include <string> #include <ctime> using namespace std;class Base { public : static int a; static void func () { cout << "父类的静态函数" << endl; } }; int Base::a = 100 ;class son :public Base{ public : static int a; static void func () { cout << "子类的静态函数" << endl; } }; void test01 () { son s1; cout << "son 的 a" << s1. a << endl; cout << "base 的 a" << s1. Base::a << endl; cout << "son 的 a" << son::a << endl; cout << "base 的 a" << son::Base::a << endl; cout << "base 的 a" << Base::a << endl; s1.f unc(); s1. Base::func (); son::func (); son::Base::func (); } int son::a = 10 ;int main () { test01 (); system ("pause" ); return 0 ; }
多继承语法 c++允许一个类继承多个类
语法:class 子类 :继承方式 父类1,继承方式 父类2
多继承可能会引发父类中同名成员出现,需要加作用域区分
c++实际开发中不建议用多继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <iostream> #include <string> #include <ctime> using namespace std;class Base1 { public : int a; Base1 () { a = 100 ; } }; class Base2 { public : int a; Base2 () { a = 200 ; } }; class Son :public Base1, public Base2{ public : int c; int d; Son () { c = 300 ; d = 400 ; } }; void test01 () { Son s; cout << "子类所占的空间" <<sizeof (s)<< endl; cout << "base1的a" << s.Base1::a << endl; cout << "base2的a" << s.Base2::a << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
总结 :多继承中如果父类出现了同名的情况,子类使用的时候需要加作用域
菱形继承 虚基类 虚继承(重要重要) 菱形继承概念 : 两个派生类继承同一个基类 又有某个类同时继承两个派生类 这种继承被称为菱形继承,或者钻石继承
经典菱形继承案例 :
菱形继承问题 :
羊继承了 动物的数据,鸵同样继承了动物的数据,当羊驼使用数据时,就会产生二义性 羊驼继承自动物的数据继承了两份,其实我们应该清楚,这份数据我们只需要一份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <string> #include <ctime> using namespace std;class Animal { public : int age; }; class Sheep :virtual public Animal{ }; class Camel :virtual public Animal{ }; class Alpaca :public Camel, public Sheep{ }; void test01 () { Alpaca a1; a1. Sheep::age = 18 ; a1. Camel::age = 28 ; cout << "a1.Sheep::age " << a1. Sheep::age << endl; cout << "a1.Camel::age " << a1. Camel::age << endl; cout << "a1.age " << a1. age << endl; } int main () { test01 (); system ("pause" ); return 0 ; }
总结 : 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义 利用虚继承可以解决菱形继承问题
多态 多态的基本概念 多态是C++面向对象三大特性之一 多态分为两类 静态多态:函数重载和运算符重载属于静态多态,复用函数名 动态多态:派生类和虚函数实现运行时多态 静态多态和动态多态区别: 静态多态的函数地址早绑定 - 编译阶段确定函数地址 动态多态的函数地址晚绑定 - 运行阶段确认函数地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> #include <string> #include <ctime> using namespace std;class Animal { public : virtual void speak () { cout << "动物在说话" << endl; } }; class Cat :public Animal{ public : void speak () { cout << "小猫在说话" << endl; } }; class Dog :public Animal{ public : void speak () { cout << "狗叫" << endl; } }; void doSpeak (Animal &animal) { animal.speak (); } void test01 () { Cat c1; doSpeak (c1); Dog d1; doSpeak (d1); } int main () { test01 (); system ("pause" ); return 0 ; }
重点 :动态多态满足条件 1、有继承关系 2、子类重写父类的虚函数
使用条件:父类的指针或者引用指向子类的对象
原理:
多态案例一 计算器类 案例描述 :
分别利用普通写法和多态技术,设计实现两个操作数进行运算的计算器类
多态的优点: 代码组织结构清晰 可读性强 利于前期和后期的扩展以及维护
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 #include <iostream> #include <string> #include <ctime> using namespace std; class Calculator { public : int n1; int n2; int getResutl (string oper) { if (oper == "+" ) { return n1 + n2; } else if (oper == "-" ) { return n1 - n2; } else if (oper == "*" ) { return n1 * n2; } } }; class AbstractCalc { public : int n1; int n2; virtual int getResult () { return 0 ; } }; class AddCalc :public AbstractCalc{ public : virtual int getResult () { return n1 + n2; } }; class SubCalc :public AbstractCalc{ public : virtual int getResult () { return n1 - n2; } }; class MulCalc :public AbstractCalc{ public : virtual int getResult () { return n1 * n2; } }; void test01 () { Calculator c1; c1. n1 = 10 ; c1. n2 = 20 ; cout << "+" << c1. getResutl ("+" ) << endl; cout << "-" << c1. getResutl ("-" ) << endl; cout << "*" << c1. getResutl ("*" ) << endl; } void test02 () { AbstractCalc* abc = new AddCalc; abc->n1 = 10 ; abc->n2 = 20 ; cout << "+ " << abc->getResult () << endl; delete abc; } int main () { test01 (); test02 (); system ("pause" ); return 0 ; }
纯虚函数和抽象类(非常重要) 在多态中,通常父类中虚函数的实现是毫无意义的,主要调用子类重写的内容
因此可以将虚函数改为纯虚函数
纯虚函数语法:virtual 返回值类型 函数名 (参数列表) = 0;
当类中有了纯虚函数,这个类也称为抽象类
抽象类特点:
无法实例化对象 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <iostream> #include <string> #include <ctime> using namespace std;class Base { public : virtual void func () = 0 ; }; class Son1 :public Base{ public :}; class Son2 :public Base{ public : virtual void func () { cout << "func函数调用" << endl; } }; void test01 () { Son2 s1; Base* base = new Son2; base->func (); } int main () { test01 (); system ("pause" ); return 0 ; }
多态案例2 制作饮品 案例描述: 制作音频的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料
利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <iostream> #include <string> #include <ctime> using namespace std;class AbsDrink { public : virtual void boil () = 0 ; virtual void brew () = 0 ; virtual void Pour () = 0 ; virtual void PutSth () = 0 ; void makeDrink () { boil (); brew (); Pour (); PutSth (); } }; class Coffee :public AbsDrink{ public : virtual void boil () { cout << "煮农夫三拳" << endl; } virtual void brew () { cout << "冲咖啡" << endl; } virtual void Pour () { cout << "倒入" << endl; } virtual void PutSth () { cout << "加糖" << endl; } }; class Tea :public AbsDrink{ public : virtual void boil () { cout << "煮矿泉水" << endl; } virtual void brew () { cout << "冲茶叶" << endl; } virtual void Pour () { cout << "倒入" << endl; } virtual void PutSth () { cout << "加枸杞" << endl; } }; void doWork (AbsDrink &a) { a.makeDrink (); } void doWork (AbsDrink *a) { a->makeDrink (); delete a; } void test01 () { Coffee c1; doWork (c1); doWork (new Tea); } int main () { test01 (); system ("pause" ); return 0 ; }
虚析构和纯虚析构 多态使用时,如果 子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构和纯虚析构
虚析构和纯虚析构的共性: 可以解决父类指针释放子类对象 都需要具体的函数实现
虚析构和纯虚析构的区别: 如果是虚析构,该类属于抽象类,无法实例化对象
虚析构语法: virtual ~类名(){}; 纯虚析构语法: virtual ~类名() = 0; 类名::类名(){}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <iostream> #include <string> #include <ctime> using namespace std;class Animal { public : virtual void speak () = 0 ; Animal () { cout << "Animal构造函数调用" << endl; } virtual ~Animal () = 0 ; }; Animal::~Animal () { cout << "Animal纯虚析构函数调用" << endl; } class Cat :public Animal{ public : string *cname; virtual void speak () { cout << *cname<<"喵" << endl; } Cat (string name) { cout << "cat struct func " << endl; cname = new string (name); } ~Cat () { if (cname != NULL ) { cout << "~CAT running" << endl; delete cname; cname = NULL ; } } }; void test01 () { Animal* a1 = new Cat ("Tom" ); a1->speak (); delete a1; } int main () { test01 (); system ("pause" ); return 0 ; }
总结 : 虚析构和纯虚析构就是用来解决通过父类指针释放子类对象 如果子类中没有堆区数据,可以不写为虚构或者纯虚析构 拥有纯虚析构的类也属于抽象类
多态案例3 电脑组装 案例描述:
电脑主要组成部件为CPU 显卡 内存条 将每个零件疯转给出抽象基类 并且提供不同的厂商生产不同的零件 创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口 测试时组装三台不同的电脑进行工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 #include <iostream> #include <string> #include <ctime> using namespace std;class CPU { public : virtual void calculate () = 0 ; }; class GPU { public : virtual void display () = 0 ; }; class Memory { public : virtual void srorage () = 0 ; }; class Computer { public : Computer (CPU* c, GPU* g, Memory* m) { c1 = c; g1 = g; m1 = m; } void work () { c1->calculate (); g1->display (); m1->srorage (); } ~Computer () { if (c1 != NULL ) { delete c1; c1 = NULL ; } if (g1 != NULL ) { delete g1; g1 = NULL ; } if (m1 != NULL ) { delete m1; m1 = NULL ; } } private : CPU* c1; GPU* g1; Memory* m1; }; class IntelCPU :public CPU{ public : virtual void calculate () { cout << "英特尔的cpu开始计算了" << endl; } }; class IntelGPU :public GPU{ public : virtual void display () { cout << "英特尔的显卡开始超频了" << endl; } }; class IntelMemo :public Memory{ public : virtual void srorage () { cout << "英特尔的内存开始RGB了" << endl; } }; class ASUSCPU :public CPU{ public : virtual void calculate () { cout << "ROG的cpu开始计算了" << endl; } }; class ASUSGPU :public GPU{ public : virtual void display () { cout << "ROG的显卡开始超频了" << endl; } }; class ASUSMemo :public Memory{ public : virtual void srorage () { cout << "ROG的内存开始RGB了" << endl; } }; class lenovoCPU :public CPU{ public : virtual void calculate () { cout << "lenovo的cpu开始计算了" << endl; } }; class lenovoGPU :public GPU{ public : virtual void display () { cout << "lenovo的显卡开始超频了" << endl; } }; class lenovoMemo :public Memory{ public : virtual void srorage () { cout << "lenovo的内存开始RGB了" << endl; } }; void test01 () { CPU* intelCpu = new IntelCPU; GPU* intelGpu = new IntelGPU; Memory* intelMemo = new IntelMemo; Computer* c1 = new Computer (intelCpu, intelGpu, intelMemo); c1->work (); delete c1; CPU* cp2 = new ASUSCPU; GPU* g2 = new ASUSGPU; Memory* m2 = new ASUSMemo; Computer* c2 = new Computer (cp2, g2, m2); c2->work (); delete c2; CPU* cp3 = new lenovoCPU; GPU* g3 = new lenovoGPU; Memory* m3 = new lenovoMemo; Computer* c3 = new Computer (cp3, g3, m3); c3->work (); delete c3; } int main () { test01 (); system ("pause" ); return 0 ; }
课程考试部分 特殊及零散知识点 课后练习 1、有如下程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;int f (int x) ;int sum (int n) { int x, s = 0 ; for (x = 0 ; x <= n; x++) s += f (x); return s; } int f (int x) { return (x * x + 1 ); } int main () { int a, b; cout << "Enter an integer number: " ; cin >> a; b = sum (a); cout << a << ", " << b << endl; return 0 ; }
如果输入数字3,其输出结果是: A、 3,12 B、 3,16 C、 3,18 D、 4,20
2有以下程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> using namespace std;int f (int a, int b) ;int main () { int i = 1 , x; x = f (i, i + 1 ); cout << x << endl; return 0 ; } int f (int a, int b) { int c; c = a; if (a > b) c = 1 ; else c = -2 ; return c; }
**运行后的输出结果是: A、 1 B、 0 C、 -1 D、 -2
3、若有以下函数调用语句,在此函数调用语句中实参的个数是
1 fun(a+b,(y=10,y),fun(n,k,d));
A、 3 B、 4 C、 5 D、 6
4、以下函数调用语句中,含有的实参个数是() func(rec1,rec2 +1,(rec3,rec4));
A、 3 B、 4 C、 5 D、 有语法错误
以下程序的输出结果是
1 2 3 4 5 6 7 8 void fun (int a,int b,int c) { a=456 ;b=567 ;c=678 ;}int main () { int x=10 ,y=20 ,z=30 ;fun (x,y,z);cout<<z<<”,”<<y<<”,”<<x<<endl; }
A、 30,20,10 B、 10,20,30 C、 456,567,678 D、 678,567,456
C++语言中,形参与实参之间的数据传递方式是 A、 只能按值传递 B、 只能按引用传递
C、 既可以按值传递也可以按引用传递
D、 以上说法都不对
编程题练习 编程题:学生信息管理 题目描述:
设计一个类 Student,实现学生信息的管理功能。
数据成员:
name:学生的姓名(字符串类型)。
age:学生的年龄(整数类型)。
score:学生的成绩(浮点型)。
静态数据成员:
total_students:记录学生对象的总数量。
成员函数:
构造函数:初始化学生姓名、年龄和成绩,并更新 total_students。
析构函数:销毁对象时,减少 total_students 的数量。
print_info():打印学生的基本信息(姓名、年龄、成绩)。
静态成员函数:
get_total_students():返回当前已创建的学生对象总数量。
主函数要求:
在主函数中:
创建若干个 Student 对象。
调用每个学生对象的 print_info() 函数输出学生信息。
输出当前学生对象的总数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 #include <iostream> #include <string> using namespace std;class Student { public : string name; int age; double score; static int total_students; Student () { } Student (string m_name, int m_age, double m_score) { name = m_name; age = m_age; score = m_score; total_students++; cout << "正在调用学生类的构造函数" << endl; } ~Student () { total_students--; cout << "正在调用学生类的析构函数" << endl; } static int get_total_students () { return total_students; } void print_info () { cout << "学生信息" << endl; cout << "name: " << name << "age: " << age << "score: " << score << endl; } }; int Student::total_students = 0 ;int main () { int n; cout << "请输入要定义的学生数量" << endl; cin >> n; if (n < 1 ) { cout << "非法字符" << endl; return 1 ; } else if (n > 10 ) { cout << "数量过多" << endl; return 1 ; } Student* s1 = new Student[n]; for (int i = 0 ; i < n; i++) { string name; int age; double score; cout << "请输入第" << i+1 << "个学生的信息" << endl; cout << "name:" << endl; cin >> name; cout << "年龄" ; cin >> age; cout << "得分" ; cin >> score; s1[i] = { name,age,score }; } cout << "\n所有学生信息如下" << endl; for (int i = 0 ; i < n; i++) { s1[i].print_info (); } system ("pause" ); return 0 ; }
ppt编程题例题1 定义一个复数类 Complex,重载运算符“+”,使之能用于复数的加法运算。参加运算的两个 运算量可以都是类对象,也可以其中有一个是整数,顺序任意。例如:c1+c2、i+c1 均合法。 (其中 i 是整数,c1、c2 是复数),编程实现求 2 个复数之和、整数与复数之和。 • 主函数如下: int main(){ int r1, i1, r2, i2 ; int i; cin >> r1 >> i1 >> r2 >> i2 >> i; Complex c1(r1, i1), c2(r2, i2), c3; c3 = c1 + c2; c3.display(); c3 = i + c1; c3.display(); return 0; }
ppt编程题例题2 声明一个Shape抽象类,由其派生出Point类,再由Point类派生出Circle类, 三个类均有area( ) 和shapeName()成员。 主函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int main ( ) { Point point (1 ,1 ) ; Circle circle (1 ,1 ,5.6 ) ; Shape *pt; pt=&point; pt->shapeName ( ); cout<< ”x=” <<point.getX ( )<<” , y=” << point.getY ( ) << ” , pointarea=”<<pt->area ( )<<endl; pt=&circle; pt->shapeName ( ); cout<<”x=”<<circle.getX ( )<<” , y=”<<circle.getY ( )<<”, circlearea=”<<pt >area ( ) <<endl; }
1 2 3 程序运行输出如下: Point:x=1,y=1, pointarea=0 Circle:x=1,y=1, circlearea= 98.4
编程题例题4-Building类(非常重要) • 实现一个Building建筑类, • 数据成员包括:编号id、名字name、建筑类型• 静态数据成员包括:总楼数total、下一个楼的编号next • 成员函数包括:构造函数、析构函数、打印信息函数print_info • 静态成员函数:getTotal() • 主函数、样例输入输出见下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 主函数 int main() { string name, type; Building* buildings[3]; for (int i = 0; i < 3; i++) { cin >> name >> type; buildings[i] = new Building(name, type); } cout << "Building counts: " << Building::getTotal() << endl; for (int i = 0; i < 3; i++) { buildings[i]->printInfo(); } } • 样例输入 A_building teach B_building live C_building teach • 样例输出 Building counts: 3 id: 0 A_building, teach id: 1 B_building, live id: 2 C_building, teach
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <string> using namespace std;class Building { public : int id; string name; string type; static int total; static int next; Building () { total++; next++; }; Building (string b,string c) { id = next; name = b; type = c; total++; next++; } ~Building () { total--; } void PrintInfo () { cout << "id:" << id << " , " << name << "," << type << endl; } static int getTotal () { return total; } }; int Building::total = 0 ;int Building::next = 0 ;int main () { string name, type; Building* buildings[3 ]; for (int i = 0 ; i < 3 ; i++) { cin >> name >> type; buildings[i] = new Building (name, type); } cout << "Building counts: " << Building::getTotal () << endl; for (int i = 0 ; i < 3 ; i++) { buildings[i]->PrintInfo (); } }
爷的代码,跑起来辣
编程题例题5 Animal(非常重要) 请实现以下三个类:
一个动物Animal类,包含构造函数、数据成员年龄(age),成员函数getage()、纯虚函数speak()。
再由Animal类派生出两个类:猫Cat类、鸟Bird类。其中Cat类含有数据成员姓名(name);Bird类含有数据成员种类(kind),两个派生类都有speak()函数。
主函数参照以下程序执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int main(){ Animal *pa; Cat ct("Garfield",2); Bird bd("sparrow",1); string x; while(cin>>x){ if(x=="cat") pa=&ct; else if(x=="bird") pa=&bd; pa->speak(); } return 0; } 样例输入: bird cat 样例输出: zizi~I'm a sparrow ,1-year-old. Meow~I'm Garfield , 2-year-old.
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream> #include <string> using namespace std;class Animal { public : int age; Animal () {} ~Animal () {} int getage () { return age; } virtual void speak () = 0 ; }; class Cat :public Animal{ public : string name; void speak () { cout << "喵" << endl; } Cat (string a, int b) { name = a; age = b; } }; class Bird :public Animal{ public : string kind; void speak () { cout << "鸣" << endl; } Bird (string a, int b) { kind = a; age = b; } }; int main () { Animal* pa = nullptr ; Cat ct ("Garfield" , 2 ) ; Bird bd ("sparrow" , 1 ) ; string x; while (cin >> x) { if (x == "cat" ) { pa = &ct; pa->speak (); } else if (x == "bird" ) { pa = &bd; pa->speak (); } } return 0 ; }