C++ 中常用的一些东西,通过使用动态数组来实现顺序表,
掌握了一下知识点:
1.预处理有三中方法
宏定义,文件包含,条件编译
2.使用同名的变量时,可以在外层使用命名空间 类解决变量名重定义的错误
3.类中三个访问权限,
public : 公有访问权限,主要写一些函数接口
protected: 保护访问
private 私有访问权限 封装性,
4.构造函数\析构函数
5.重载运算符
sub.h文件
/* 实现一个顺序表 1.创建类.成员包含.指向顺序表的指针,顺序表的长度,顺序表的元素个数 2.实现功能:添加,删除,修改,查看 */ //用头文件进行声明的时候,可以使用 ifnedf endif #ifndef __SUB_H__ /* #ifndef 是if not define 的简写 它是预处理功能三种(宏定义,文件包含,条件编译)的条件编译 再C++中使用可以避免出现 " 变量重复定义的错误 " */ #define __SUB_H__ #include <iostream> using namespace std; //使用作用域,保证函数名不会出错 namespace data { //创建vector类 class vector { //定义私有成员,包括指向空间的指针,空间大小,空间元素个数 private: int *element = nullptr; size_t count = 0; //size_t 是地址线宽度 int是数据线宽度, size_t length = 0; //定义保护成员 新空间不足需要生成新空间 protected: bool re_new(int size); //定义公有成员函数包括:构造函数,析构函数,成员其它函数 public: //可以统一使用返回值为bool的来确定函数的使用情况 //析构函数 进行初始化的作用 //这里首先,初始化一下,默认参数 在这里声明 定义不用 vector(int count=10); //析构函数 进行指针等的释放工作 ~vector(); //顺序表添加 使用bool为返回值,方便检测是否函数运行成功 //插入需要两个参数:分别是插入的位置,插入的内容 bool insert(int index, int elem); //顺序表删除 只需要插入删除的位置即可 bool erase(int index); //重载[] 进行内容的查找及修改 int & operator[](int index); //查看元素个数 int Ssize()const { return length; } //运算符重载,方便输出 //使用友元函数重载cout运算符 friend ostream & operator<<(ostream & o, const vector & vec); }; } #endif // !__SUB_H__
sub.cpp文件
#include "sub.h" using namespace std; //前边类定义了作用域,这里需要使用才能访问 namespace data { //构造函数 需要作用域来明确函数属于哪里 vector::vector(int count ) //参数已经为10,在声明中 { //初始化基本成员变量 //因为要使用类内的count来赋值,碰到相同变量名, //使用this指针来区分.有this指针的是属于类的变量 this->count = count; length = 0; //元素个数,初始为0 //初始化指向顺序表空间的指针 //在堆内申请空间,空间大小为count element = new int[count]; // = {0}; 初始化繁琐 //申请完空间需要对空间进行初始化 \ 使用memset(指针变量,初始值, 空间大小 ) memset(element ,0,sizeof(int)*count); } //析构函数 析构没参数, 构造有参数,参数可变 //析构函数 用来释放对象占用的空间 vector::~vector() { //首先释放指向空间的指针 //判断指针现在是否为空 if (element!=nullptr) { //使用 new 申请, delete 进行释放, //这里使用方括号是因为 申请时, 类型是 int[] delete[] element; } //初始化元素个数 length = 0; } //顺序表插入\添加 /* 需要考虑: 1.插入的位置是否合适,有可能插入的是-1的位置,数组下标最小为0,-1就会出现错误 2.判断空间大小,因为空间大小是初始设定的,在添加数据时有可能数据超出 3.添加元素的位置,需要讲后边的所有元素向后移动一位,才能空出来 4.将空出来的位置赋值需要的元素 5.将元素个数 +1 6.返回成功 */ //index 为插入的位置, elem为插入的元素内容 //不要忘记类的作用域 bool vector::insert(int index ,int elem) { //1.判断位置 if (index<0 || index >length) { //因为不合适,所以需要退出程序 return false; } //2.判断空间大小 看元素个数是否和空间大小相等,相等说明空间不足 if (length == count) { //相等说明空间不足,需要开辟新内存 //这里直接使用 类的成员函数, 如果开辟空间失败需要提示一下 if (!re_new(count+10)) { printf("空间申请失败!"); //使用system 让用户看到提示 system("pause"); //exit为C++的退出函数,exit(0)正常退出,非0 非正常退出 exit(-1); } } //3.插入位置移动 通过循环遍历,位置,将位置后移 //这里的i 需要等于元素的个数, 因为总长度才能找到对应 存在的位置 //当i到需要插入的位置时,在向后移动一次,就可以空出这个位置了 for (int i=length-1; i>=index; --i ) { //将当前位置元素移动到下一个位置, element[i + 1] = element[i]; } //将插入位置 赋值内容 element[index] = elem; //因为插入了一个内容所以需要将元素个数 +1 ++length; //返回成功 return true; } //删除元素 /* 需要考虑: 1.判断位置是否有效 2.删除的位置,后边的依次向前移动一位 这里需要注意,最后一位的问题.因为是依次向前移动,所以需要将最后一位赋值为0 , 就是说:最后一个元素的下一位也要向前移动,覆盖原来的元素 3.将元素个数 -1 4.返回成功 */ //只需要删除的位置即可 bool vector::erase(int index) { //1.判断位置 因为length表示多少个元素,所以 length -1 是下标的位置 if (index <0 || index >length-1) { return true; } //2.删除元素 for (int i =index;i<=length-1;i++ ) { element[i] = element[i + 1]; } //3.元素个数 -1 --length; //4. 返回成功 return true; } //重载[] 方便存取元素 int & vector::operator[](int index) { //重载运算符,不能改变运算符的性质, //[]就是一个下标值,所以这里可以进行,查询和修改 return element[index]; } //开辟新空间 调用此函数说明空间不足,需要重新分配 bool vector::re_new(int size) { //申请堆空间,大小为 size 是实参传进来比原空间大10的数, //如果向让程序更优,这里需要设置成原数的2倍,避免多次分配空间 int* new_element = new int[size]; //申请堆空间后,需要初始化 使用memset memset(new_element , 0 , sizeof(int)*size); //这里还要检测一下空间是否申请成功 if (!new_element) //申请成功返回的是1,取反,就是0 ,不进入判断 { return false; } //将原空间的内容拷贝到新空间 使用memcpy函数 memcpy(new_element,element,this->count*sizeof(int)); //释放原来空间 delete[] element; //将指针指向新空间 element = new_element; //这里不要忘记, 原来空间替换成新空间大 this->count = size; //返回成功 return true; } //因为这里是友元函数,所以属于一个全局函数,不需要类名作用域 ostream& operator<<(ostream & o,const vector & vec) { for (int i=0;i<vec.Ssize();i++) { //endls 是 输出一个空格 o << vec.element[i] << ends; } return o; } }
main.cpp文件
#include "sub.h" int main() { //这里需要作用于来定义类的对象 //当创建对象以后,构造函数就执行 data::vector vec(10); //写入元素 for (int i =0;i<30;i+=2) { vec.insert(0, i + 1); } //经过运算符重载,vec可以直接输出 cout << vec << endl; // 查询第几个位置,第几个值 cout << vec.operator[](5) << endl; //将第几个值,修改成多少 vec.operator[](5) = 555; cout << vec << endl; return 0; }