自用数组总结(C++)

数组

数组是一个变量,由数据类型相同的一组元素组成

数组的结构和基本要素:
标识符(唯一的名称): 数组的名称,用于区分不同数组
数组元素:向数组中存放的数据
元素下标(从零开始):对数组元素的编号(每个元素都可以通过下标来访问)
元素类型:数组元素的数据类型

数组的长度固定不变,避免数组越界,并且C与C++ 数组越界编译器一般不会报错

一维数组

datatype arrayName[size]

int num[2];

初始化

在C99的编译器里C++ 中可以使数组的长度为变量 但推荐用动态数组vector

可以理解成数组长度可以用变量定义,但是初始化的时候是不能变量.因为程序的初始化是在执行之前,所以在程序执行之前不能给一个变量给数组初始化.除了const int等等.

int echo[6] = {1,2,3,4,5,6};
//元素个数与声明的一致

int goal[2] = {0,2,3,4;}
//后面的元素未初始化,默认值为0

int days[] = {1,2};
//元素的个数初始化为2

int air[] = {};
//错误,未知个数初始化错误.

在C++11后初始化可以省略 = 号 //int days[] {1,5};
大括号可以为空,表示元素置零. //int days[365] = {};

const int N = 100;
int num[N];
num[0] = 6666;
int N = 100;
int num[N];
num[0] = 6666;

利用sizeof()探究未赋值的数值;

int num[5];
cout << "数组的长度为"<< sizeof(num)/sizeof(int) <<endl;

因为初始化后的num里默认是5个0,sizeof(num)得到的是5个int的长度,所以再除以一个int长度的值就为5

查找数组中数字的时候,养成良好习惯.将存储下标的变量设置为不可能的值,像-1或者INT_MIN

int search_index = -1; 
	for (i = 0; i < 7; i++)
	{
		if (total[i] == j)
		{	
			search_index = i;
			cout << "你寻找的数字在数组的第" << i + 1 << "号" << endl;
		}
	}
	if (search_index == -1)
	{
		cout << "数组中没有你想要的数字喔" << endl;
	}

数组的大小一旦确定了就不能再更改了
为了实现静态数组的动态化我们可以

double num[999];		//先预留足够大的空间
int num_count = 0; 		//当前元素的个数
num[num_count++] = 1;
num[num_count++] = 3;
num[num_count++] = 1;
num[num_count++] = 4;

数组排序

冒泡排序

按从小到大从上到下排列
1.最下面的数从下面往上冒泡,假如下面的数比上面小就往上走.往上走就会有调换的次数.第一轮的时候5个数字我们就需要比较4次.
2.第二轮的时候同理冒泡,但是这第二个数是不需要和第一个数对比的,因为在第一次循环的时候已经比较过了,所以比较的次数要比第二轮的少一次.也就是只需要比较3次.
3.然后利用嵌套循环进行冒泡排序的控制.外层控制5个数字里4个数字要去冒泡,也就是数字冒泡的轮数.而内层控制每个数字冒泡要比较多少次,因为每轮结束后下一轮比较的次数要少1.

int num[5];
	int i,j,temp;
	for (i = 0; i < 5; i++)
	{
		cin >> num[i];
	}
	cout << "排序前的数组顺序为:";
	for (i = 0; i < 5; i++)
	{
		cout << num[i] << "\t";
	}

	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4 - i; j++)
		{
			if (num[j] < num[j + 1])
			{
				temp = num[j];
				num[j] = num[j + 1];
				num[j + 1] = temp;
			}
		}
	}
	cout << "排序后的数组顺序为:";
	for (i = 0; i < 5; i++)
	{
		cout << num[i] << "\t";
	}
选择排序

用temp临时数进行打擂台,从第一个数赋值开始,和后面每个数进行比较,如果temp里的数比当前面对的数小,就进行一次调回,在最后的时候进行数组内调换数字(当前的num[i]和极值,)极值值就排到边边.

跟冒泡排序的区别在于内层循环的j与i的关系为 j = i + 1, 与当前num[i]的下一位数比较

