目录
一、程序控制
①输入输出
Ⅰ.cin&cout
Ⅱ.scanf&printf
②运算与符号
Ⅰ常用数学函数#include
Ⅱ.数据类型转换
③控制结构
④函数
Ⅰ.函数定义
Ⅱ函数使用
二、数据结构
①一维数组
排序与查找
②多维数组
③指针
Ⅰ字符,指针运算
Ⅱ字符串函数#include
Ⅲ指针参数与动态内存
④结构:struct
⑤链表
三、文件操作
Ⅰ基本文件输入输出
Ⅱ文件指针
四、类和对象
①类的创建和使用
②静态成员
③构造函数
④类的复合
⑤This指针
⑥友元
Ⅰ友元函数
Ⅱ友元类
五、运算符重载
①原理
②方式
Ⅰ成员函数重载
Ⅱ友元函数重载
③单目与双目运算符重载
Ⅰ单目(目表示操作数)
Ⅱ流插入和流提取运算符的重载
Ⅲ双目
Ⅳ类型转化
六、继承派生多态
①继承
Ⅰ成员函数的重定义
Ⅱ类指针
②多态
Ⅰ虚函数
Ⅱ抽象基类与纯虚函数
Ⅲ虚析构函数
③STL
Ⅰ动态学生信息管理https://www.educoder.net/tasks/p4imnbvy/887783/ok8rac4vzhbx?coursesId=p4imnbvy
Ⅱ还原键盘输入https://www.educoder.net/tasks/p4imnbvy/887783/yf2swgkio7ma?coursesId=p4imnbvy
一、程序控制
①输入输出
Ⅰ.cin&cout
流操作算子 #include<iomanip>
setbase(n),进制,n=8,10,16
setprecision(n),浮点数精度设置为n
setw(n),域宽n,小于n空位填充,大于n输出所有
setiosflags(long),long,流格式状态标志
#include <iostream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
//setbase(n),进制,n=8,10,16
int a = 1000;
cout << "oct(八进制):"<<setbase(8) << a<<" "<<oct << a << endl;
cout << "hex(十六进制):" << setbase(16) << a << " " << hex << a << endl;
//setprecision(n),浮点数精度设置为n
double b = log(2);
cout << dec << b << " 保留两位小数:" << setprecision(2) << b << endl;
//setw(n),域宽n,小于n空位填充,大于n输出所有
cout << setw(5) << "域宽为5:" << "1234" << endl;
cout << setw(5) << "域宽为5:" << "hello,world!" << endl;
//setiosflags(long),long,流格式状态标志
//ios::left/right/internal 左对齐,右对齐,符号左对齐数值右对齐
//ios::showpos 显示正负号
//ios::scientific 科学计数显示浮点数
//ios::showpoint 显示小数点
double c = 1010.234;
cout << c << "科学技术显示浮点数并显示正负号:" << setiosflags(ios::showpos | ios::scientific) << c<<endl;
return 0;
}
out:
oct(八进制):1750 1750
hex(十六进制):3e8 3e8
0.693147 保留两位小数:0.69
域宽为5:1234
域宽为5:hello,world!
1e+03科学技术显示浮点数并显示正负号:+1.01e+03
其他流输入输出
cin.get(char) 抽取下一个字符
cin.peek() 读取下一个字符
cin.putbact(char) 将字符写入输入流的开头
cin.ingnore(int, char) 忽略前面int个或char及其之前的字符
cin.getline(char*, int, char) 最多读取前面n个字符或读取到char截止
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
string line;
//getline(cin,str)
//cin.get(char) 抽取一个字符
char gch;
cin.get(gch);
getline(cin, line);//getline抽取整行的输入流
cout << "cin.get()抽取的字符是:" << gch<<endl;
cout << "cin.get()抽取后的输入流为:" << line << endl<<endl;
//cin.peek() 读取下一个字符
char pch;
pch=cin.peek();
getline(cin, line);
cout <<"cin.peek()预览的下一个字符是:"<<pch<<endl;
cout << "cin.peek()预览后的输入流为:" <<line<< endl<<endl;
//cin.putback(char) 将字符写入输入流的开头
cin.putback('A');
getline(cin, line);
cout << "cin.putback('A')操作后的输入流:" << line << endl<<endl;
//cin.ingnore(int,char) 忽略前面int个或char及其之前的字符
cin.ignore(3, 'o');
getline(cin, line);
cout << "cin.ignore(3, 'o'): " <<line<< endl<<endl;
cin.ignore(3, 'o');
getline(cin, line);
cout << "cin.ignore(3, 'o'): " <<line<< endl<<endl;
//cin.getline(char*,int,char) 最多读取前面n个字符或读取到char截止,若输入流有剩余则继续操作
char cs[5];
cin.getline(cs, 5, 'l');
cout << "cin.getline(cs, 5, 'l'): " << cs << endl<<endl;
getline(cin, line);
cin.getline(cs, 5, 'l');
cout << "cin.getline(cs, 5, 'l'): " << cs<< endl<<endl;
getline(cin, line);
return 0;
}
out:
qwer
cin.get()抽取的字符是:q
cin.get()抽取后的输入流为:wer
qwer
cin.peek()预览的下一个字符是:q
cin.peek()预览后的输入流为:qwer
qwer
cin.putback('A')操作后的输入流:Aqwer
qwerty
cin.ignore(3, 'o'): rty
qoerty
cin.ignore(3, 'o'): erty
hello
cin.getline(cs, 5, 'l'): he
heeeee
cin.getline(cs, 5, 'l'): heee
Ⅱ.scanf&printf
格式化输入输出#include<stdio.h>
printf(<格式化控制>,<参数列表>)
scanf(<宽度>,<转换说明符>)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
//printf(<格式化控制>,<参数列表>)
//<标志>:-左对齐,+显示符号,0用0填充域宽
//<域宽>:小于域宽空白填充,大于按照实际输出
//<精度>:整数:至少输出的数字个数,少的0补前面,字符串:输出最大长度
//<转换说明符>:数据转换类型
double num =-123.456;
printf("%+015.5f\n", num);//0:缺项补0,15:域宽,5:精度
//scanf(<宽度>,<转换说明符>)
char c;
int d;
scanf("%3c%3d",&c,&d);
cout << "c: " << c << endl<<"d: "<<d<<endl;
}
out:
-00000123.45600
qes132245
c: q
d: 132
②运算与符号
Ⅰ常用数学函数#include<math.h>
abs
ceil 向上取整
exp(x) e^x
floor 向下取整
pow(x,y) x^y
log 以e为底数
log10 以10为底数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
cout <<"abs(-1)="<< abs(-1) << endl;
cout << "ceil(0.5)="<<ceil(0.5) << endl;
cout << "exp(0.1)="<<exp(0.1) << endl;
cout << "floor(0.5)="<<floor(0.5) << endl;
cout << "pow(2, 3)="<<pow(2, 3) << endl;
cout << "log(10)="<<log(10) << endl;
cout <<"log10(10)="<< log10(10) << endl;
return 0;
}
out:
abs(-1) = 1
ceil(0.5) = 1
exp(0.1) = 1.10517
floor(0.5) = 0
pow(2, 3) = 8
log(10) = 2.30259
log10(10) = 1
Ⅱ.数据类型转换
隐式转换
显式转换
ASCII码与BOOL
运算符
三目运算符:<1> ? <2> : <3>
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
//隐式转换
int e = 3;
double f = e + 3.12;
//显式转换
cout << "double(3/2)="<<double(3 / 2) << endl;//运算后再转换为double
cout << "double(3.0/2)=" << double(3.0 / 2) << endl;
cout << "(double)3/2=" << (double)3 / 2 << endl;//所有数据先转换为doble再运算
//ASCII码与BOOL
cout << "int('a')=" << int('a') << endl;
cout << "int(true)=" << int(true) << endl;
cout << "char(97)=" << char(97) << endl;
cout<<"(char)(97+256)="<<(char)(97 + 256) << endl; //char占一个字节,256溢出不计
//运算符
//+,-,*,/,%
//==,<=,>=,!=
//&&,||,!
//&,|,~,^,<<,>>:按位与,按位或,按位取反,按位异或,左右移位
//三目运算符:<1>?<2>:<3>
//if<1>则<2>;else <3>
int a = 1, b = 2, c = 3;
a > b ? a = b : a = c;
cout << a;
return 0;
}
out:
double(3/2)=1
double(3.0/2)=1.5
(double)3/2=1.5
int('a')=97
int(true)=1
char(97)=a
(char)(97+256)=a
3
③控制结构
两个数的值交换
三个数的排序
switch - case-break - defalut方便跳出多重循环
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
//两个数的值交换
int e = 1, f = 2;
int t = e;
e = f;
f = t;
//三个数的排序
int a = 1, b = 2, c = 3;
int maxab = a > b ? a : b;
int minab = a + b - maxab;
int max = maxab > c ? maxab : c;
int temp = (maxab + c) - max;
int min = temp > minab ? minab : temp;
cout << "max:" << max << "\n" << "mid:" << (a + b + c) - max - min << endl<<"min:"<<min<<endl;
//switch-case-break-defalut
int flag = 1;
while (flag)
{
int command;
cin >> command;
switch (command)
{
case 1:
cout << "1号任务" << endl;
break;//不能缺少break语句
case 2:
cout << "2号任务" << endl;
break;
case 0:
flag = 0;
break;
default:
cout << "你干嘛" << endl;
}
}
//goto 方便跳出多重循环
for (int i = 1; i < 10; i++)
{
for (int j = 1; j < 10; j++)
{
for (int k = 1; k < 10; k++)
{
if (3*i + 4 * j + 5 * k == 100)
{
printf("i=%d,j=%d,k=%d是3*i+4*j+5*k=100的解\n", i, j, k);
goto flag1;
}
}
}
}
flag1:
cout<<"flag1";
return 0;
}
out:
max:3
mid:2
min:1
1
1号任务
4
你干嘛
0
i=8,j=9,k=8是3*i+4*j+5*k=100的解
flag1
④函数
Ⅰ.函数定义
函数头放前面,具体定义放后面,增强可读性
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
//<返回类型><函数名字>(<参数列表>){<语句>}
bool isprime(int n);//函数头放前面,具体定义放后面,增强可读性
void goldbach(int n);
int main()
{
cout << "15~30的偶数哥德巴赫猜想验证\n";
for (int i = 16; i <= 30; i+=2)
{
goldbach(i);
cout << endl;
}
return 0;
}
// function library
bool isprime(int n) //判断是否为素数
{
int c = 1;
for (int i = 2; i <= n; i++)
{
if (n % i == 0)
{
c++;
}
}
return c == 2 ? true : false;
}
void goldbach(int n)
{
for (int i = 2; i < n / 2 + 1; i++)
{
if (isprime(i) && isprime(n - i))
{
printf("%d=%d+%d", n, i, n - i);
break;
}
}
}
out:
15~30哥德巴赫猜想验证
16 = 3 + 13
18 = 5 + 13
20 = 3 + 17
22 = 3 + 19
24 = 5 + 19
26 = 3 + 23
28 = 5 + 23
30 = 7 + 23
Ⅱ函数使用
传值
传引用
函数重载,函数名字可相同,但传参类型个数或顺序不同
作用域:块作用域,{}, 全局作用
存储类别:auto, static.(auto现在已经被淘汰了, 函数内直接定义即可)递归函数:汉诺塔问题
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
using namespace std;
int a = 1;
double max(double x, double y);
void swap(double& x, double& y);
int max(int x, int y);
void storeauto(int &x, int &y);
void storesta(int& x, int& y);
void hannuo(int n, char s, char m, char t);//n:规模,s:源柱,m:辅柱,t:目标柱
int main()
{
//传值
double x = 1.1, y = 2.2;
//传引用
printf("x=%.1f,y=%.1f\t", x, y);
swap(x, y);//这里不用写(&x,&y)
printf("after swapping \tx=%.1f,y=%.1f\n", x, y);
//函数重载,函数名字可相同,但传参类型个数或顺序不同
int r = 1, s = 2;
cout << max(r, s)<<endl;
//作用域:块作用域,{},全局作用
{int a=1; cout <<"块1:a="<< a << endl; };
{int a = 2; cout <<"块2:a="<< a << endl; };
cout << "全局:a=" << a << endl;
//存储类别:auto,static.(auto现在已经被淘汰了,函数内直接定义即可)
int q = 2, w = 4;
printf("q=%d,w=%d\n", q, w);
for (int i = 1; i <= 2;i++)
{
storeauto(q, w);
printf("storeauto(q,w)调用%d次后,q=%d,w=%d\n", i, q, w);
}
cout << endl;
printf("q=%d,w=%d\n", q, w);
for (int i = 1; i <= 2; i++)
{
storesta(q, w);
printf("storesta(q,w)调用%d次后,q=%d,w=%d\n", i, q, w);
}
//汉诺塔问题
hannuo(3, 'A', 'C', 'B');
return 0;
}
// function library
double max(double x, double y)
{
return x < y ? y : x;
}
void swap(double& x, double& y)
{
double temp=x;
x = y;
y = temp;
}
int max(int x, int y)
{
return x < y ? y : x;
}
void storeauto(int &x, int &y)
{
int j=1;//auto int j=0;
x += j;
y += j;
j++;
}
void storesta(int& x, int& y)
{
static int j =1;//auto int j=0;
x += j;
y += j;
j++;
}
void hannuo(int n, char s, char m, char t)
{
if (n == 1)
{
cout << s <<"->" << t << endl;
}
else
{
hannuo(n - 1, s, t, m);//n-1个盘子移到辅柱
cout << s << "->" << t << endl;//最后一个移到目标柱
hannuo(n - 1, m, s, t);//辅柱变为源柱
}
}
out:
x=1.1,y=2.2 after swapping x=2.2,y=1.1
2
块1:a=1
块2:a=2
全局:a=1
q=2,w=4
storeauto(q,w)调用1次后,q=3,w=5
storeauto(q,w)调用2次后,q=4,w=6
q=4,w=6
storesta(q,w)调用1次后,q=5,w=7
storesta(q,w)调用2次后,q=7,w=9
A->B
A->C
B->C
A->B
C->A
C->B
A->B
二、数据结构
①一维数组
排序与查找
一维数组 a[n], n是数据个数
排序 交换(每次找到都交换),选择(先找最值再交换),快排
内置函数#include<algorithm>
查找:二分查找
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
void quick_sort(int a[], int start, int end);//快排自定义
int binary_search(vector<int>& nums, int target);
int main()
{
//一维数组 a[n],n是数据个数
int d[4]; //大小是常量值
int b[] = { 1,2,3,4 };//根据数目确定大小
float c[5] = { 1.2 };//缺省值0
//排序 交换(每次找到都交换),选择(先找最值再交换),快排
//交换排序
int a[10] = { 1,2,3,5,6,8,10,9,7,4 };
for (int i = 0; i < 10 - 1; i++)
{
for (int j = i+1; j < 10; j++)
{
if (a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
cout << "交换排序结果:";
for (int i = 0; i < 10; i++)
{
cout << a[i] << " ";
}
cout << endl;
//选择排序
for (int i = 0; i < 10 - 1; i++)
{
int min = i;
for (int j = i + 1; j < 10; j++)
{
if (a[j] < a[i])
{
min = j;
}
}
if (i != min)
{
int temp = a[i];
a[i] = a[min];
a[min] = a[i];
}
}
cout << "选择排序结果:";
for (int i = 0; i < 10; i++)
{
cout << a[i] << " ";
}
cout << endl;
//快排
quick_sort(a, 0, 10- 1);
cout << "快排结果:";
for (int i = 0; i < 10; i++)
{
cout << a[i] << " ";
}
cout << endl;
//内置函数#include<algorithm>
sort(a, a + 10, greater<int>());//左闭右开,greater,降序,int 类型,默认为升序
//查找:二分查找
vector<int> nums = { 1, 3, 5, 7, 9, 11, 13, 15, 17 };
int target = 11;
int index = binary_search(nums, target);
if (index == -1) {
cout << "Target not found" << endl;
}
else {
cout << "Target found at index " << index << endl;
}
return 0;
}
// function library
void quick_sort(int a[], int start, int end)
{
if (start >= end) {
return;
}
int pivot = a[start];
int left = start + 1, right = end;
while (left <= right) {
if (a[left] < pivot && a[right] > pivot) {
swap(a[left], a[right]);
left++;
right--;
}
if (a[left] >= pivot) {
left++;
}
if (a[right] <= pivot) {
right--;
}
}
swap(a[start], a[right]);
quick_sort(a, start, right - 1);
quick_sort(a, right + 1, end);
}
int binary_search(vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
else if (nums[mid] < target) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return -1;
}
out:
交换排序结果:1 2 3 4 5 6 7 8 9 10
选择排序结果:1 2 3 4 5 6 7 8 9 10
快排结果:10 9 8 7 6 5 4 3 2 1
Target found at index 5
②多维数组
初始化 a[m][n], m行n列,按行连续储存
作为函数参数, 指定数组的每一维的大小
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int sum(int arr[][3], int rows, int cols);
int main()
{
//多维数组 初始化 a[m][n],m行n列,按行连续储存
int a[2][2] = { {2},{2,3} };//缺省值为0
int b[2][2] = { 1,2,3};//按行读入
int c[][2] = { {1,2},{1} };//只能省略第一维
//多维数组 作为函数参数
//由于多维数组的内存布局是连续的,因此在将多维数组作为形参传递时,必须指定数组的每一维的大小
int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
int s = sum(arr, 2, 3);
cout << "The sum of the array is: " << s << endl;
return 0;
}
// function library
int sum(int arr[][3], int rows, int cols)
{
int s = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
s += arr[i][j];
}
}
return s;
}
out:
The sum of the array is : 21
③指针
Ⅰ字符,指针运算
加密问题
二维字符数组
指针运算:& 地址运算* 复引用 + -算术运算 前移后移,计算距离,关系运算,赋值
指针操作数组
指针数组:数组存放指针
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
//加密问题
char a[10];
cin >> a;
int l = 0;
while (a[l] != '\0')
{
a[l] = a[l] + 'A' - 'a'+3;
l++;
}
cout << "输入字符串长度为:" << l << "\t加密后为:" << a << endl;
//二维字符数组
char s[2][10];
cin >> s[0] >> s[1];
cout << s[0] << endl << s[1] << endl;
//指针运算:&地址运算 *复引用 +-算术运算 前移后移,计算距离,关系运算,赋值
//& 地址运算
int* yptr;
int y = 5;
yptr = &y;//得到指向y的指针
//*复引用
int* p1, * p2;//同时定义两个指针都要打*
int y1 = 2, y2 = 3;
p1 = &y1;
p2 = &y2;
*p1 += 1;
printf("y1=%d,y2=%d\n*p1=%d,*p2=%d\n", y1, y2, *p1, *p2);
//+-算术运算 前移后移,计算距离
cout << "p1-p2=" << p1 - p2 << endl;
//关系运算
cout << "p1<p2?" << bool(p1 < p2) << endl;
//赋值,不同类型需要类型转换
float f = 0.1;
int* d = (int*)&f;
cout << "int* d = (int*)&f,*d=" << *d << endl;//d的输出并不是0,涉及到浮点数的存储方式和类型转换
//指针操作数组
int arr1[5] = { 1, 2, 3, 4, 5 };
int* pa = arr1;
for (int i = 0; i < 5; ++i) {
cout << *pa << " ";
pa++;
}
cout << endl;
//指针数组:数组存放指针
const char *gender[3][10] = {"man","women","other"};
cout << "*gender[0]="<< * gender[0] << endl;
return 0;
}
// function library
out:
helloworld
输入字符串长度为:10 加密后为:KHOORZRUOG
hello world
hello
world
y1 = 3, y2 = 3
* p1 = 3, *p2 = 3
p1 - p2 = -8
p1 < p2 ? 1
int* d = (int*)&f, *d = 1036831949
1 2 3 4 5
* gender[0] = man
Ⅱ字符串函数#include<string.h>
int strlen(const char*) 计算字符串长度
char* strcpy(char* dest, const char* src) 将src指向的空间复制到dest
char* strcat(char* dest, const char* src) 将src指向的空间连接到dest之后
int strcmp(const char* s1, const char* s2) 逐一比较字典序,s1 < s2返回1
char* strchr(const char* s, int c) 在s中查找第一个对应ASCII码为c的字符并返回位置,否则返回NULL
综合应用 : countstring(const chat* s1, const char* s2),查找子串s2在s1中的出现次数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int countstring(const char* s1, const char* s2);
int main()
{
//int strlen(const char*) 计算字符串长度
const char* c1 = "hello world";
char c2[] = "hello world"; //两种初始化方式
cout << "strlen(c1)=" << strlen(c1) << "\tstrlen(c2)=" << strlen(c2) << endl;
//char* strcpy(char* dest,const char* src) 将src指向的空间复制到dest
char a[20]="hello", b[20] = "world";
strcpy(a, b);//a原来有的内容不会保留
cout << "strcpy(a, b),a=" << a << endl;
//char* strcat(char* dest,const char* src) 将src指向的空间连接到dest之后
strcat(a, b);//拼接在一起
cout << "strcat(a, b),a=" << a << endl;
//int strcmp(const char* s1,const char* s2) 逐一比较字典序,s1<s2返回1
char s1[] = "abc", s2[] = "abb";//按照字典,谁在前面谁大
cout << "strcmp(s1,s2)=" << strcmp(s1, s2) << endl;
//char* strchr(const char* s,int c) 在s中查找第一个对应ASCII码为c的字符并返回位置,否则返回NULL
cout << "strchr(s1,'b')返回:" << strchr(s1, 'b') << endl;
if (strchr(s1, 'd') == NULL)
{
cout << "strchr(s1, 'd') == NULL" << endl;
}
//char* strstr(const char* s1,const char* s2) 在s1中查找s2出现的首位置并返回,否则返回NULL
char s3[] = "abcdefabcdef", s4[] = "cd";
cout << "strstr(s3, s4):" << strstr(s3, s4) << endl;
//综合应用:countstring(const chat* s1,const char* s2),查找子串s2在s1中的出现次数
char s5[] = "abcdefhabcewfhabcmkknabc", s6[] = "abc";
printf("\"%s\"在\"%s\"中出现的次数为:%d\n", s6, s5, countstring(s5, s6));
return 0;
}
// function library
int countstring(const char* s1, const char* s2)
{
int count = 0, l = strlen(s2);
const char* p = s1;
while ((p = strstr(p, s2)) != NULL) {
count++;
p += l;
}
return count;
}
out:
strlen(c1) = 11 strlen(c2) = 11
strcpy(a, b), a = world
strcat(a, b), a = worldworld
strcmp(s1, s2) = 1
strchr(s1, 'b')返回:bc
strchr(s1, 'd') == NULL
strstr(s3, s4):cdefabcdef
"abc"在"abcdefhabcewfhabcmkknabc"中出现的次数为:4
Ⅲ指针参数与动态内存
const与指针
动态分布:new& delete, malloc& free
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
//const与指针
const int* p1; // 指向常量的非常量指针
int a = 1;
p1 = &a; // OK,p1指向a,但不能通过p1修改a的值
int b = 2;
p1 = &b; // OK,p1指向b,但不能通过p1修改b的值
int* const p2 = &a; // 指向非常量的常量指针
*p2 = 3; // OK,可以通过p2修改a的值
int c = 4;
// p2 = &c; // ERROR,p2是常量指针,不能改变指向的对象
const int* const p3 = &b; // 指向常量的常量指针
// *p3 = 5; // ERROR,不能通过p3修改b的值
int d = 6;
// p3 = &d; // ERROR,p3是常量指针,不能改变指向的对象
//动态分布:new&delete,malloc&free
int x; //数组的长度
cin >> x;//运行时才能确定x的值
float* scores = new float[x];
cout <<"分配的内存空间长度:"<< sizeof(float) * x << endl;
delete[]scores;//及时释放,防止内存泄露,建议每次new就直接写delete
int* s = (int*)malloc(sizeof(int) * 4);
for (int i = 0; i < 4; i++)
{
cin >> s[i];
}
for (int i = 0; i < 4; i++)
{
cout << s[i] << " ";
}
free(s);
return 0;
}
// function library
out:
5
分配的内存空间长度:20
1
2
3
4
1 2 3 4
④结构:struct
定义与声明
初始化
结构与函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
//定义与声明
struct birthday
{
int year;
int month;
int day;
};
struct lifting
{
char name[20];
float weight;
birthday date;//可以包含其他strcut
lifting* a;//可以是指向本结构类型的指针
}lift1,lift2;//声明两个变量
void print(lifting* l);
int main()
{
//初始化
lift1 = { "张三",57,{2005,1,13},&lift2 };//lift1.a指向lift2
lifting* p1 = &lift1;
//p1->name = "张三";这里不能直接修改
strcpy(p1->name, "李四"); // 使用strcpy函数修改name的值
cout << lift1.name;
cout << "生日为:" << lift1.date.year<<" "<< lift1.date.month<<" "<< lift1.date.day<<endl;
//结构与函数:结构变量的成员是普通变量,可作为函数的参数或返回值
print(p1);
return 0;
}
// function library
void print(lifting* l)
{
cout << "姓名:"<<l->name << endl <<"体重:"<< l->weight<<endl;
}
out:
李四生日为:2005 1 13
姓名:李四
体重:57
⑤链表
node* insertTail(node* h, node* t) //尾部插入
node* insertHead(node* h, node* t)//头部插入
node* insertSort(node* h, node* t) //从小到大插入
node* search(node* h, int num) //查找指定节点
node* delAt(node* h, int i)//删除指定位置节点
node* delHas(node* h, int n) //删除含有指定元素的节点
int listLength(node* h)//计算链表长度
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<iomanip>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
struct node
{
int data;
node* next;
};
node* insertTail(node* h, node* t) //尾部插入
{
if (h == nullptr)
{
return t;// 如果当前链表为空,直接将待插入结点作为链表头并返回
}
node* p = h;
while (p->next != nullptr) {
p = p->next; // 找到链表的最后一个结点
}
p->next = t;// 将链表的最后一个结点的next指针指向待插入结点
return h;
}
node* insertHead(node* h, node* t)//头部插入
{
if (h == nullptr)
{
return t;
}
t->next = h;
return t;
}
node* insertSort(node* h, node* t) //从小到大插入
{
if (h == NULL)
{
t->next = NULL;// 空链表,直接将结点t插入
return t;
}
if (t->data <= h->data)
{
t->next = h;// 将结点t插入链表头
return t;
}
node* p = h;
while (p->next != NULL && p->next->data < t->data) {
p = p->next;
}
t->next = p->next;
p->next = t;
return h;
}
node* search(node* h, int num) //查找指定节点
{
if (h == NULL)// 空链表
{
return NULL;
}
node* p = h;
while (p != NULL) {
if (p->data == num) {
return p;
}
p = p->next;
}
return NULL; // 循环结束,未找到该结点
}
node* delAt(node* h, int i)//删除指定位置节点
{
int num = 0;
node* p = h;
while (p->next != nullptr)
{
num++;
p = p->next;
}
if (i == 0)
{
return h->next;
}
else if (i > num)
{
return h;
}
else
{
node* t = h;
node* m = h;
for (int j = 0; j < i; j++)
{
t = m;
m = t->next;
}
t->next = m->next;
return h;
}
}
node* delHas(node* h, int n) //删除含有指定元素的节点
{
if (h == NULL) // 空链表
{
return h;
}
if (h->data == n)
{
node* p = h;
h = h->next;// 删除头结点
free(p);//释放原来头节点的内存
return h;
}
node* p = h;
while (p->next != NULL && p->next->data != n)
{
p = p->next;// 找到要删除结点的前驱结点
}
if (p->next == NULL)
{
return h;// 要删除的结点不存在
}
node* q = p->next; // 被删除结点
p->next = q->next; // 将被删除结点从链表中删除
free(q);//释放内存
return h;
}
int listLength(node* h)//计算链表长度
{
int c = 0;
while (h != nullptr)
{
c++;
h = h->next;
}
return c;
}
三、文件操作
Ⅰ基本文件输入输出
打开文件 ios::in打开供读取,out打开供写入, app打开写入末尾
输入输出
example:文本操作与二进制操作
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<fstream>
using namespace std;
struct person
{
char name[16];
int number;
}me={"zhangsan",20220001},t,r;
int main()
{
/*
//打开文件 ios:: in打开供读取,out打开供写入,app打开写入末尾
ofstream ofs;
ofs.open("f1.txt", ios::out);
//或者:ofstream ofs("f1.txt",ios::out)
//关闭
ofs.close();
//输入输出
ifstream ifs("f1.txt", ios::in);
int n;
ifs >> n;
ifs.close();
ofstream ofs("f1.txt", ios::out);
int n = 123;
ofs << n; ofs.close();
//块输入输出 ifstram&read,ofstream&write
ifstream ifs("f1.txt", ios::in);
int n;
ifs.read((char*)&n, sizeof(int));
ifs.close();
ofstream ofs("f1.txt", ios::out);
int n = 123;
ofs.write((char*)&n, sizeof(n)); ofs.close();
*/
//example
//文本操作
ofstream f("a.txt", ios::out);
f << me.name << " " << me.number << endl;
f.close();
ifstream f1("a.txt", ios::in);
f1 >> t.name >> t.number;
f1.close();
cout << t.name << " " << t.number << endl;
//二进制操作
ofstream g("b.txt", ios::out|ios::binary);
g.write((char*)&me, sizeof(me));
g.close();
ifstream g1("b.txt", ios::in |ios::binary);
g1.read((char*)&r, sizeof(r));
g1.close();
cout << r.name << " " << r.number << endl;
return 0;
}
// function library
out:
zhangsan 20220001
zhangsan 20220001
Ⅱ文件指针
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<fstream>
using namespace std;
struct date
{
int year, month, day;
};
int main()
{
//seekg(streamoff off,ios::seek_dir dir) 读文件时修改FP
//seekp(streamoff off,ios::seek_dir dir) 写文件时修改FP
//off:偏移量,单位字节 dir:位置常量,ios:: beg起始,cur当前,end结尾
//example
int i,n;
cin >> n;
date* t=new date[n]; //动态分配内存
for (i = 0; i <n; i++)
{
t[i].year = 1900 + i;
t[i].month = i % 12 + 1;
t[i].day = 1;
}
ofstream fout("a.dat", ios::out | ios::binary);
fout.write((char*)t, sizeof(date)*n);//这里t是指针,要写整个数组的大小
fout.close();
date t20, t50;
ifstream fin("a.dat", ios::in | ios::binary);
fin.seekg((sizeof(date) * 19, ios::beg));//指针便宜量
fin.read((char*)&t20, sizeof(date));
fin.seekg(sizeof(date) * 29, ios::cur);
fin.read((char*)&t50, sizeof(date));
fin.close();
cout << t20.year << "-" << t20.month << "-" << t20.day << endl;
cout << t50.year << "-" << t50.month << "-" << t50.day << endl;
return 0;
}
// function library
out:
51
1900 - 1 - 1
1930 - 7 - 1
四、类和对象
①类的创建和使用
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//类和对象
class complex
{
public:
complex(double r = 0, double i = 0)
{
real = r;
imag = i;
}
~complex() {};//析构函数,撤销对象时自动调用
complex mul(complex x)
{
double r = real * x.real - imag * x.imag;
double i = real * x.imag + imag * x.real;
return complex(r, i);
}
complex add(complex x)
{
return complex(real + x.real, imag + x.imag);
}
void output()
{
if (imag >= 0)
{
cout << "(" << real << "+" << imag << "i)" << endl;
}
else
{
cout << "(" << real << imag << "i)" << endl;
}
}
private:
double real, imag;
};
int main()
{
complex a(1.2, 2.3), b(5, -6.7), c, d;
c = a.add(b); d = a.mul(b);
c.output();
d.output();
return 0;
}
out:
(6.2 - 4.4i)
(21.41 + 3.46i)
②静态成员
静态成员的声明:static
访问静态成员:对象名 / 对象引用 + 点操作符号,classname + ::,类指针 + 箭头
作用域与析构函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//静态成员的声明:static
class book
{
public:
book(const char* bookname);
~book();//析构函数
static int getbooknum();//静态成员函数只能访问静态成员
private:
char name[50];//书名
static int booknum;//静态数据,不依赖对象而存在
};
//访问静态成员:对象名/对象引用+点操作符号,classname+::,类指针+箭头
book::book(const char* bookname)
{
strcpy(this->name, bookname);//类指针+箭头
booknum++;//对象产生,booknum增加
}
book::~book()
{
booknum--;//对象撤销时,booknum减少
}
int book::booknum = 0;//初始化类的静态成员
int book::getbooknum()
{
return booknum;
}
int main()
{
cout << "Thers is " << book::getbooknum() << " book." << endl;
{//块1
book one("C++程序设计");//创建一个对象
cout << "After book one created,there is " << one.getbooknum() << " book." << endl;//对象名+.
{//块2
book two("Python程序设计");
cout << "After book two created,there are " << two.getbooknum() << " books." << endl;
}//块2结束,自动撤销two(作用域)
cout << "After book two destroyed,there is " << one.getbooknum() << " book." << endl;
}//块1结束,自动撤销one
cout << "After book one destroyed,there is " << book::getbooknum() << " book." << endl;
return 0;
}
out:
Thers is 0 book.
After book one created,there is 1 book.
After book two created,there are 2 books.
After book two destroyed,there is 1 book.
After book one destroyed,there is 0 book.
③构造函数
带默认参数的构造函数
复制构造函数(创建信息相同的对象)文章来源:https://www.toymoban.com/news/detail-490105.html
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
class circle
{
public:
//带默认参数的构造函数
circle(double a = 5.0, double b = 5.0, double c = 5.0)//每个参数的类型都要写清楚
{
x = a;
y = b;
c > 0 ? r = c : r = 5.0;//三目运算符
}
//复制构造函数(创建信息相同的对象)
circle(circle& c)
{
x = c.x; y = c.y; r = c.r;
}
~circle() {};
void print(circle &c);
private:
double x, y, r;
};
void circle::print(circle& c)
{
cout << "x=" << c.x << "\ty=" << c.y << "\tr=" << c.r<<endl;
}
int main()
{
{
circle a;//参数被设定为默认参数
circle b(1.0);//只传第一个参数
circle c(4.0, 5.0, 6.0);
circle d(c);
cout << "a:"; a.print(a);
cout << "b:"; b.print(b);
cout << "c:"; c.print(c);
cout << "d:"; b.print(d);
}
return 0;
}
out:
a:x = 5 y = 5 r = 5
b : x = 1 y = 5 r = 5
c : x = 4 y = 5 r = 6
d : x = 4 y = 5 r = 6
④类的复合
成员对象在包含它的对象之前被建立
成员函数的构造函数被大对象的构造函数调用
大对象的成员函数对成员对象来说依然是外部函数,需要遵循访问规则,注意调用格式文章来源地址https://www.toymoban.com/news/detail-490105.html
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
#define pi 3.14
class circle
{
public:
//带默认参数的构造函数
circle(double a = 5.0, double b = 5.0, double c = 5.0);//每个参数的类型都要写清楚
~circle();
double area();
void print();
private:
double x, y, r;
};
//function library
circle::circle(double a, double b, double c)
{
x = a;
y = b;
c > 0 ? r = c : r = 5.0;
cout << "circle object start:x=" << x << "\ty=" << y << "\tr=" << r << endl;
}
circle::~circle()
{
cout << "circle object end:x=" << x << "\ty=" << y << "\tr=" << r << endl;
}
double circle::area()
{
return pi * r * r;
}
void circle::print()
{
cout << "x=" << x << "\ty=" << y << "\tr=" << r;
}
//创建column类
class column
{
public:
column(double h = 5.0, double a = 5.0, double b = 5.0, double c = 5.0);
~column();
double volume();
private:
circle circle;//数据成员
double height;
};
column::column(double h, double a, double b, double c)
:circle(a, b, c)//为数据成员circle调用其构造函数,初始化列表
{
h > 0 ? height = h : height = 5.0;
cout << "coulumn object start : height = " << height << ",";
circle.print();
cout << endl;
}
double column::volume()
{
return height * circle.area();
}
column::~column()
{
cout << "column object end:height=" << height << ",";
circle.print();
cout << endl;
}
int main()
{
column obj(2.3, 3.4, 4.5, 5.6);
cout << "The volume of obj is" << obj.volume() << endl;
return 0;
}
out:
circle object start : x = 3.4 y = 4.5 r = 5.6
coulumn object start : height = 2.3, x = 3.4 y = 4.5 r = 5.6
The volume of obj is226.482
column object end : height = 2.3, x = 3.4 y = 4.5 r = 5.6
circle object end : x = 3.4 y = 4.5 r = 5.6
⑤This指针
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
/*
class test
{
public:
test(int n = 0)
{
data = n;//直接访问
}
void print()
{
cout << "data=" << this->data << endl;//使用this指针访问
}
private:
int data;
};
*/
//静态成员函数没有维护this,访问非静态数据成员需要this
class test
{
public:
test(int n = 0) { data = n; }
test& setdata(int n)//返回值类型
{
data = n;
return *this;
}
void print()
{
cout << "data=" << data << "!" << endl;
}
private:
int data;
};
int main()
{
test obj;
cout << "obj: ";
obj.setdata(100).print();//函数连续调用,因为setdata返回的是test&类型
return 0;
}
out:
obj: data=100!
⑥友元
Ⅰ友元函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//友元函数具有访问类的所有成员的权限,friend+函数原型
class triangle
{
friend void seta(triangle& t, int n);//声明友元函数
public:
triangle(int x = 5, int y = 5, int z = 5);
void print();
private:
int a, b, c;
};
triangle::triangle(int x, int y, int z)
{
if (x + y > z && x + z > y && y + z > x)
{
a = x; b = y; c = z;
}
else
{
a = b = c = 5;
}
}
void triangle::print()
{
cout << "triangle:" << a << "," << b << "," << c << endl;
}
void seta(triangle& t, int n)
{
t.a = n;//访问对象的私有成员
}
int main()
{
triangle t;
t.print();
seta(t, 10);
t.print();
return 0;
}
out:
triangle:5, 5, 5
triangle : 10, 5, 5
Ⅱ友元类
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//一个类的友元类所有成员函数都有访问类的所有成员的权限,friend+class+类名
//友元的声明是单方面不传递的
class B;
class A
{
public:
void setB(B& b, int m);
void print(B& b);
};
class B
{
friend class A;//声明友元,A可以访问B中所有成员
private:
int data;
};
void A::setB(B& b, int m)
{
b.data = m;
}
void A::print(B& b)
{
//访问私有成员
cout << "Thea private data of class B:" << b.data << endl;
}
int main()
{
A a;
B b;
a.setB(b, 10);//调用A的成员函数修改类B的对象b的私有数据
a.print(b);//调用A的成员函数访问b的私有数据
return 0;
}
out:
Thea private data of class B :10
五、运算符重载
①原理
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//操作预定义数据对象的方式,自定义的对象操作方式,operator<运算符>
//.,*,::,?:,sizeof 不能被重载
class complex
{
public:
complex(double = 0.0, double = 0.0);
complex operator+(const complex&)const;//常量成员函数,即该函数不会修改类的任何成员变量。
complex& operator=(const complex&);
void print() const;
private:
double real;
double imaginary;
};
complex::complex(double r, double i)
{
real = r; imaginary = i;
}
complex complex::operator+(const complex& operand2)const
{
complex sum;
sum.real = real + operand2.real;
sum.imaginary = imaginary + operand2.imaginary;
return sum;
}
complex& complex::operator=(const complex& right)
{
real = right.real;
imaginary = right.imaginary;
return *this;
}
void complex::print()const
{
cout << "(" << real << "," << imaginary << ")";
}
int main()
{
complex x, y(4.3, 8.2), z(3.3, 1.1);
x = y + z;//x.operator=(y.operator+(z));赋值运算符
cout << "x=y+z:\n";
x.print();
cout << "="; y.print();
cout << "+"; z.print();
cout << endl;
return 0;
}
out:
x = y + z :
(7.6, 9.3) = (4.3, 8.2) + (3.3, 1.1)
②方式
Ⅰ成员函数重载
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//成员函数方式重载运算符
//重载!为成员函数
class mystring
{
public:
mystring(const char* m = NULL);//默认构造函数
~mystring();
//运算符重载成员函数原型
bool operator!();
private:
char* str;
};
mystring::mystring(const char* m)
{
if (m == NULL)
{
str == NULL;
}
else
{
int len = strlen(m) + 1;//留一个放"\0"
str = new char[len];
strcpy_s(str, len, m);
}
}
mystring::~mystring()
{
if (str != NULL)
delete[]str;
}
//实现运算符重载函数
bool mystring::operator!()
{
if (str == NULL || strlen(str) == 0)
return true;
return false;
}
int main()
{
mystring s1, s2("some string");
if (!s1)
cout << "s1 is NULL!" << endl;
else
cout << "s1 is not NULL!" << endl;
if (!s2)
cout << "s2 is NULL!" << endl;
else
cout << "s2 is not NULL!" << endl;
return 0;
}
out:
s1 is NULL!
s2 is not NULL!
Ⅱ友元函数重载
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
class mystring
{
public:
mystring(const char* m = NULL);//默认构造函数
~mystring();
friend bool operator!(mystring&s);
private:
char* str;
};
mystring::mystring(const char* m)
{
if (m == NULL)
{
str == NULL;
}
else
{
int len = strlen(m) + 1;//留一个放"\0"
str = new char[len];
strcpy_s(str, len, m);
}
}
mystring::~mystring()
{
if (str != NULL)
delete[]str;
}
//实现运算符重载函数
bool operator!(mystring& s)
{
if (s.str == NULL || strlen(s.str) == 0)
return true;
return false;
}
int main()
{
mystring s1, s2("some string");
if (!s1)
cout << "s1 is NULL!" << endl;
else
cout << "s1 is not NULL!" << endl;
if (!s2)
cout << "s2 is NULL!" << endl;
else
cout << "s2 is not NULL!" << endl;
return 0;
}
out:
s1 is NULL!
s2 is not NULL!
③单目与双目运算符重载
Ⅰ单目(目表示操作数)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//重载运算符前自增++,返回值*this,类型complex&
class complex
{
public:
complex(double = 0.0, double = 0.0);
complex& operator++();//成员函数形式
void print()const;
private:
double real;
double imaginary;
};
complex::complex(double r, double i)
{
real = r;
imaginary = i;
}
void complex::print()const
{
cout << "(" << real << "," << imaginary << ")";
}
complex& complex::operator++()
{
this->real += 1;
return *this;
}
int main()
{
complex y(4.3, 8.2), x;
x = ++y;//x=y.operator++()
cout << "y:"; y.print();
cout << "\tx:"; x.print();
cout << endl;
return 0;
}
out:
y:(5.3,8.2) x:(5.3,8.2)
Ⅱ流插入和流提取运算符的重载
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//如何实现用cout输出自定义类型的对象,重载<<和>>
class mystring
{
//重载流插入和流提取函数
friend ostream& operator<<(ostream& output, mystring& s);
friend istream& operator>>(istream& input, mystring& s);
public:
mystring(const char* m = NULL);
~mystring();
private:
char* str;
};
mystring::mystring(const char* m)
{
if (m == NULL)
str == NULL;
else
{
int len = strlen(m) + 1;
str = new char[len];
strcpy_s(str, len, m);
}
}
mystring::~mystring()
{
if (str != NULL)
delete[]str;
}
//定义运算符<<重载函数
ostream& operator<<(ostream& output, mystring& s)
{
output << s.str;
return output;
}
//定义运算符>>重载函数
istream& operator>>(istream& input, mystring& s)
{
char temp[1000];
cin >> temp;
if (s.str)delete[]s.str;//释放内存
int len = strlen(temp) + 1;//"\0"
s.str = new char[len];
strcpy_s(s.str, len, temp);
return input;
}
int main()
{
mystring s1, s2;
cout << "Please input two strings" << endl;
cin >> s1 >> s2;
cout << "Output is:" << endl;
cout << "s1——" << s1 << endl << "s2——" << s2 << endl;
return 0;
}
output:
Please input two strings
dager
fewre
Output is :
s1——dager
s2——fewre
Ⅲ双目
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//友元函数重载运算符+=
class mystring
{
friend mystring& operator+=(mystring& x, mystring& y);
public:
mystring(const char* m = NULL);
~mystring();
void print() const;
private:
char* str;
};
mystring::mystring(const char* m)
{
if (m == NULL)
str == NULL;
else
{
int len = strlen(m) + 1;
str = new char[len];
strcpy_s(str, len, m);
}
}
mystring::~mystring()
{
if (str != NULL)
delete[]str;
}
void mystring::print()const
{
cout << str<<endl;
}
mystring& operator+=(mystring& x, mystring& y)
{
int len = strlen(x.str) + strlen(y.str) + 1;
char* temp = new char[len];
strcpy_s(temp, len, x.str);
strcat_s(temp, len, y.str);
delete[]x.str;
x.str = temp;
return x;
}
int main()
{
mystring s1("hello"), s2("world");
s1 += s2;
s1.print();
return 0;
}
output:
helloworld
Ⅳ类型转化
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//类型转换,必须是类的非静态成员函数,不是友元函数,不能指定返回类型(其实已经指定了)
//operator+类型名 (int)obj等价于obj.operator int()
class Fraction {
private:
int numerator;
int denominator;
public:
Fraction(int num, int den) : numerator(num), denominator(den) {}
// 将 Fraction 类型转换为 double 类型
operator double() const {
return (double)numerator / denominator;
}
};
int main()
{
Fraction f(3, 4);
double d = f; // 将 Fraction 类型转换为 double 类型
cout << d << endl;
return 0;
}
out:
0.75
六、继承派生多态
①继承
Ⅰ成员函数的重定义
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//派生类重定义基类成员函数
class child
{
public:
void showinfo()
{
cout << "I'm child" << endl;
}
};
class parent:public child
{
public:
void showinfo()
{
child::showinfo();
cout << "I'm parent" << endl;
}
};
int main()
{
parent p;
p.showinfo();
return 0;
}
out:
I'm child
I'm parent
Ⅱ类指针
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
//类指针
class media
{
public:
media(const char* n, const char* c);
~media();
const char* getname();
const char* getcompany();
private:
char* name;
char* company;
};
media::media(const char* n, const char* c)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
company = new char[strlen(c) + 1];
strcpy(company, c);
}
media::~media()
{
if (name != NULL) delete[]name;
if (company != NULL) delete[]company;
}
const char* media::getname()
{
return name;
}
const char* media::getcompany()
{
return company;
}
class audiomedia :public media
{
public:
audiomedia(const char* n, const char* c, const char* s);
~audiomedia();
const char* getsinger();
private:
char* singer;
};
audiomedia::audiomedia(const char* n, const char* c, const char* s) :media(n, c)//调用基类的构造函数
{
singer = new char[strlen(s) + 1];
strcpy(singer, s);
}
audiomedia::~audiomedia()
{
if (singer != NULL) delete[]singer;
}
const char* audiomedia::getsinger()
{
return singer;
}
int main()
{
media medium("slumdog millionaire", "celador films");
audiomedia audio("the color of my love", "columbia", "celine dion");
media* mptr;
mptr = &medium;
cout << "Accessing media object through meida*" << endl;
cout << "name:" << mptr->getname() << endl;
cout << "company:" << mptr->getcompany() << endl;
mptr = &audio;
cout << "Accessing auidomedia object through media*" << endl;
cout << "name:" << mptr->getname() << endl;
cout << "company:" << mptr->getcompany() << endl;
cout << "singer:" << ((audiomedia*)mptr)->getsinger()<<endl;//强制类型转换
return 0;
}
out:
Accessing media object through meida*
name : slumdog millionaire
company : celador films
Accessing auidomedia object through media*
name : the color of my love
company : columbia
singer : celine dion
②多态
Ⅰ虚函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;
class media
{
public:
media(const char* n, const char* c);
~media();
virtual void showinfo();
private:
char* name;
char* company;
};
media::media(const char* n, const char* c)
{
name = new char[strlen(n) + 1];
strcpy(name, n);
company = new char[strlen(c) + 1];
strcpy(company, c);
}
media::~media()
{
if (name != NULL) delete[]name;
if (company != NULL) delete[]company;
}
void media::showinfo()
{
cout << "name:" << name << endl;
cout << "company:" << company << endl;
}
class audiomedia :public media
{
public:
audiomedia(const char* n, const char* c, const char* s);
~audiomedia();
void showinfo();
private:
char* singer;
};
audiomedia::audiomedia(const char* n, const char* c, const char* s) :media(n, c)//调用基类的构造函数
{
singer = new char[strlen(s) + 1];
strcpy(singer, s);
}
audiomedia::~audiomedia()
{
if (singer != NULL) delete[]singer;
}
void audiomedia::showinfo()
{
media::showinfo();//调用被重定义的函数
cout << "singer:" << singer <<endl;
}
int main()
{
media* mptr;
media medium("slumdog millionaire", "celador films");
audiomedia audio("the color of my love", "columbia", "celine dion");
mptr = &medium;
mptr->showinfo();//基类指针指向基类对象
cout << endl;//基类指针调用成员函数,动态绑定
mptr = &audio;//基类指针指向派生类对象
mptr->showinfo();//基类指针调用成员函数,动态绑定
return 0;
}
name:slumdog millionaire
company : celador films
name : the color of my love
company : columbia
singer : celine dion
Ⅱ抽象基类与纯虚函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#define PI 3.14
using namespace std;
//纯虚函数:没有函数体,初始化为0
//抽象类,包含纯虚函数不能实例化对象
class shape//抽象基类
{
public:
virtual double area()const = 0;
virtual void show()const = 0;
};
class circle :public shape
{
public:
circle(double = 0.0, double = 0.0, double = 1.0);
double area()const;
void show()const;
private:
double x, y;
double r;
};
circle::circle(double a, double b, double c)
{
x = a; y = b; r = c;
}
double circle::area()const
{
return PI * r * r;
}
void circle::show()const
{
cout << "I'm a circle:";
}
class rectangle :public shape
{
public:
rectangle(double = 1.0, double = 1.0);
double area()const;
void show()const;
private:
double length;
double width;
};
rectangle::rectangle(double a, double b)
{
length = a; width = b;
}
double rectangle::area()const
{
return length * width;
}
void rectangle::show()const
{
cout << "I'm a rectangle:";
}
void callarea(shape&obj)
{
obj.show();
cout << "area=" << obj.area() << endl;
}
int main()
{
circle cir(0.0, 0.0, 2.5);
rectangle rec(2.4, 5.3);
callarea(cir);
callarea(rec);
return 0;
}
out:
I'm a circle:area=19.625
I'm a rectangle:area=12.72
Ⅲ虚析构函数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstring>
#define PI 3.14
using namespace std;
class employee
{
public:
employee()
{
cout << "Employee begin!" << endl;
}
virtual ~employee()
{
cout << "Employee end!" << endl;
}
};
class programmer :public employee
{
public:
programmer(char* str)
{
cout << "Programmer begin!" << endl;
name = new char[strlen(str) + 1];
strcpy(name, str);
}
~programmer()
{
delete[]name;
cout << "programmer end!" << endl;
}
private:
char* name;
};
class accountant :public employee
{
public:
accountant(int n)
{
cout << "accountant begin!" << endl;
age = n;
}
~accountant()
{
cout << "accountant end!" << endl;
}
private:
int age;
};
int main()
{
int no;
employee* ptr[100], * tptr;//声明储存雇员信息的数组
int Enum = 0;
char name[100];
int age;
for (int i = 0; i < 100; i++)
{
ptr[i] = NULL;
}
cout << "Input employees' info:" << endl;
cout << "1---Programmer" << endl
<< "2---Accoutant" << endl
<< "0--exit" << endl;
cin >> no;
while (no)
{
switch (no)
{
case 1:
cout << "Input name:";
cin >> name;
tptr = new programmer(name);
ptr[Enum++] = tptr;
break;
case 2:
cout << "Input age:";
cin >> age;
tptr = new accountant(age);
ptr[Enum++] = tptr;
break;
default:
cout << "It's over" << endl;
};
cout << "Input another employee's info:" << endl;
cout << "1---Programmer" << endl
<< "2---Accountant" << endl
<< "0---exit" << endl;
cin >> no;
}
//撤销所有对象
for (int i = 0; i < Enum; i++)
{
delete ptr[i];
}
return 0;
}
out:
Input employees' info:
1-- - Programmer
2-- - Accoutant
0--exit
1
Input name : swx
Employee begin!
Programmer begin!
Input another employee's info:
1-- - Programmer
2-- - Accountant
0-- - exit
2
Input age : 12
Employee begin!
accountant begin!
Input another employee's info:
1-- - Programmer
2-- - Accountant
0-- - exit
0
programmer end!
Employee end!
accountant end!
Employee end!
③STL
Ⅰ动态学生信息管理https://www.educoder.net/tasks/p4imnbvy/887783/ok8rac4vzhbx?coursesId=p4imnbvy
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Student {
public:
string name;
int score;
Student(string n, int s) {
name = n;
score = s;
}
};
vector<Student> studentTable;
void addOrUpdateRecord(string name, int score)
{
bool found = false;
for (int i = 0; i < studentTable.size(); i++) {
if (studentTable[i].name == name) {
studentTable[i].score = score;
found = true;
break;
}
}
if (!found) {
Student newStudent(name, score);
studentTable.push_back(newStudent);
}
}
void deleteRecord(string name) {
for (int i = 0; i < studentTable.size(); i++) {
if (studentTable[i].name == name) {
studentTable.erase(studentTable.begin() + i);
break;
}
}
}
void printTable() {
if (studentTable.empty()) {
cout << "[空]" << endl;
}
else {
for (int i = 0; i < studentTable.size(); i++) {
cout << studentTable[i].name << " " << studentTable[i].score << endl;
}
}
}
bool compareScore(Student s1, Student s2) {
return s1.score > s2.score;
}
void sortTable() {
sort(studentTable.begin(), studentTable.end(), compareScore);
}
int main()
{
string input;
while (getline(cin, input)) {
if (input[0] == 'A') {
char name[10];
int score;
sscanf(input.c_str(), "A %s %d", name, &score);
addOrUpdateRecord(name, score);
}
else if (input[0] == 'R') {
char name[10];
sscanf(input.c_str(), "R %s", name);
deleteRecord(name);
}
else if (input[0] == 'P') {
printTable();
}
else if (input[0] == 'S') {
sortTable();
}
}
}
Ⅱ还原键盘输入https://www.educoder.net/tasks/p4imnbvy/887783/yf2swgkio7ma?coursesId=p4imnbvy
#include <iostream>
#include <string>
#include <list>
using namespace std;
int main()
{
//读取输入,解析并输出复原后的输出
string input;
string output;
while (getline(cin, input)) {
list<char> chars;
auto it = chars.begin();
for (char c : input) {
if (c == '<') {
if (it != chars.begin()) {
it--;
}
}
else if (c == '>') {
if (it != chars.end()) {
it++;
}
}
else if (c == '[') {
it = chars.begin();
}
else if (c == ']') {
it = chars.end();
}
else {
it = chars.insert(it, c);
it++;
}
}
for (char c : chars) {
output += c;
}
cout << output << endl;
output.clear();
}
return 0;
}
到了这里,关于C++大一基础知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!