繁体   English   中英

C ++数组指针

[英]C++ array pointer

我遇到了像这样的C ++程序

#include<iostream>
using namespace std;

int main() {
    int N = 10;
    int M = 2;
    int a[] = { 2,1,4,3,6,5,8,7,10,9 };
    int(*b)[5] = (int(*)[5]) a;
    for (int i = 0; i<M; i++) {
        for (int j = 0; j<N / M; j++) {
            cout << b[i][j] << endl;
        }
    }

    system("pause");
    return 0;
}

上述计划的产出为2,1,4,3,6,5,8,7,10,9 看起来b是一个数组点。 那么(int(*)[5]) a是什么意思? 有人可以帮我解释一下吗?

a是一个包含10个元素的int数组: int [10] b是一个指向具有5个元素的int数组的指针: int (*) [5] b被初始化为值a ,并使用C样式转换明确地浇铸: (int(*)[5]) a

有效地a是1×10矩阵并且b是2×5矩阵,实际上它是具有相同内容的ab的“重塑”。 这里“最”危险的是重塑不执行深层复制,即b变化也会影响a ,反之亦然;

类型,这里是int ,完全不相关。 是一个在线示例,有几种不同的类型。

这里, a[]是10个整数的数组。 b是指向5个元素的数组的指针。

int(*b)[5] = (int(*)[5]) a;

在上面的语句中,数组a[]的地址被类型化为指向5个元素的数组的指针。 然后, b作为二维阵列被访问。

该声明

int a[] = { 2,1,4,3,6,5,8,7,10,9 };

在内存中看起来像这样

     +---+---+---+---+---+---+---+---+---+---+
a -> | 2 | 1 | 4 | 3 | 6 | 5 | 8 | 7 | 10| 9 |;
     +---+---+---+---+---+---+---+---+---+---+
      +0  +1 ...  

当您访问数组中的元素时,通常使用[]但是因为a是地址。 您也可以使用指针样式偏移来访问元素

a + 2   // address to third int, *(a+2) the actual value `3`

现在,通过声明另一种方式来访问10个整数,您可以访问的内存a以不同的方式,类型决定您访问内存的方式

int(*b)[5] = (int(*)[5]) a; // compiler, pretend a is of same type

在上面的语句ba引用相同的内存但b是指向int数组的类型指针。

因为b是一个指针:

b指向a开始的地方。 b++ ,B现在指向的中间a阵列,因为B的声明中说,它认为只有五个整数

所以

b[0] points to address a + 0
b[0][0] is the value of a + 0 or a[0] alt. *(a + 0)

b[1] points to address a + 5 
b[1][0] is the value of a + 5 or a[5] alt. *(a + 5)

由于C通常没有检查你是否超出了上述范围。

由于b是指向5个整数数组的指针,因此:

  • b[0]将指向由b指向的位置存储的5个整数的数组。
  • b[1]将指向由b + (5*sizeof(int))指向的位置存储的5个整数的数组。

由于b已经分配了a通过类型转换的地址int(*b)[5] = (int(*)[5]) a; 因此:

  • b[0]将指向数组a前5个整数,即a[0..4]
  • b[1]将指向数组a下一个5个整数,即a[5..9]

现在,

  • b[0][0]将给出由b[0]指向的数组的0索引的第一个元素的值,a[0]
  • b[0][1]将给出由b[0]指向的数组1索引的第二个元素的值,a[1]

..

..

  • b[1][0]将给出由b[1]指向的数组的0索引的第一个元素的值,a[5]
  • b[1][1]将给出由b[1]指向的数组1索引的第二个元素的值,a[6]

Int-array a被显式初始化为包含10个元素。 变量a的内部表示是指向第一个元素的指针。 写一个[3]是“给我一个偏移量为3的内容”。

然后将变量b创建为指针数组(长度5)到int(它不是“点”,而是“指针”,顺便说一句)。 b用a的内容初始化,但由于a是不同的类型,因此必须对正确的类型(即b的类型)进行类型转换。 类型转换基本上意味着“假装变量a的内存属于不同类型”。 这是用c风格演员完成的

(int(*)[5]) a

总而言之,我不会努力复制这种编码风格。

此外,以下代码仅在指向int的指针是int的两倍大小时才有效,例如64位指针,32位int。 脏的,脏的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM