数组的存储与初始化、对象数组、数组作为函数参数

数组的存储

数组在内存中是一组连续的内存单元,也就是说数组元素是连续存储的。数组名是数组所占内存的首地址。

一维数组是按照下标的顺序存储的,而对多维数组就复杂些,以一定的约定顺序将多维数组存储在连续的内存单元中很重要。因为要对数组赋初值、函数间的数组数据传递等都需要先知道数组元素和存储位置的对应关系。

一维数组的元素是按照下标从小到大的顺序存在内存中的,例如,int a[3]在内存中的存储顺序是:a[0] a[1] a[2]。

对于二维数组元素,第一个下标叫做行标,第二个下标叫做列标。例如,数组int a[2][3]相当于一个两行三列的矩阵:

a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]

上面的a[0][0],行标为0,列标也为0,表示矩阵第一行第一个元素,a[1][2],行标为1,列标为2,表示矩阵第二行第三个元素。二维数组在内存中是按行存储的,也就是先存第一行,再存第二行…。

每行中的元素按照列标从小到大的顺序存储。这种存储方式叫做行优先存储。上面例子中的二维数组a在内存中的存储顺序是:a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]。

对于多维数组,其存储方式与二维数组类似。可以把多维数组的下标看作一个计数器。

多维数组右边的下标为低位,左边的为高位,每一位都在各自的上界与下界之间变化。当某一位超过上界则向左进一位,该位及右边各位就恢复为下界。最右边一维的下标变化最快,最左边的变化最慢。

再提醒大家注意,下界都是0,某一维的上界是声明时该维的下标表达式值减1。

例如,数组int a[2][2][2]在内存中的存储顺序是:a[0][0][0] a[0][0][1] a[0][1][0] a[0][1][1] a[1][0][0] a[1][0][1] a[1][1][0] a[1][1][1]。

实际上我们在软件开发时三维及三维以上的数组很少用到,用的最多的是一维数组。

数组的初始化

在我们声明数组时对部分或全部元素赋值就是数组的初始化。这里分开给大家讲简单数组类型的数组和对象数组,简单数组类型数组的初始化就是给数组元素赋初值,而对象数组的每个元素都是某个类的对象,它的初始化就是调用对象的构造函数。对象数组下面单独讲。

我们可以在声明数组时就给出每个元素的初值,例如:int a[2] = { 2,3 };这条语句声明了一个有2个元素的int类型的数组,a[0]的初值是2,a[1]的初值是3。

如果我们在声明数组时每个元素都给出初始值的话,就可以不说明元素个数,例如:int a[] = { 2,3 };和上面的那个数组声明语句等价。

我们也可以只对数组的前面一部分元素赋初值,例如,int a[3] = { 1,2 };这时数组元素的个数就必须给出,经过这样声明后,a[0]为1,a[1]为2,a[3]默认为0,也就是后面没有赋初值的元素默认为0。

多维数组的初始化也满足上面讲到的规则。另外,如果我们对数组初始化时给出了全部元素的初值,则第一位的元素个数可以不用显式说明,例如:int a[2][2] = { 1,2,1,2 };等价于int a[][2] = { 1,2,1,2 };

多维数组还可以按照第一维的下标分组,用括号把每一组括起来。二维数组的话可以用大括号将每组括起来,例如:int a[2][2] = { {1,2},{1,2}};与上面的语句等价,通过将每组元素括起来我们更能直观的分开每行数据。

对象数组

当数组的元素是某个类的对象时此数组就是对象数组。声明一维对象数组的形式为:类名 数组名[下标表达式];

跟前面说过的基本数据类型的数组一样,使用对象数组也只能引用单个的数组元素,而每个数组元素都是对象,利用这个对象又可以引用它的公有成员,引用形式为:数组名[下标].成员名

对象数组在初始化时每个对象元素都会调用其构造函数。如果初始化时数组元素显式给出初始值就会调用带形参的构造函数,如果没有显式指定初始值则调用默认构造函数。

例如,A b[2] = { A(2,3) };会先调用带形参的构造函数初始化b[0],再调用默认构造函数初始化b[1]。

数组作为函数参数

函数的参数可以是数组元素也可以是数组名。数组元素作为函数参数时跟同类型的变量作函数参数效果一样。

数组名作为函数参数时,实参和形参都须是数组名,并且数组类型要一样。此时传递的是数组的首地址,也就是说形参数组的首地址跟实参是一样的,后面的元素根据其在内存中的顺序进行对应,对应的元素的内存地址相同,所以实参数组的元素个数应该等于或多于形参数组的元素个数。

如果在函数内对数组元素值改变,则主调函数中实参数组的相应元素也会改变。

给大家一个数组作为函数参数的例子:主函数中初始化一个矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。

#include <iostream>
using namespace std;
void RowSum(int A[][4], int nrow)
{
    int sum;
    for (int i = 0; i < nrow; i++)
    {
        sum = 0;
        for(int j = 0; j < 4; j++)
        sum += A[i][j];
        cout << "Sum of row " << i << " is " << sum << endl;
        A[i][0]=sum;
    }
}
int main()
{
    int Table[3][4] = {{1,2,3,4},{2,3,4,5},{3,4,5,6}};
    
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        cout << Table[i][j] << "   ";
        cout << endl;
    }
    RowSum(Table,3);
    for (int i = 0; i < 3; i++)
    cout << Table[i][0] << endl;
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光开朗男孩

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值