所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
1.声明数组
在 C++ 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
type arrayName [ arraySize ];
这叫做一维数组。arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C++ 数据类型。
例如:double balance[10];
2.初始化数组
初始化总共分为一下几种方式:
2.1 定义数目,{}初始化
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。
2.2 不定义数目,{}初始化
数组的大小则为初始化时元素的个数,省略掉了数组的大小。
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
2.3 为数组中某个元素赋值
balance[4] = 50.0;
仅为第5个元素赋值,其他元素不变。
- 注意:所有数组都是以0作为他们的第一个元素的索引。
3.访问数组
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。
double salary = balance[9];
4.多维数组
C++ 支持多维数组。多维数组声明的一般形式如下。
type name[size1][size2]...[sizeN];
示例:创建一个三维数组
int threedim[5][10][4];
4.1 二维数组
多维数组最简单的形式是二维数组。一个二维数组,在本质上,是一个一维数组的列表。声明一个 x 行 y 列的二维整型数组,形式如下
type arrayName [ x ][ y ];
一个二维数组可以被认为是一个带有 x 行和 y 列的表格。下面是一个二维数组,包含 3 行和 4 列:
4.2 初始化二维数组
- 方法一:多维数组可以通过在括号内为每行指定值来进行初始化
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 /
{4, 5, 6, 7} , / 初始化索引号为 1 的行 /
{8, 9, 10, 11} / 初始化索引号为 2 的行 */
};
- 方法二:直接按行初始化
(与上面等效)
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
5.C++指向数组的指针
数组名是指向数组中第一个元素的常量指针。因此,在下面的声明中:
double runoobAarray[50];
runoobAarray 是一个指向 &runoobAarray[0] 的指针,即数组 runoobAarray 的第一个元素的地址。因此,下面的程序片段把 p 赋值为 runoobAarray 的第一个元素的地址:
double *p;
double runoobAarray[10];
p = runoobAarray;
使用数组名作为常量指针是合法的,反之亦然。因此,*(runoobAarray + 4) 是一种访问 runoobAarray[4] 数据的合法方式。
一旦您把第一个元素的地址存储在 p 中,您就可以使用 p、(p+1)、*(p+2) 等来访问数组元素。下面的实例演示了上面讨论到的这些概念:
C/C++ 对 char 型数组做了特殊规定,直接输出首地址时,会输出数组内容。如果想得到地址,可采用 & 。
示例1
char name[] = {"Zara Ali"};
cout << name << endl; // 输出 Zara Ali
cout << &name << endl; // 输出 0x7ffe08e50977
示例2
char name[] = "Zara Ali";
cout << name << endl; // char[],输出整个字符数组的描述(就是字符串)
cout << &name << endl; // char[],输出数组的地址(就是首字符的地址)
cout << (void *)&name[1] << endl;//由于&name[1]的类型是char*,直接输出会是字符串,所以需要强转成其他类型才能输出地址
printf("name:%s name:%p &name:%p &name[1]:%p\n",name,name,&name,&name[1]);//print可以指定输出样式,所以没有上面cout的问题
int bbb[] = {1,2,3,4};
cout << bbb << endl;//int[],输出整个数组的描述(数组变量的地址代表整个变量的描述)
cout << &bbb << endl;//int[],输出数组的地址(就是首元素的地址)
cout << &bbb[1]<< endl;//&bbb[1] 输出下标为1的元素的地址(就是输出一个int *的指针变量的值)
6.传递数组给函数
C++ 中您可以通过指定不带索引的数组名来传递一个指向数组的指针。
C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。
如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,您也可以传递一个多维数组作为形式参数。
-
方式 1
形式参数是一个指针:void myFunction(int *param) { . . . }
-
方式 2
形式参数是一个已定义大小的数组:void myFunction(int param[10]) { . . . }
-
方式 3
形式参数是一个未定义大小的数组:void myFunction(int param[]) { . . . }
#include <iostream>
using namespace std;
double getAverage(int *arr, int size); //形式参数是一个指针:
double getAverage(int arr[5]); // 重载函数,形式参数是一个已定义大小的数组:
double getAverage2(int arr[]); // 不可重载,形式参数是一个未定义大小的数组:
int main(int argc, char const *argv[])
{
// 带有 5 个元素的整型数组
int balance[5] = {1000, 2, 3, 17, 50};
int *pt1 = balance;
// 分别计算数组元素个数,以及整型指针的字节数
size_t balance_size = sizeof(balance) / sizeof(int);
size_t pt1_size = sizeof(pt1);
double avg, avg2, avg3;
cout << "array size : " << balance_size << endl;
cout << "pt1_size : " << pt1_size << endl;
avg = getAverage(balance, 5);
avg2 = getAverage(balance);
avg3 = getAverage2(balance);
// 输出返回值
cout << "方法1平均值是:" << avg << endl;
cout << "方法2平均值是:" << avg << endl;
cout << "方法3平均值是:" << avg << endl;
return 0;
}
double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
double getAverage(int arr[5])
{
int i, sum = 0, size = 5;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
double getAverage2(int arr[])
{
int i, sum = 0, size = 5;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
arr 是一个指针,即为地址,指针占几个字节跟语言无关,而是跟系统的寻址能力有关。
例如:以前是 16 位地址,指针即为 2 个字节,现在一般是 32 位系统,所以是 4 个字节,以后 64 位,则就占 8 个字节。
7.从函数返回数组
C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。
如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:
int * myFunction()
{
.
.
.
}
另外,C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// 要生成和返回随机数的函数
int * getRandom( )
{
static int r[10];
// 设置种子
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// 要调用上面定义函数的主函数
int main ()
{
// 一个指向整数的指针
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}