1、前置递增(递减)与后置递增(递减)区别
均会对变量进行递增(递减),但在表达式运算中结果不同。前置递增(递减)会先对变量进行递增(递减)操作再计算,而后置则相反。
编程实例:
#include<iostream>
using namespace std;
int main() {
int value1 = 3;
int value2 = 3;
// a++ ==++a;
/*value1++;
++value2;
cout << "value1++:" << value1 << endl;
cout << "++value2: " << value2 << endl*/;
//a--==--a;
/*value1--;
--value2;
cout << "value1--:" << value1 << endl;
cout << "--value2: " << value2 << endl;
*/
int ex1;
int ex2;
/*ex1 = value1++ * 2;
ex2 = ++value2 * 2;
cout << "value1= " << value1 << endl;
cout << "value2= " << value2 << endl;
cout << "ex1= " << ex1 << endl;
cout << "ex2= " << ex2 << endl;*/
ex1 = value1-- * 2;
ex2 = --value2 * 2;
cout << "value1= " << value1 << endl;
cout << "value2= " << value2 << endl;
cout << "ex1= " << ex1 << endl;
cout << "ex2= " << ex2 << endl;
system("pause");
return 0;
}
2、输出不同进制数
在输入流(<<)前用标识符oct、hex、dec控制即可,默认为十进制,没有二进制标识符‘。且更改后一直影响输出方式,直到再次用标识符更改。
例
int a=12;
int b = 13;
cout << a << endl;//默认十进制
cout << hex << a << endl;//输出c(a的十六进制)
cout << b << endl;//输出 d(b 十六进制表示)
cout <<oct<< a << endl;//输出14(a的八进制)
cout << b << endl;//输出15(b的八进制)
cout << dec << a << endl;//output 12 (a 的十进制)
cout << b << endl;//output13(b 的十进制)
3、三目运算符
表达式: 表达式1?表达式2:表达式3
含义:如果表达式1为真则输出表达式2,否则输出表达式3
注意:三目运算符输出可以作为左值也可以作为右值,即 a=表达式1?表达式2:表达式3,或表达式1?表达式2:表达式3=b(作为左值输出必须为变量)
4、随机数生成
#include<iostream>
#include<ctime> //需要调用time()
using namespace std;
int main() {
// 用系统时钟生成随机数种子
srand(unsigned int(time(NULL)));
//生成 1-100随机数
int randnum = rand() % 100 + 1;
system("pause");
return 0;
}
5、获取n位数的各位数
最低位:取模(%10);
最高位:取整(/10^n)
m位(1<m<n):取两位整数后取模(/10^m%10)
a = num / 100;//num的百位
b = num / 10 % 10;//num的十位
c = num % 10;//num的个位
6、九九乘法表实现
九九乘法表特点:九行九列,每行的列数与当前行数相同,结果为行数乘以列数
#include<iostream>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++)//i表示行数
{
for (int j = 1; j <= i; j++)//j表示列数,每行的列数等于当前行数
{
cout << i << "*" << j << "=" << i * j << " ";//结果等于行数*列数
}
cout << endl;
}
system("pause");
return 0;
}
7、冒泡排序法
元素个素为n,进行n-1轮比较,每次将最大或最小的数放在最后,每轮进行n-当前轮数-1
#include<iostream>
#include<string>
using namespace std;
int main() {
int arry[10] = { 5,2,6,1,8,3,9,6,2,8 };
int arryl = 10;
int max = arry[0];
for (int i = 0; i < arryl-1; i++) //i为排序轮数,排序轮数=数组总元素-1
{
for (int j =0; j <10-i-1; j++)//j为每轮需比较次数,每次比较后将最大(最小)元素放在最后,比较次数为元素个数-当前轮数-1
{
if (arry[j] < arry[j+1]) //降序排列,最大的数放在最后
{
max = arry[j+1];
arry[j+1] = arry[j];
arry[j] = max;
}
}
}
cout << "排序后;" << endl;
for (int i = 0; i < arryl; i++)
{
cout << arry[i] << " ";
}
system("pause");
return 0;
}
8、指针常量与常量指针
指针常量:int * const p ,指针指向不能修改,所指向的值可以修改;
常量指针:const int * p,指针指向可以修改,所指向的值不能修改(常量)
9、值传递和地址传递
值传递不改变实参,地址传递修改实参
10、引用
int &a=b;a为b的引用,相当于b的别名,等价于指向b的指针常量
注意:引用必须初始化,且不可更改(指针常量不能改变指向);引用作为函数返回值不能返回局部变量的引用(函数运行完就释放,会造成不确定性,但系统回保留一次,即第一次使用可以得到正确值);函数返回的引用可以作为左值
本质:指针常量,可以修改值但不能改变指向;
常量指针: const int &a; 不可以改变引用值,主要用于函数引用传递,修饰形参,防止实参被误操作。
11、高级函数
默认参数:函数有多个参数,从第一个默认参数开始从左至右参数都必须有默认参数;函数声明与定义只能有一个有默认参数;
函数重载:相同的函数名,不同的参数(参数数量、顺序、个数),仅返回值不同不能作为函数重载的条件。调用时,系统自动根据参数的情况匹配相应函数。引用、常量引用可以作为函数重载的条件,当传递数据为常量时调用常量引用函数,因为int &a=10不合法。函数重载参数尽量不加默认值,容易导致二义性报错,void print(int a)、void print(int a,int b=10),调用print(a)导致报错。
12、析构函数
分类:有参、无参;普通、拷贝;
调用:括号法( 类名(参数),不要使用括号法调用无参析构,系统会识别为函数声明)、显示法(匿名对象,当前行执行后即释放对象)、隐式转换法(对象声明=赋值操作)。
注意:如果属性有在堆区开辟的(new),一定要自己提供析构拷贝函数,防止浅拷贝(拷贝前后数据内存空间重叠)带来的问题。
13、利用开发者工具查看对象模型
打开开发者工具->跳转盘符(F: 文件在C盘无需跳转 )->cd 文件地址(跳转到当前文件)->cl / d1 reportSingleClassLayout对象名 文件名(tab键补齐)回车
14、菱形继承问题(继承多个相同基类)
问题:相同数据有多份,造成二义性、空间浪费;
解决办法:使用虚基类,派生类中使用virtual继承方式;
底层实现:实际派生类中继承的是虚基类指针vbptr,用指针偏移量访问数据,可利用开发者工具查看,
15、文件操作
1)两种方式:ASCII存储、二进制存储
2)ASCII存储基本操作步骤:
包含头文件#include<fstream>;创建流对象(ifstream读文件需判断是否打开成功,ofstream写文件,fstream读写操作);打开文件(对象名.open(文件名,打开方式));读写文件;关闭文件(对象名.close())
读写方式:ios::in读文件; ios::out写文件; ios::ate;初始位置文件尾; ios::app追加文件; ios::trunc如文件存在先删除再创建; ios::binary二进制文件
组合读写方式:用 | ;例如:二进制方式写 ios::binary|ios::out
判断文件是否打开成功:ifstream.is_open()返回bool类型值,true打开成功,false打开失败
读取文件数据方式:四种,成员函数getline、成员函数个体(),全局函数getline,直接输出到数组中
实例:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main() {
//写文件
ofstream of;//创建流对象
of.open("test.txt", ios::app); //打开文件
of <<"大花花" <<endl;//写入数据
of << "花花" << endl;
of.close();//关闭文件
//读文件
ifstream ifs;//创建流对象
ifs.open("test.txt", ios::in);//打开文件
if (!ifs.is_open())//判断文件是否打开成功
{
cout << "文件打开失败" << endl;
return 0;
}
//读取文件数据
//第一种读取方式 数组接受 每次读取一行(以换行符为标志)
/*char buf[1024] = { 0 };
while (ifs >> buf)
{
cout << buf<<endl;
}*/
//第二种方式 利用ifstream 的getline()成员函数 每次获取一行
/*char buf[1024] = { 0 };
while (ifs.getline(buf, 1024))
{
cout << buf << endl;
}*/
//第三种方式 利用全局函数getline()包含string头文件
/*string buf;
while (getline(ifs,buf))
{
cout << buf << endl;
}*/
//第四种方式 利用读文件流成员函数getc() 每次读取一个字符
char c;
while ((c=ifs.get())!=EOF) //EOF表示文件尾
{
cout << c;
}
ifs.close(); //关闭文件
system("pause");
return 0;
}
3)二进制方式存储
写文件:成员函数write(const char*,sizeof());
读文件:成员函数read(char*,sizeof())
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class person {
public:
string m_name;
int m_age;
};
int main() {
person p = { "张三",20 };
/*--------写入二进制数据-------*/
//1、创建流对象
ofstream ofs;
//2、打开文件 成员函数open
ofs.open("Person.txt", ios::binary | ios::out);
//3、写数据 成员函数write
ofs.write((const char *)&p, sizeof(p));
//4、关闭文件
ofs.close(); //关闭文件
/*------------读取二进制文件-----------*/
//1、创建流对象
ifstream ifs;
//2、打开文件并判断是否打开成功
ifs.open("Person.txt", ios::binary | ios::in);
if (!ifs.is_open())
{
cout << "打开文件失败" << endl;
return 0;
}
//3、读取数据
person p1;
ifs.read((char*)&p1, sizeof(person));
cout << "姓名:" << p1.m_name << "年龄:" << p1.m_age << endl;
//4、关闭文件
ifs.close();
system("pause");
return 0;
}
储-可以存储任意数据,包括自定义数据