本文为个人学习笔记,参考链接:菜鸟教程。请点击链接查看原文,尊重楼主版权。
/*
12.数组
C++数组,可以存储一个固定大小的相同类型元素的顺序集合。
数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,
比如 numbers,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
1/ 声明数组
在 C++ 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
type arrayName [ arraySize ];
这叫做一维数组。arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C++ 数据类型。
例如,要声明一个类型为 double 的包含 10 个元素的数组 balance,声明语句如下:
double balance[10];
现在 balance 是一个可用的数组,可以容纳 10 个类型为 double 的数字。
2/ 初始化数组
在 C++ 中,您可以逐个初始化数组,也可以使用一个初始化语句,如下所示:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。
如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
您将创建一个数组,它与前一个实例中所创建的数组是完全相同的。下面是一个为数组中某个元素赋值的实例:
balance[4] = 50.0;
上述的语句把数组中第五个元素的值赋为 50.0。
所有的数组都是以 0 作为它们第一个元素的索引,也被称为基索引,数组的最后一个索引是数组的总大小减去 1。
3/ 多维数组 同C#差不多,不多说了
//---------------------------------------------------------------------------------------------------------------------------
4/ 指向数组的指针
数组名是一个指向数组中第一个元素的常量指针。因此,在下面的声明中:
double balance[50];
balance 是一个指向 &balance[0] 的指针,即数组 balance 的第一个元素的地址。
因此,下面的程序片段把 p 赋值为 balance 的第一个元素的地址:
double *p;
double balance[10];
p = balance;
使用数组名作为常量指针是合法的,反之亦然。因此,*(balance + 4) 是一种访问 balance[4] 数据的合法方式。
一旦您把第一个元素的地址存储在 p 中,您就可以使用 *p、*(p+1)、*(p+2) 等来访问数组元素。
下面的实例演示了上面讨论到的这些概念:
实例
#include <iostream>
using namespace std;
int main ()
{
// 带有 5 个元素的双精度浮点型数组
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
p = balance;
// 输出数组中每个元素的值
cout << "使用指针的数组值 " << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
cout << "使用 balance 作为地址的数组值 " << endl;
for ( int i = 0; i < 5; i++ )
{
cout << "*(balance + " << i << ") : ";
cout << *(balance + i) << endl;
}
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
使用指针的数组值
*(p + 0) : 1000
*(p + 1) : 2
*(p + 2) : 3.4
*(p + 3) : 17
*(p + 4) : 50
使用 balance 作为地址的数组值
*(balance + 0) : 1000
*(balance + 1) : 2
*(balance + 2) : 3.4
*(balance + 3) : 17
*(balance + 4) : 50
在上面的实例中,p 是一个指向 double 型的指针,这意味着它可以存储一个 double 类型的变量。
一旦我们有了 p 中的地址,*p 将给出存储在 p 中相应地址的值,正如上面实例中所演示的。
---------------
注意:(字符数组)
C++ 中,将 char * 或 char[] 传递给 cout 进行输出,结果会是整个字符串,
如果想要获得字符串的地址(第一个字符的内存地址),可使用以下方法:
强制转化为其他指针(非 char*)。可以是 void *,int *,float *, double * 等。
使用 &s[0] 不能输出 s[0](首字符)的地址。因为 &s[0] 将返回 char*,
对于 char*(char 指针),cout 会将其作为字符串来处理,向下查找字符并输出直到字符结束 。
如:
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
char var[MAX] = {'a', 'b', 'c'};
char *ptr;
// 指针中的数组地址
ptr = var;
for (int i = 0; i < MAX; i++)
{
cout << "Address of var[" << i << "] = ";
cout << (int *)ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 移动到下一个位置
ptr++;
}
return 0;
}
输出结果:
Address of var[0] = 0x7fffd63b79f9
Value of var[0] = a
Address of var[1] = 0x7fffd63b79fa
Value of var[1] = b
Address of var[2] = 0x7fffd63b79fb
Value of var[2] = c
//---------------------------------------------------------------------------------------------------------------------------
5/ 传递数组给函数
C++ 中您可以通过指定不带索引的数组名来传递一个指向数组的指针。
C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。(见下面例二)
如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,
这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,您也可以传递一个多维数组作为形式参数。
-1-形式参数是一个指针:
void myFunction(int *param)
{
}
-2-形式参数是一个已定义大小的数组:
void myFunction(int param[10])
{
}
-3-形式参数是一个未定义大小的数组:
void myFunction(int param[])
{
}
就函数而言,数组的长度是无关紧要的,因为 C++ 不会对形式参数执行边界检查。
所以,函数定义时,形参可以直接写 int arr[],不用写容量大小。
例二 :C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址
#include <iostream>
using namespace std;
// 函数声明
double getAverage(int arr[], int size);
int main ()
{
// 带有 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;
cout << "array size : " << balance_size << endl;
cout << "int pointer size : " << pt1_size << endl;
// 传递一个指向数组的指针作为参数
avg = getAverage( balance, 5 ) ;
// 输出返回值
// cout << "平均值是:" << 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 (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = double(sum) / size;
return avg;
}
运行结果如下:
array size : 5
int pointer size : 8
Inside getAverage sizeof(arr) = 8
可见,数组的元素个数有 5 个。但是函数中传递的其实是一个指向整型的指针,而整型指针占用 8 个字节。
------------------------------------------
6/ 从函数返回数组
C++ 不允许返回一个完整的数组。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。
如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:
int * myFunction()
{
}
另外,C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
现在,让我们来看下面的函数,它会生成 10 个随机数,并使用数组来返回它们,具体如下:
#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;
}
*/