C++学习——数组

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。

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;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容