float arrayName [] []和float(* arrayNamePointer)[]之间的区别是什么

时间:2015-04-05 16:13:15

标签: c arrays pointers multidimensional-array

下面发生了什么?

以下是C Primer Plus的摘录:

const float rain[YEARS][MONTHS] =
    {
        { 4.3, 4.3, 4.3, 3.0, 2.0, 1.2, 0.2, 0.2, 0.4, 2.4, 3.5, 6.6 },
        { 8.5, 8.2, 1.2, 1.6, 2.4, 0.0, 5.2, 0.9, 0.3, 0.9, 1.4, 7.3 },
        { 9.1, 8.5, 6.7, 4.3, 2.1, 0.8, 0.2, 0.2, 1.1, 2.3, 6.1, 8.4 },
        { 7.2, 9.9, 8.4, 3.3, 1.2, 0.8, 0.4, 0.0, 0.6, 1.7, 4.3, 6.2 },
        { 7.6, 5.6, 3.8, 2.8, 3.8, 0.2, 0.0, 0.0, 0.0, 1.3, 2.6, 5.2 }
    };

    int year, month;
    float subtot, total;

    printf(" YEAR RAINFALL (inches)\n");

    for (year = 0, total = 0; year < YEARS; year++)
    {
        // for each year, sum rainfall for each month
        for (month = 0, subtot = 0; month < MONTHS; month++)
        {
            subtot += rain[year][month];
        }

        printf("%5d %15.1f\n", 2010 + year, subtot);
        total += subtot; // total for all years
    }

我不得不改变它以使用指针而不是数组下标。

所以我选择了:

[....]

float (* rainPointer)[2];
rainPointer = rain;

[....]

subtot += *(*(rainPointer + year) + month);

这适用于第0年。年份正确递增,月份正确重置。然而,第1年并没有指出我期望的地方。我已经完成了这一百万次,我并排运行它们,rainPointer总是(对我来说)似乎是正确的,年和月总是正确的。

我通过谷歌找到答案,我应该使用:

subtot += *(*(rain + year) + month);

雨与雨之间有什么不同?如果它们都指向两个整数数组的开头,它们为什么不相同?

有些事情发生了,我显然不知道,或完全失踪。

1 个答案:

答案 0 :(得分:1)

rain是一个二维数组,声明为

const float rain[YEARS][MONTHS];

在表达式中,数组的名称将转换为指向数组第一个元素的指针。例如,如果你有一个数组

T rain[YEARS];

然后在表达式rain中转换为T *

类型的指针

实际上,二维数组是一维数组元素,其中依次是一维数组。

因此声明

const float rain[YEARS][MONTHS];

可以写成

typedef float T[MONTHS];
const T rain[YEARS];

其中T的类型为float [MONTHS}

因此,当rain被转换为指向其第一行的第一个元素的指针时,由于指针算术表达式rain + year是指向一维数组的指针(行) )对应于今年。

Expression *(rain + year)产生的这个数组就是这一行。

所以*(下雨+年)是一行是一维数组。数组再次转换为指向其第一个元素的指针。元素的类型是const float因此,表达式*(rain + year) + month是指向此一维数组(行)中与给定月份对应的元素的指针。

最后,表达式*(*(rain + year) + month)会产生该行的这个元素。

因此,使用表达式rain + year迭代行。使用表达式*(rain + year) + month,您可以遍历给定行的元素

如果你想仅使用指针重写循环,那么它们看起来像

const float ( *rain_ptr )[MONTHS];
const float *month_ptr;
float total = 0.0f;

for ( rain_ptr = rain; rain_ptr != rain + YEARS; ++rain_ptr )
{
    // for each year, sum rainfall for each month
    float subtot = 0.0f;
    for ( month_ptr = *rain_ptr; month_ptr != *rain_ptr + MONTHS; ++month_ptr )
    {
        subtot += *month_ptr;
    }

    printf("%5d %15.1f\n", 2010 + rain_ptr - rain, subtot);
    total += subtot; // total for all years
}

当然,如果编译器允许,则不需要在循环之前声明指针。最好在循环语句中声明它们。