C++基础—— 数组

一、基本数组

1、数组的特点

  • 数组中每个元素数据类型相同。
  • 数组中元素的位置在内存中是连续的。
  • 在很多情况下使用数组的名字,其实使用的是一个指向数组首元素的指针。

2、数组作为函数的形参

(1)、数组有两个性质:不允许拷贝数组,以及使用数组时会将其转换成指针。因为不能拷贝数组,所以无法以值传递的方式使用数组参数。因为数组会被转换成指针,所以当为函数传递一个数组时,实际上传递的是指向数组首元素的指针。

(2)、数组的引用

// arr是一个整型数组的引用,该数组具有10个整数
void f1(int (&arr)[10]);

(3)、指针和数组

// 10个指针构成的数组,数组的元素类型是指针:int *
int *arr1[10];
// 指向含有10个整数的数组的指针。
int (*arr2)[10];

3、一维数组

(1)、一维数组定义方式(如下三种):

// 数据类型  数组名 [ 数组长度 ];
int a[10];

// 用常量来指定数组的大小
int num1;
constexpr int num2;
int a[num1]; //错误,因为 num1 不是常量
int a[num2]; //正确,因为 num2 是常量

// 数据类型  数组名 [ 数组长度 ] = {1,2,3,4};
int b[3] = { 1,2,3 };

// 数据类型  数组名 [] = {1,2,3};
int c[] = { 1,2,3 };

(2)、一维数组名的用途

  • 统计数组所有元素在内存中的长度 —— sizeof (数组名)
  • 获取数组在内存中的首地址(即数组名)
// 获取数组的长度
int len = sizeof(arr)/sizeof(arr[0]) ;

 (3)、C++11 定义了头指针和尾指针的下一个元素的函数:begin,end。如下面的s1数组有4个元素时:

  • begin:返回指向数组的首元素位置的指针变量(int *)
  • end:返回指向数组尾元素的下一个位置的指针变量(int *)

               

auto p = begin(s1);
auto e = end(s1);
auto d=p-e;  //结果为4

 对应的类型如下图所示

4、多维数组

  • 严格来讲,C++中并没有多维数组,通常所说的多维数组其实是数组的数组。

(1)、二维数组定义(缺省的元素用0来表示)

int a1[2][3];
int a2[2][3] = { {1,2,3},{4,5,6} };
int a3[2][3] = { 1,2,3,4,5,6 };
int a4[][3] = { 1,2,3,4,5,6 };

 (2)、使用范围for来进行遍历多维数组时:除了最内层的循环外,其他的所有循环控制变量都应该是引用类型

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	int arr[2][3] = {
		{1,2,3},
		{4,5,6} };

	for (auto &row : arr)  // 除最内层外,其他的控制变量都要用引用的类型
	{
		for (auto col : row)
		{
			cout << col << " ";
		}
		cout << endl;
	}

	cin.get();	
}

因为:如果row不是引用类型,编译器在初始化row时,会自动的将这些数组形式的元素转换成指向该数组内首元素的指针。这样row的类型就是 int * ,这样内层循环就不合法了。


二、数组的遍历

1、将数组作为函数的形参,可以用指针或数组名的形式来进行传递实参

// 以指针的形式,arr为数组的首地址,len为数组元素的个数
void PrintArray(int *arr , int len)

// 数组名的形式,看起来更直观。len为数组元素的个数
void PrintArray(int arr[] , int len)

2、关于数组的长度求解。

(1)、如果在传递数组的时候只传递数组名,此时在接受的函数中用 sizeof 将无法求得数组的元素个数。实验示例如下:

#include<iostream>
#include<string>

using namespace std;

// 只传递数组名,在调用函数中求数组长度
void PrintArray01(int *arr)
{
	int len01 = sizeof(arr) / sizeof(arr[0]);
	cout << "len01 = " << len01 << endl;
	for (int i = 0; i < len01; i++)
	{
		cout << arr[i] << " ";
	}
	cout << "\n---------------------\n";
}

int main()
{
	int a[] = { 5,2,6,8,4,3,7 };
	cout << "PrintArray01打印结果为:\n";
	PrintArray01(a);

	system("pause");
}

运行结果如下:

所以在子函数中用 sizeof(arr) / sizeof(arr[0])  来求数组的元素时结果为1,因为该函数只接受了数组的第一个元素的地址。

参数的传递是将实参的值赋给形参。然而对于数组来说却是一个例外,因为数组的数据太多了,将其一一赋值既麻烦又浪费空间。所以数组作为参数传递给函数时,只传递了数组首元素的地址,函数在需要用到后面元素时再按照这个地址和数组下标去查找。也就是说后面的元素根本没到函数里来,所以在函数里求不出数组的大小也就不足为奇了。

(2)、为解决以上的问题,需要在定义数组的地方,预先用 sizeof(arr) / sizeof(arr[0])  来求得数组的元素个数。再将求得的数组元素个数和数组名一起传递给函数。实例如下

#include<iostream>
#include<string>

using namespace std;

// 在定义数组的地方求得数组的元素个数,再作为实参传递过来
void PrintArray02(int* arr, int len)
{
	cout << "len = " << len << endl;
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << "\n--------------------\n";
}


int main()
{
	int a[] = { 5,2,6,8,4,3,7 };
	int len = sizeof(a) / sizeof(a[0]);  // 预先求得数组元素的个数

	cout << "PrintArray02打印结果为:\n";
	PrintArray02(a, len);

	system("pause");
}

运行结果如下

发布了213 篇原创文章 · 获赞 48 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/Jeffxu_lib/article/details/102692984