int num[5];
	int i, j, temp;
	int min_index = 0;
	for (i = 0; i < 5; i++)
	{
		cin >> num[i];
	}
	cout << "排序前的数组顺序为:";
	for (i = 0; i < 5; i++)
	{
		cout << num[i] << "\t";
	}
	cout << "\n此数组中的个数为:" << sizeof(num) / sizeof(int) << endl;
	for (i = 0; i < sizeof(num) / sizeof(int) - 1; i++)
	{
		temp = num[i];
		min_index = i;				//超几把重要,不仅最小的数字要重置,最小数的小标也要重置,假如没有没有进入j循环的比较环节,min_index讲沿用上一次循环的下标.
		for (j = i + 1; j < sizeof(num) / sizeof(int) ; j++)
		{
			if ( num[j] < temp )
			{
				temp = num[j];
				min_index = j;
			}
		}
		if (min_index > i)
		{
			num[min_index] = num[i];
			num[i] = temp;
		}
	}

	cout << "排序后的数组顺序为:";
	for (i = 0; i < 5; i++)
	{
		cout << num[i] << "\t";
	}

元素的插入和删除

删除的话要设置好下标为-1 和上面的排序一样 假如查找不到要删除的数字就不更改下标,然后通过检测下标是否为-1来判读是否有要删除的数字.

1.找一个数字比目标数字大的,放在它的旁边.(需要注意数据有可能有重复性, 例如查找从大到小排序的数组,找比2大并且将2放在其后面时,我们可能会放到第一个3的后面,那我们就可以换个查找方式,找到比2小的数,放在它的前面.)
2.从最后一个元素开始向右挪动
3.将挪出来的空位插入目标数字
4.数组的长度增加一个数据. // num_count++;

double num[999];		//先预留足够大的空间
	int num_count = 0; 		//当前元素的个数
	num[num_count++] = 1;
	num[num_count++] = 3;
	num[num_count++] = 1;
	num[num_count++] = 4;
	double temp;
	int max_index = 0;

	double del_num;
	int del_index = -1;


	for (int i = 0; i < num_count; i++)			//输出
	{
		cout << num[i] << "\t";
	}
	cout << endl;

	for (int i = 0;i < num_count - 1; i++)		//排序
	{
		temp = num[i];
		max_index = i;
		for (int j = num_count; j > i; j--)
		{
			if (temp < num[j])
			{
				temp = num[j];
				max_index = j;
			}
		}
		num[max_index] = num[i];
		num[i] = temp;
	}
	for (int i = 0; i < num_count; i++)			//输出
	{
		cout << num[i] << "\t";
	}

	int insert_index = num_count;				//输入数字的下标.使数组里数字个数 + 1,且把下标定在最后一个.
	double insert_power;

	cout << "\n请输入数字" << endl;
	cin >> insert_power;
	num[insert_index] = insert_power;


	for (int i = 0; i < num_count; i++)				//把输入的数字放在最后,然后从头到尾查找一次
	{
		if ( num[i] < insert_power )				//当找到一个数比我输入的数小时就执行
		{
			for (int j = num_count; j >= i + 1; j--)		//从倒数第二个开始把数字向左挪
			{
				num[j] = num[j - 1];
			 }
			num[i] = insert_power;				//令空出来的那个位置等于输入的数字
			insert_index = i;					//更新下标
			break;								
		}
	}
	num_count++;								//记得增加数组中个数

	for (int i = 0; i < num_count; i++)			//输出
	{
		cout << num[i] << "\t";
	}
	cout << endl;

	
	cout << "请输入你想删除的数字" << endl;
	cin >> del_num;

	for (int i = 0; i < num_count - 1; i++)
	{
		if (num[i] == del_num)
		{
			del_num = i;						//记录所做的下标
			for (int j = i; j < num_count - 1; j++)
			{
				num[j] = num[j + 1];
			}
			del_index = i;
			num_count--;
		}
	}

	if (del_index == -1)
	{
		cout << "没有找到你输入的数字喔~~" << endl;
	}
	else 
	{
		for (int i = 0; i < num_count; i++)			//输出
		{
			cout << num[i] << "\t";
		}
		cout << endl;
	}

二维数组

datatype arrayName[size1][size2]

int num[2][3];
double index[1][2];

