c++ 【一维数组】的了解

在开始前点个赞和关注!还有收藏!

数组是一种基本的数据结构,用于存储一系列相同类型的元素。从这个定义我们可以看出数组的声明并不是声明一个个单独的变量,比如 student0、student1、…、student99(共100个变量),而是声明一个能保存这些相同类型的变量,比如 students。这个变量可以用students[0]、students[1]、…、students[99] 的形式来代表一个个单独的变量。

数组中的特定元素可以通过索引访问。数组是由连续的内存位置组成的,最低的地址对应第一个元素,最高的地址对应最后一个元素。比如students数组中的第一个元素是students[0],第二个元素是students[1]……,最后一个元素是students[99]。中括号内的数字就是某个元素的索引(index)。

1.数组的声明和初始化
在C++中,声明一个一维数组需要指定数组的类型、名称和大小。语法如下:
type arrayName[arraySize];
type 可以是任意有效的 C++ 数据类型,如int、float等;arrayName符合C++关于标识符定义的规则即可;arraySize 必须是一个大于等于零的整数常量(或变量)。例如,要声明一个类型为 int的包含 100个元素的数组 students,声明语句如下:
int students[100];
现在 students就 是一个可用的数组,可以容纳 100 个int 类型的数字。这里要特别注意,arraySize部分的值可以为0,也可以是变量(但是我们不建议这么做)。比如下面的定义都是合法(但不推荐)的:

int n = 100;
int array1[0];
int array2[n];

推荐的做法是结合宏定义来声明全局数组(在函数外定义的数组称为全局数组),如下所示:

#include
using namespace std;
#define N 100
int students[N];

int	main() 
{
	
	return 0;
}

2.初始化数组
C++语言中,全局数组每个元素都会被自动初始化为数字0(无论任何类型)。而非全局数组(在函数内定义的数组)的每个元素,如果未被初始化或赋值则为随机值
(1)完全初始化所有元素。例如:
int myArray[5] = {1, 2, 3, 4, 5};

(2)部分初始化
int myArray[5] = {1, 2};
这里只有前两个数组元素被指定的值初始化,而其余(后三个)元素会被初始化为0。

(3)省略数组大小
int myArray[] = {1, 2, 3, 4, 5};
编译器会根据初始化列表的大小确定数组大小。相当于:int myArray[5] = {1, 2, 3, 4, 5};

3.访问数组元素
数组元素即为普通的变量。数组元素的使用与变量的使用一样。例如:
(1)对数组元素赋值
myArray[0] = 1;
(2)参与表达式计算
myArray[1] = myArray[0] *100;
(3)直接输出
printf(“%d”,myArray[0] );
cout<

4.数组的常见操作
(1)遍历数组:
int myArray[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++)
{
cout << myArray[i] << endl;
}
这里是每个元素独占一行。如果想在一行显示所有元素,中间用空格分割,可以用下面的代码实现:

#include
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	cout<

(2)查找某个值是否存在。如果存在多个相同的值则返回第一次出现的位置。如果要查找的值不存在,则返回-1。参考代码如下:

#include
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int m;//要查找的值
	int p = -1;//假设要查找的值不存在
	
	cin>>m;
	for (int i = 0; i < 5; i++)
	{
		if(myArray[i]==m)
		{
			p = i;
			break;
		}
	}
	cout<

如果存在多个相同的值,要返回最后一次出现的位置该怎么办呢?我们可以从后往前来遍历数组,这样找第一次找到的位置就是正序的最后一次出现的位置。参考代码如下:

#include
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int m;//要查找的值
	int p = -1;//假设要查找的值不存在
	
	cin>>m;
	for (int i = 4; i >=0 ; i--)
	{
		if(myArray[i]==m)
		{
			p = i;
			break;
		}
	}
	cout<

(3)查找最大/小值
在数组中查找最大值,并返回最大值所在的位置。参考代码如下:

#include
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int max = INT_MIN;//保存最大值。初始化为最小值
	int p = -1;//最大值所在的位置
	
	for (int i = 0; i <5 ; i++)
	{
		if(myArray[i]>max)
		{
			max = myArray[i];
			p = i;
		}
	}
	cout<
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int max;//保存最大值
	int p;//最大值所在的位置
	
	max = myArray[0];
	p = 0;
	for (int i = 1; i <5 ; i++)
	{
		if(myArray[i]>max)
		{
			max = myArray[i];
			p = i;
		}
	}
	cout<max条件是不成立的,所以无法记录第二个最大值的位置。那么想返回最后一个最大值的位置该如何处理呢?答案是,只要把if语句中的大于号改成大于等于即可。
上面的代码其实还可以进一步优化,就是不使用max变量,只记录最大值的位置即可。比如:
#include
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int pmax;//最大值所在的位置

	pmax = 0;
	for (int i = 1; i <5 ; i++)
	{
		if(myArray[i]>myArray[pmax])
		{
			pmax = i;
		}
	}
	cout<
using namespace std;
#define N 5
int myArray[5] = {1, 2, 3, 4, 5};
int	main() 
{
	int pmin;//最小值所在的位置

	pmin = 0;
	for (int i = 1; i <5 ; i++)
	{
		if(myArray[i]

(4)插入一个元素。
前面已经讲过数组中的所有元素都是连续存放的。那么要在数组中插入一个元素,就得先给这个元素“腾”出一个位置来。那又该如何“腾”出这个位置呢?答案就是:最后一个元素向后移动一个位置,倒数第二个元素“挪”到原来倒数第一个元素所在的位置,倒数第三个元素“挪”到原来倒数第二个数据所在的位置,以此类推,直到把要插入数据的位置空出来为止。假设我要在第p个位置,插入一个新的元素m。参考代码如下:

#include
using namespace std;
#define N 10
int myArray[N] = {0,1, 2, 3, 4, 5,6,7};
int	main() 
{
	int n = 8;//数组中元素的个数
	int p;//要插入的位置,在这个位置之后插入数据
	int m;//要插入的数据
	cin>>p>>m;
	
	//把位置p+1到n-1的数据向后移动一个位置。
	for(int i = n-1;i>=p+1;i--)
	{
		myArray[i+1] = myArray[i];
	}
	
	//把新的数据插入的指定位置之后
	myArray[p+1] = m;
	
	//数组的元素个数增加1
	n++;
	
	cout<

(5)删除一个元素
与插入数据正好相反,删除数据是不断地往前“挪”。从要删除的位置后第一个数据开始往前“挪”,直到最后一个元素为止。其实,数据不是被删除的,而是被后面的数据覆盖掉的。参考代码如下:

#include
using namespace std;
#define N 10
int myArray[N] = {0,1, 2, 3, 4, 5,6,7};
int	main() 
{
	int n = 8;//数组中元素的个数
	int p;//要删除的位置

	cin>>p;
	
	//把位置p+1到n-1的数据向前移动一个位置。
	for(int i = p;i

注意:当数组中数据元素很多的时候,这种移动操作是非常消耗资源的。因此有的时候,会把要删除的数据用一个不存在的值去代替。比如数组中的元素都是正整数,要删除的数据直接改为-1,这样通过减少移动数据来提高算法效率。

(4)数组排序
经典的排序算法有很多种,这里我们介绍一种最简单的排序算法——冒泡排序(Bubble Sort)。冒泡排序算法要重复地遍历要排序的数组。我们默认进行升序排序。那么第一次遍历数组时,首先第一个元素和第二个元素比较,如果不满足升序规则(即第一个元素小于第二个元素),则交换这两个元素的值。如果满足则什么都不做;然后按照上述规则,比较第二个元素和第三个元素的大小……直到比较数组的最后两个元素。遍历一次数组我们称为一趟排序。当完成第一趟排序时,数组中的最大的元素就会被排到数组的最后。换句话说,冒泡排序算法进行一趟排序就会把一个值移动到正确的位置上。那么第二趟排序的时候就可以不考虑最后这个元素,这就相当于减小了数组的规模。第一趟排序在n个数中排序,第二趟排序的时候在前n-1个元素中排序……直到数组中剩下两个元素,再做一趟排序,那么整个数组的排序工作就完成了。我们用数据来演示一下,比如原来数组中的数据是 4 3 5 2 1,那么第一趟排序时,首先4和3比较,4大于3不满足升序规则,4和3交换位置,数据的数据变为:3 4 5 2 1;然后4和5比较,满足升序规则什么都不做;5和2比较,不满足升序规则,交换顺序,数组元素变为:3 4 2 5 1;然后5和1比较,继续交换,数组元素变为:3 4 2 1 5。这时候,数组中最大的元素5已经在正确的位置上了。下一趟排序时,就不需要再考虑这个元素。
通过上面的分析我们看到,如果数组中有n个元素,那么冒泡排序第一趟排序需要比较n-1次,第二趟需要比较n-2次,……..,直到剩下两个元素,比较1次。那么一共比较了多少次呢?1+2+3+…..+(n-1) =n*(n-1)/2次。当数据多时,效率很低。数据少时可以用。参考代码如下:

#include
using namespace std;
#define N 10
int myArray[N] = {7,6, 5, 4, 3, 2,1,0};
int	main() 
{
	int n = 8;//数组中元素的个数

	for(int i=0;imyArray[j+1])//不符合升序规则,交换数据
			{
				int t= myArray[j];
				myArray[j] = myArray[j+1];
				myArray[j+1] = t;
			}
			
	}
	
	cout<
using namespace std;
#define N 10
int myArray[N] = {0,1, 2, 3, 4, 5, 6, 7};
int	main() 
{
	int n = 8;//数组中元素的个数

	for(int i=0;imyArray[j+1])//不符合升序规则,交换数据
			{
				flag = false;//如果交换发生则修改有序标记
				int t= myArray[j];
				myArray[j] = myArray[j+1];
				myArray[j+1] = t;
			}
			
		if(flag)//如果没有交换发生,则提前退出排序算法
			break;
			
	}
	
	cout<

(5)计算数组的大小
可以使用 ​sizeof​运算符来获取数组的大小。注意,​sizeof​返回的是数组占用的总字节数,因此需要除以单个元素的字节数来得到元素的个数。参考代码如下:

int myArray[5] = {1, 2, 3, 4, 5};
int size = sizeof(myArray) / sizeof(myArray[0]);
cout << “Array size: ” << size; // 输出5

(6)动态分配一维数组
有的时候需要在程序运行时根据需要来确定数组的大小。可以使用new运算符或者malloc()函数来实现:

#include 
using namespace std;

int main()
{
	int size;
	cin >> size;
	int *array = new int[size]; // 动态分配一个大小为 ​size​的整型数组,
					//并返回一个指向该数组的指针。

	// 初始化数组
	for (int i = 0; i < size; ++i)
	{
		array[i] = i * 10;
	}

	delete[] array;	// 释放动态分配的内存,确保没有内存泄漏。
	return 0;
}
也可以:
#include 
using namespace std;

int main()
{
	int size;
	cin >> size;
	int *array = (int *)malloc(size * sizeof(int)); // 动态分配一维数组

	// 检查内存是否成功分配
	if (array == nullptr)
	{
		cerr << "Memory allocation failed!" << endl;
		return 1;
	}
	// 初始化数组
	for (int i = 0; i < size; ++i)
	{
		array[i] = i * 10;
	}

	free(array);	// 释放动态分配的内存
	return 0;
}

6.注意事项
(1)C++不会检测数组越界的情况。因此代码如果访问或修改超出数组范围的元素会导致未定义行为,可能会导致程序崩溃或产生不可预测的结果。
(2)C++中的数组大小在编译时确定,不能动态改变。因此在声明数组时,要一次申请够用(当然也不要查过实际需求过多)。如果需要动态大小的数组,可以考虑使用 STL中的数据结构:vector​。

本节课练习:
一维数组

你可能感兴趣的:(c++,算法,数据结构)