C++抽象编程——数组(2)——数组与指针

有效大小与分配大小

虽然sizeof技术允许你确定静态分配的数组的大小,但是有许多应用程序在编写代码时无法知道数组应该有多大,因为实际的元素数量取决于用户的数据。解决选择适当数组大小的问题的一个策略是声明一个你知道的数组大于你需要的数组,然后只使用它的一部分。因此,不是声明数组以使其保存实际数量的元素,而是定义一个常量,指示最大数量的元素,并在该数组的声明中使用该常量。在任何给定使用的程序中,实际数量的元素小于或等于此常量。当你使用此策略时,需要维护一个单独的整数变量来跟踪实际使用的值的数量。声明中指定的数组的大小称为分配的大小(allocated size),主动使用的元件数称为有效大小(effective size)。
例如,假设你想定义一个数组,其中包含体操中的竞争对手的分数,裁判可以以数字的形式对每个参赛者进行评分(从0.0到10.0)。如果你希望程序允许最多100名法官,即使实际的数字通常较小,可以声明该数组:

const int MAX_JUDGES = 100;
double scores[MAX_JUDGES];

为了跟踪有效大小,你需要声明一个额外的变量,例如可以调用nJudges,确保它跟踪实际有多少法官。

数组与指针

在C ++中,数组的名称与指向其初始元素的指针是同义的。 举个例子,声明:

int list[5];

为五个整数的数组分配空间.该数组在当前栈中分配存储空间,如下图所示

名称list表示一个数组,但也可以用作指针值。当它用作指针时,列表被定义为数组中初始元素的地址。因此,如果编译器自身遇到变量名称list,而且在其后面没有任何下标,它会将数组名称转换为数组在内存中开始的指针值。
C ++将数组视为指针的最重要的含义之一是数组参数与调用参数共享,即使没有涉及引用的显式调用。 例如,可以按如下方式实现基于数组的版本的选择排序算法的:

void sort(int array[], int n) {
    for (int lh = 0; lh < n; lh++) {
    int rh = lh;
    for (int i = lh + 1; i < n; i++) {
        if (array[i] < array[rh]) rh = i;
    }
    swap(array[lh], array[rh]);
    }
}

该函数正确排序调用者传递的数组,因为函数通过复制调用参数的地址初始化数组参数。 该函数然后使用该地址从数组中选择元素,这意味着元素是调用参数中的元素.(也就是说,函数的第一个参数是数组的第一个地址,其他的元素按照下标来选取作为参数
上面函数的原型,工作方式与此完全相同:

void sort(int *array, int n);

在这种情况下,第一个参数被声明为一个指针,但效果与上面的实现中的相同。在任一情况下,存储在名称array下的栈框架中的值都是调用参数的初始元素的地址。在机器内部,两种声明是等效的。 无论你在声明中使用哪种形式,都可以对变量array应用相同的操作。
一般的规则,我们应该以反映其用途的方式声明参数。如果你打算使用参数作为数组并从中选择元素,则应将该参数声明为数组。 如果打算使用该参数作为指针并取消引用,则应将其声明为指针。
当变量最初被声明时,C ++中的数组和指针之间的关键区别就起作用了,而不是在当这些值作为参数传递时。根本区别:声明:

int array[5];

以及声明:

int *p;

都是是内存分配之一。第一个声明保留了连续存储数组元素的五个连续的存储单元。第二个声明只保留一个word,足够大以容纳机器地址。记住这个区别的含义对于你来说是很重要的。如果你声明一个数组,你可以使用存储地址; 如果你声明一个指针变量,那么该变量在初始化之前不与任何内存相关联。
初始化指向数组的指针的最简单方法是将现有数组的基址复制到指针变量中。 举个例子,如果你要
声明:

p = array;

在进行上述声明之后,指针变量p将指向与数组相同的地址,可以互换使用两个名称。

设置指向现有数组的地址的指针的技术是相当有限的。毕竟,如果你已经有一个数组名,你就可以直接使用它。将该名称分配给一个指针并不是真的没有任何好处。使用指针作为数组地址的真正优点在于你可以将该指针初始化为以前未分配的新内存,这样可以在程序运行时创建新的数组。以后的动态分配中再说。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值