string stu_names[] = { "张三","李四","王五" };
	string subject[] = { "C++","CAD","工程力学" };
	const int ROW = 3;
	const int COL = 3;
	double scores[ROW][COL];
	for (int i = 0; i < ROW; i++)		//外层循环控制学生
	{
		for (int j = 0; j < COL; j++)	//内层循环控制课程
		{
			cout << stu_names[i] << "的" << subject[j] << "成绩为" << endl;
			cin >> scores[i][j];
		}
	}

	for (int i = 0; i < COL; i++)
	{
		cout << "\t" << subject[i];
	}
	cout << endl;
	for (int i = 0; i < ROW; i++)
	{
		cout << stu_names[i];
		for (int j = 0; j < COL; j++)
		{
			cout << "\t" << scores[i][j];
		}
		cout << endl;
	}

从而达到输出成一个表格状的结构
在这里插入图片描述

假如在此处无法用cout cin string类型的数据或者数组,可以看我的另一篇文章

C++输入输出string类型.

数组的替代品vector(向量)

vector是容器,是一个模板类,是相当于一个快速的动态分配内存的数组.

①其为动态数组,可以在运行阶段设置长度
②具有数组的快速索引方式
③可以插入和删除元素

之所以说是代替,是因为在C++里不论是一维还是多维都可以用vector来代替数组
并且推荐在C++里使用快捷方便的容器vector
关于vector是否可以完全替代数组可以参考下面链接里大佬的回答
关于vector是否可以完全替代数组.

使用前要添加头文件< vector >
定义和初始化

vector<int> vec1;		//只能存放int类型的数据
vector<int> vec2(3);	//给他3个数据类型的存放空间
vector<int> vec3(4,0);	//给4个int类型 全部赋为0;

其常用操作有

claer()移除容器里的全部数据
empty()判断容器是否为空
size()返回容器中元素的个数
[index]、at(index)返回索引为index的元素
erase(position)删除position位置处的数据(只能用于迭代器)
erase([begin,end])删除[begin,end]区间的数据
front()返回第一个元素
insert(position,element)在position出插入元素element
pop_back()删除最后一个元素
push_back(element)在容器末尾插入一个元素
resize(num)重新设置容器大小
begin()、end()返回容器首、尾元素的迭代器

在使用算法时我们还需要额外引入头文件
< algorithm >

迭代器

迭代器其实是一种指针。
那it的自加自减就是地址的自加自减.
由此我们可以知道在内存分配时,分配的是相邻的地址,并且按照下标顺序进行地址顺序分配

我们这里演示自带的算法排序和输出

	vector<double> vec_double = {	3.0,	1.0,	4.0,	2.0,	5.0 };
	vec_double.push_back(0.0);
	for (unsigned int i = 0; i < vec_double.size(); i++)
	{
		cout << vec_double[i] << "\t";
	}
	cout << endl;

	vector<double>::iterator it;			//启用同一数据类型double的迭代器
	
	sort(vec_double.begin(), vec_double.end());		//进行正序排列
	for (it = vec_double.begin(); it != vec_double.end(); ++it)	
	//此处为vector式输出,it为前置自加
	{
		cout << *it << "\t";
	}
	cout << endl;

	reverse(vec_double.begin(), vec_double.end());	//进行逆序排序
	for (it = vec_double.begin(); it != vec_double.end(); ++it)
	{
		cout << *it << "\t";
	}
	cout << endl;

小知识

vector其实也有默认分配的内存.当我们一直往里面push_back时,最终会超出它的默认分配内存.此时它会运行一下几个操作
①创造一个新的更大内存的vector1
②把vector里的数据分配到vector1
③删除vector

总结

①数组是在内存里分配一块连续的存储结构供我们使用(但是里面的元素要是同一个数据类型)
②数组需要先初始化,才能够使用(初始化就是分出一定量的内存空间,我们可以用变量控制数组的size,但是我们不能用变量初始化数组)
③数组的元素我们使用下标来访问(要自己声明一个index)
④不论是一维数组还是二维数组,都可以使用循环来动态初始化.例如下式

for(int i = 0; i < 5; i ++)
{
	for(int j = 0; j < 4; j++)
		{
			cin >> num[i][j];
		}
}

⑤vector(容器)在安全性和功能性上都比数组要强,但是在编译时会比数组满,是典型的功能复杂强大带来的弊端.

在CSDN学习的时光,是博客和在看的你支持了我~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值