C++将内存划分为4个区域
#include
using namespace std;
// 全局变量
int g_a = 0;
int g_b = 1;
// 全局常量
const int c_g_a = 0;
int main()
{
// 内存分为四个区
// 代码区,全局区,栈区,堆区
cout<<"全局变量g_a的地址:"<<&g_a<
观察上述的地址
不要返回局部变量的地址
#include
using namespace std;
int* fun()
{
int a = 10;
return &a;
}
int main()
{
int* p = fun();
cout<<*p<
new / delete
int* fun()
{
int* a = new int(10);//在堆区开辟一个内存,值是10,然后将其的地址赋值给指针p
return a;
}
int main()
{
int* p = fun();
cout<<*p<
int a = 10;
int& b = a;
cout<<"b = "<
#include
using namespace std;
// 值传递
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
// 地址传递
void swap02(int* a,int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//引用传递,参数理解为起的别名
void swap03(int& a,int& b)
{
int temp = a;
a = b;
b = a;
}
int main()
{
int a = 10;
int b = 99;
swap01(a,b);//并没有交换两个值
swap01(&a,&b);//成功交换
swap03(a,b);//成功交换
return 0;
}
//不能返回局部变量的引用
int& fun01()
{
int a = 0;
return a;
}
int main()
{
int& ref = fun01();
cout<
// 函数的调用可以作为左值
int& fun02()
{
static int a = 0;//静态变量,存放在全局区,在程序结束后释放
return a;
}
int main()
{
int& ref2 = fun02();
cout<<"ref2 = "<
引用的本质就是一个指针常量
int main()
{
int a = 10;
//自动转换为 int* const ref = &a; 指针常量是指向一个不可更改的常量,也说明了引用为什么不可更改
int& ref = a;
ref = 20;//内部发现是一个引用,自动帮我们转换为 *ref = 20;
cout<<"a = "<
常量引用主要用来修饰形参,防止误操作(防止实参被修改)
//常量引用,用来修饰形参,防止实参被修改
// 这个函数会将外部的实参修改掉
void printValue01(int& a)
{
a = 0;
cout<<"value + 10 = "<
引用作为函数参数
#include
using namespace std;
// 函数重载需要注意的事项
void fun(int& a)// int& a = 10 不合法
{
cout<<"fun(int& a)"<
函数重载遇到默认参数
// 函数重载遇到默认参数
void fun01(int a,int b = 10)
{
cout<<"fun01(int a,int b = 10)"<
#include
class Student
{
public:
string name;
int stuId;
void printInfo()
{
cout<<"name = "<
C++中,struct和class的唯一区别就是访问权限不同
构造函数和析构函数都是必须有的实现,如果不提供,编译器会提供至少3个函数:默认构造函数(空实现)、析构函数(空实现)、拷贝构造函数 (值拷贝)
如果用户定义了有参构造函数,c++不会提供无参构造函数,但是会提供拷贝构造函数
如果用户定义了拷贝构造函数,c++不会提供其它构造函数
构造函数
可以重载
创建对象时调用
析构函数
不可以重载
程序的生命周期终结时调用
#include
using namespace std;
class Person
{
public:
Person()
{
cout<<"Person 构造函数"<
3种构造的方法
class Person
{
private:
int age;
public:
Person()
{
cout<<"Person 无参函数"<age = age;
cout<<"Person 有参构造"<age = p.age;
cout<<"Person 拷贝构造函数"<
Person fun()
{
Person p1;
return p1;//这里返回的并不是p1对象,而是执行力拷贝构造函数,创建了一个新的对象
}
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
如果有属性是在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
class Car
{
private:
int car_id;
double* car_value;
public:
Car()
{
cout<<"无参构造函数";
}
Car(int id,double value)
{
car_id = id;
car_value = new double(value);//在堆区new一个空间,返回一个指针
cout<<"有参构造函数";
}
//自己实现拷贝构造函数,解决编译器提供的拷贝构造函数带来的浅拷贝问题
Car(const Car& car)
{
car_id = car.car_id;
//car_value = car.car_value;//编译器提供的拷贝构造函数,就是这行代码,浅拷贝
// 深拷贝,解决car_value内存释放冲突问题
car_value = new double(*car.car_value);
}
~Car()
{
if (car_value != NULL)//car_value是在堆区手动创建的,需要手动释放
{
delete car_value;
car_value = NULL;
}
cout<<"析构函数"<
class A
{
private:
int A_a;
int A_b;
int A_c;
public:
A(int a,int b,int c):A_a(a),A_b(b),A_c(c){}
};
int main()
{
A aa(1,3,4);
return 0;
}
class Phone
{
string name;
}
class Person
{
int id;
Phone phone;
}
class A
{
private:
static string name;//类外访问不到
public:
static int id;
static void fun()
{
cout<
空对象占用的内存空间为 1
编译器会给每个空对象分配 1 个字节空间,为了区分空对象占内存的地址,每个空对象也应该有一个独一无二的内存地址
class A
{
};
int main()
{
A a;//空对象 sizeof(a) = 1
}
class B
{
int aa;//属于类的对象
static int bb;//不属于类的对象
void fun();//不属于类的对象
};
int main()
{
B b;//sizeof(b) = 4
}
class Person
{
int age;
Person(int age)
{
this->age = age;//this指针解决命名冲突
}
Person& addAge01(Person& p)//返回 引用
{
this->age += p.age;
return *this;//返回对象本体
}
Person addAge02(Person& p)//返回 值
{
this->age += p.age;
return *this;//返回一个新的对象(调用拷贝构造函数)
}
};
class Phone
{
int age;
void showClass()
{
cout<"this is class Phone";
}
void showAge()
{
if (this == NULL)
{
return;
}
cout<<"age is "<age
}
}
int main()
{
Phone* p = NULL;
phone.showClass();//正常执行
phone.showAge();//报错 空指针异常
return 0;
}
常函数
mutable
,在常函数中就可以修改class A
{
//this指针本质是一个指针常量,指针的指向是不可修改的
//后面加const,意味着指针指向的值也不可以修改
void showA() const
{
//this->age = 10;//会报错,this指针不可以修改
this->id = 1;//正常执行
}
int age;
mutable id;//特殊变量,在常函数和常对象中可以修改
}
常对象
声明对象前加 const
常对象只能调用常函数
void fun()
{
const Person p;//在对象前加const,变为常对象
//p.age = 10;//错误,不能被修改
p.id = 1;//正确,可以修改
p.showA();//正确,可以执行
}
全局函数作友元,可以访问类的私有成员
#include
#include
using namespace std;
class Home
{
//声明全局函数friend_fun是一个友元,就可以访问Home中的的私有成员
friend void friend_fun(Home* home);
public:
Home()
{
this->sitting_room = "客厅";
this->bad_room = "卧室";
}
string sitting_room;
private:
string bad_room;
};
void friend_fun(Home* home)
{
cout<<"公共属性 "<sitting_room<bad_room<
类作友元
class TV
{
public:
Home* home;
TV()
{
this->home = new Home;
}
}
class Home
{
//类作友元,
friend class TV;
public:
Home()
{
this->sitting_room = "客厅";
this->bad_room = "卧室";
}
string sitting_room;
private:
string bad_room;
};
成员函数作友元
class TV
{
private:
Home* home;
public:
void visit01()
{
cout<sitting_room<bad_room<sitting_room<bad_room<sitting_room = "客厅";
this->bad_room = "卧室";
}
string sitting_room;
private:
string bad_room;
};
+
运算 符重载,实现两个自定义对象的相加#include
using namespace std;
class Person
{
public:
Person(){}
Person(int a,int b)
{
this->m_a = a;
this->m_b = b;
}
// 1 成员函数重载 + 运算符
Person operator+(Person& p)
{
Person temp;
temp.m_a = this->m_a + p.m_a;
temp.m_b = this->m_b + p.m_b;
return temp;
}
int m_a;
int m_b;
};
// 2 全局函数重载 + 运算符
Person operator+(Person& p1,Person& p2)
{
Person p3;
p3.m_a = p1.m_a + p2.m_a;
p3.m_b = p1.m_b + p2.m_b;
return p3;
}
//函数重载的版本
Person operator+(Person& p,int num)
{
Person p3;
p3.m_a = p.m_a + num;
p3.m_b = p.m_b + num;
return p3;
}
int main()
{
//实现两个自定义数据类型相加的运算
Person p1 = Person(2,3);
Person p2 = Person(10,20);
Person p3 = p1 + p2;
Person p4 = p1 + 99;
cout<<"p3.m_a = "<
<<
运算符重载class Person
{
friend ostream& operator<<(ostream& out,Person p);
public:
Person(){}
Person(int a,int b)
{
this->m_a = a;
this->m_b = b;
}
private:
int m_a;
int m_b;
};
//只能用全局函数实现 重载<<运算符
ostream& operator<<(ostream& out,Person p)
{
out<<"m_a = "<#include
using namespace std;
class MyInteger
{
friend ostream& operator<<(ostream& out,MyInteger myint);
public:
MyInteger(){}
MyInteger(int m)
{
this->m_num = m;
}
//重载 前置++ 运算符
MyInteger& operator++()//用MyInteger& 是为了对自身进行返回,一直对一个数据进行++
//如果 用MyInteger,则会新创建一个MyInteger对象
{
//先进行++运算
this->m_num++;
// 在将自身返回
return *this;
}
//重载 后置++ 运算符
MyInteger operator++(int)//int表示站位参数,可以用于区分前置和后置
{
// 先记录最开始的值
MyInteger temp = *this;
// 再递增
this->m_num++;
// 返回最开始的值
return temp;//局部对象,只能返回值,不能返回引用
}
private:
int m_num;
};
// 重载<<运算符
ostream& operator<<(ostream& out,MyInteger myint)
{
out<
=
运算符重载#include
using namespace std;
class Person
{
public:
int* m_age;
Person(){}
Person(int age)
{
this->m_age = new int(age);
}
~Person()
{
if (this->m_age != NULL)
{
delete this->m_age;
this->m_age = NULL;
}
}
Person& operator=(Person& p)
{
//编译器提供浅拷贝,会出现内存释放冲突
//this->m_age = p.m_age;
//1 应该先判断是否有属性在堆区,如果有,先释放干净,然后再深拷贝
if (this->m_age != NULL)
{
delete this->m_age;
this->m_age = NULL;
}
//深拷贝
this->m_age = new int(*p.m_age);
return *this;
}
};
int main()
{
Person p1(20);
Person p2;
p2 = p1;
cout<<"p2 = "<<*p2.m_age<
=
的重载#include
#include
using namespace std;
class Person
{
public:
Person(int age,string name)
{
this->m_age = age;
this->m_name = name;
}
//重载两个对象的关系运算符
bool operator==(Person& p)
{
if (this->m_age == p.m_age && this->m_name==p.m_name)
{
return true;
}
else
{
return false;
}
}
bool operator!=(Person& p)
{
if (this->m_age == p.m_age && this->m_name==p.m_name)
{
return false;
}
else
{
return true;
}
}
int m_age;
string m_name;
};
int main()
{
Person p1(20,"zhangsan");
Person p2(20,"zhangsan");
if (p1 == p2)
{
cout<<"p1和p2 相等"<
()
运算符——仿函数#include
#include
using namespace std;
class printClass
{
public:
// 重载函数调用()
void operator()(string s)
{
cout<
降低代码重复
父类:基类
子类:派生类
#include
using namespace std;
class Page
{
public:
void header()
{
cout << "页面头部内容。。" << endl;
}
void footer()
{
cout << "页面尾部内容。。" << endl;
}
};
// 继承
class BuyPage : public Page
{
public:
void content()
{
cout << "购买页面" << endl;
}
};
class Browse : public Page
{
public:
void content()
{
cout << "浏览页面" << endl;
}
};
int main()
{
BuyPage buy;
buy.header();
buy.footer();
buy.content();
Browse browse;
browse.header();
browse.footer();
browse.content();
return 0;
}
#include
using namespace std;
class Father
{
public:
int m_a = 1;
protected:
int m_b = 2;
private:
int m_c = 3;
};
class Son01 : public Father
{
public:
void test01()
{
cout << m_a << endl; // 公共
cout << m_b << endl; // 保护
// cout<
父类中的所有非静态成员属性都会被子类继承下去,只是某些属性的权限不同
class Father
{
public:
int m_a = 1;
protected:
int m_b = 2;
private:
int m_c = 3;
};
class Son04 : public Father
{
public:
int m_d = 0;
};
void test()
{
//私有成员也被继承了,只是访问不到而已
cout << "size of : "<
class Base
{
Base()
{
cout<<"Base 构造函数。。"<
class Base
{
Base()
{
int m_a = 100;
}
public:
print_hh()
{
cout<<"Base: hh"<
子类,直接访问
父类,加作用域
class Base
{
public:
static int s_a;
static void fun()
{
cout << "Base--fun()" << endl;
}
};
int Base::s_a = 10;
class Son : public Base
{
public:
static int s_a;
static void fun()
{
cout << "Son--fun()" << endl;
}
};
int Son::s_a = 20;
void test01()
{
Son s;
// 通过对象访问
cout << s.s_a << endl; // 20
cout << s.Base::s_a << endl; // 10
s.fun(); // Son--fun()
s.Base::fun(); // Base--fun()
// 通过类名访问
cout << Son::s_a << endl; // 20
cout << Son::Base::s_a << endl; // 10
Son::fun();
Son::Base::fun();
}
class Base1
{
public:
Base1()
{
m_a = 1;
}
int m_a;
};
class Base2
{
public:
Base2()
{
m_a = 2;
}
int m_a;
};
class Son : public Base1, public Base2
{
public:
Son()
{
m_b = 3;
m_c = 4;
}
int m_b;
int m_c;
};
void test()
{
Son s;
cout << "size of : " << sizeof(s) << endl; // 16
// 不建议用多继承,因为会出现二义性,必须加作用域用于区分
cout << "Base1 :" << s.Base1::m_a << endl; // 1
cout << "Base2 :" << s.Base2::m_a << endl; // 2
}
两个派生类继承同一个基类,又有某个类同时继承两个派生类
A
/ \
B C
\ /
D
#include
using namespace std;
class Animal
{
public:
Animal()
{
m_age = 0;
}
int m_age;
};
// 虚继承
class Sheep : virtual public Animal
{
public:
Sheep()
{
m_age = 10;
}
};
// 虚继承
class Tuo : virtual public Animal
{
public:
Tuo()
{
m_age = 20;
}
};
class SheepTuo : public Sheep, public Tuo
{
};
int main()
{
SheepTuo st;
// cout<
虚函数,地址晚绑定,在运行阶段绑定函数地址,如果要实现多态,就需要使用虚函数
virtual
,如果不加virtual
,地址早绑定,在编译阶段确定函数地址
动态多态满足条件
#include
using namespace std;
class Animal
{
public:
//虚函数,地址晚绑定,在运行阶段绑定函数地址,如果要实现多态,就需要使用虚函数virtual
//如果不加virtual,地址早绑定,在编译阶段确定函数地址
virtual void speak()
{
cout << "animal speaking" << endl;
}
};
class Cat : public Animal
{
public:
void speak()
{
cout << "cat speaking" << endl;
}
};
class Dog : public Animal
{
public:
void speak()
{
cout << "dog speaking" << endl;
}
};
void dospeaking(Animal &animal)
{
animal.speak();
}
int main()
{
Cat cat;
// dospeaking(cat); // animal speaking(Animal类中的speak()不加virtual)
dospeaking(cat); // cat speaking
Dog dog;
dospeaking(dog); // dog speaking
return 0;
}
#include
using namespace std;
class AbstractCalcuator
{
public:
virtual int getResult()
{
return 0;
}
int number01;
int number02;
};
class AddCalcuator : public AbstractCalcuator
{
public:
int getResult()
{
return number01 + number02;
}
};
class SubCalcuator : public AbstractCalcuator
{
public:
int getResult()
{
return number01 - number02;
}
};
class MulCalcuator : public AbstractCalcuator
{
public:
int getResult()
{
return number01 * number02;
}
};
int main()
{
// 实现多态的条件
// 父类指针或引用指向子类对象
AbstractCalcuator *cal = new AddCalcuator; // 在堆区创建对象
cal->number01 = 10;
cal->number02 = 20;
cout << "number01 + number02 = " << cal->getResult() << endl;
// cal指向堆区对象,用完要释放
delete cal;
cal = new SubCalcuator; // 在堆区创建对象
cal->number01 = 10;
cal->number02 = 20;
cout << "number01 - number02 = " << cal->getResult() << endl;
// cal指向堆区对象,用完要释放
delete cal;
cal = new MulCalcuator; // 在堆区创建对象
cal->number01 = 10;
cal->number02 = 20;
cout << "number01 * number02 = " << cal->getResult() << endl;
// cal指向堆区对象,用完要释放
delete cal;
return 0;
}
抽象类无法实例化对象
子类必须重写纯虚函数,负责也属于抽象类
#include
using namespace std;
class Base
{
public:
virtual void fun() = 0;
};
class Son : public Base
{
public:
void fun()
{
cout << "fun()函数正在调用。。" << endl;
}
};
int main()
{
Base *base = new Son;
base->fun();
return 0;
}
问题:多态使用时,如果有子类的属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决:将父类中的析构函数改为虚析构或者纯虚析构
虚析构或纯虚析构是用来解决父类指针释放子类对象
如果子类没有堆区数据,可以不写虚析构或纯虚析构
拥有纯虚析构函数的类也属于抽象类
#include
#include
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal构造函数" << endl;
}
// 利用虚析构,可以解决 父类指针释放子类对象时不干净的问题
virtual ~Animal()
{
cout << "Animal析构函数" << endl;
}
virtual void eat() // 多态的实现条件
{
cout << "animal eating..." << endl;
}
};
class Cat : public Animal
{
public:
Cat(string name)
{
m_name = new string(name); // 堆区创建一个变量
cout << "Cat构造函数" << endl;
}
~Cat()
{
if (m_name != NULL)
{
delete m_name;
m_name = NULL;
cout << "Cat析构函数" << endl;
}
}
string *m_name; // 一个指针类型的属性
void eat()
{
cout << *m_name << " eating..." << endl;
}
};
int main()
{
Animal *animal = new Cat("Tom");
animal->eat();
// 父类指针在析构时,不会调用子类的析构函数,导致如果子类有堆区属性,没有成功释放,出现内存泄露
delete animal;
return 0;
}
纯虚析构
也是一个抽象类,无法实例化对象
#include
#include
using namespace std;
class Animal
{
public:
Animal()
{
cout << "Animal构造函数" << endl;
}
// 纯虚析构,类外必须实现
virtual ~Animal() = 0;
virtual void eat() // 多态的实现条件
{
cout << "animal eating..." << endl;
}
};
Animal::~Animal()
{
cout<<"Animal析构函数"<eat();
// 父类指针在析构时,不会调用子类的析构函数,导致如果子类有堆区属性,没有成功释放,出现内存泄露
delete animal;
return 0;
}
#include
using namespace std;
class CPU
{
public:
virtual void calculate() = 0;
};
class Mermory
{
public:
virtual void storage() = 0;
};
class VideoCard
{
public:
virtual void display() = 0;
};
class Computer
{
public:
Computer(CPU *cpu, Mermory *mermory, VideoCard *videocard)
{
m_cpu = cpu;
m_mermory = mermory;
m_videocard = videocard;
}
void work()
{
m_cpu->calculate();
m_mermory->storage();
m_videocard->display();
}
~Computer()
{
if (m_cpu == NULL)
{
delete m_cpu;
m_cpu = NULL;
}
if (m_mermory == NULL)
{
delete m_mermory;
m_mermory = NULL;
}
if (m_videocard == NULL)
{
delete m_videocard;
m_videocard = NULL;
}
}
private:
CPU *m_cpu;
Mermory *m_mermory;
VideoCard *m_videocard;
};
class IntelCPU : public CPU
{
public:
void calculate()
{
cout << "Intel cpu working.." << endl;
}
};
class LenovoCPU : public CPU
{
public:
void calculate()
{
cout << "Lenovo cpu working.." << endl;
}
};
class IntelMermory : public Mermory
{
public:
void storage()
{
cout << "Intel mermory working.." << endl;
}
};
class LenoveMermory : public Mermory
{
public:
void storage()
{
cout << "Lenovo mermory working.." << endl;
}
};
class IntelVideoCrad : public VideoCard
{
public:
void display()
{
cout << "Intel videocard working.." << endl;
}
};
class LenovoVideoCrad : public VideoCard
{
public:
void display()
{
cout << "Lenovo videocard working.." << endl;
}
};
int main()
{
// 组装一台电脑
CPU *cpu01 = new IntelCPU;
Mermory *mermory01 = new IntelMermory;
VideoCard *videocard01 = new IntelVideoCrad;
Computer *computer01 = new Computer(cpu01, mermory01, videocard01);
computer01->work();
delete computer01;
Computer *computer02 = new Computer(new LenovoCPU, new LenoveMermory, new LenovoVideoCrad);
computer02->work();
delete computer02;
return 0;
}
#include
#include
using namespace std;
int main()
{
// 创建写文件流对象
ofstream ofs;
// 指定打开文件的方式
ofs.open("test01.txt", ios::out);
// 写内容
ofs << "姓名:张三" << endl;
ofs << "性别:男" << endl;
ofs << "年龄:100" << endl;
ofs << "今天是2023年11月8日。。。" << endl;
// 关闭流对象
ofs.close();
return 0;
}
#include
#include
using namespace std;
int main()
{
// 创建读文件流对象
ifstream ifs;
// 读取文件
ifs.open("test01.txt", ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败!!" << endl;
}
// 第一种
// char buffer[1024] = {0};
// while (ifs >> buffer)//按行读取
// {
// cout << buffer << endl;
// }
// 第二种
// char buffer[1024] = {0};
// while (ifs.getline(buffer, sizeof(buffer))) // 每次按行读取存储在buffer中,每次最大读取sizeof()
// {
// cout << buffer << endl;
// }
// 第三种
// string buffer;
// while (getline(ifs, buffer))
// {
// cout << buffer << endl;
// }
// 第四种
char c;
while ((c = ifs.get()) != EOF) // 逐个字符读取,EOF是文件末尾的标志
{
cout << c;
}
// 流关闭
ifs.close();
system("pause");
return 0;
}
#include
#include
using namespace std;
class Person
{
public:
char name[100];
int age;
};
int main()
{
// 创建流对象
ofstream ofs("test02.txt", ios::out | ios::binary);
// 打开文件
// ofs.open("test02.txt",ios::out|ios::binary);
// 写文件
Person perosn = {"james", 40};
ofs.write((const char *)&perosn, sizeof(Person));
ofs.close();
return 0;
}
#include
#include
using namespace std;
class Person
{
public:
char name[100];
int age;
};
int main()
{
// 创建读文件对象
ifstream ifs;
ifs.open("test02.txt", ios::in | ios::binary);
if (!ifs.is_open())
{
cout << "文件打开时失败!!" << endl;
}
// 读文件
Person person;
ifs.read((char *)&person, sizeof(Person));
cout << "name: " << person.name << ", age: " << person.age << endl;
ifs.close();
system("pause");
return 0;
}
泛型编程
函数模版,类模版
自动类型推导必须推导出一致的数据类型
模版必须要确定出T的数据类型
#include
using namespace std;
// 模版函数
template
void mySwap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
template
void printInfo()
{
cout << "it's great!" << endl;
}
int main()
{
int a = 10;
int b = 20;
// 1 自动类型推导
mySwap(a, b);
cout << "a = " << a << endl; // 20
cout << "b = " << b << endl; // 10
// 2 显式指定类型
mySwap(a, b);
cout << "a = " << a << endl; // 10
cout << "b = " << b << endl; // 20
// 自动类型推导必须要推导出正确的类型
char c = 'q';
// mySwap(a,c);//错误的
// 模版必须要确定出T的类型
// printInfo();//错误的
printInfo(); // 必须显式指定
system("pause");
return 0;
}
例子
#include
using namespace std;
// 交换两个值的模版函数
template
void my_swap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
// 降序排序的模版函数
template
void sortArr(T arr[], int len) // 降序
{
int i = 0;
while (i < len)
{
int max_idx = i;
for (int j = i + 1; j < len; j++)
{
if (arr[j] > arr[max_idx])
{
max_idx = j;
}
}
if (max_idx != i)
{
my_swap(arr[max_idx], arr[i]);
}
i++;
}
}
//打印不同类型数组的模版函数
template
void printArr(T arr[], int len)
{
int i = 0;
while (i < len)
{
cout << arr[i];
i++;
}
cout << endl;
}
int main()
{
char charArr[] = "efcsab";
int lens01 = sizeof(charArr) / sizeof(char);
sortArr(charArr, lens01);
printArr(charArr, lens01);
int intArr[] = {2, 4, 6, 3, 0, 9, 3, 8};
int lens02 = sizeof(intArr) / sizeof(int);
sortArr(intArr, lens02);
printArr(intArr, lens02);
system("pause");
return 0;
}