[英]Help with Pointer Arithmetic
I've been studying C++ for a test and I am currently stuck with pointer arithmetic. 我一直在研究C ++进行测试,目前我仍然坚持使用指针算法。
The basic problem is the following: 基本问题如下:
int numColumns = 3;
int numRows = 4;
int a[numRows][numColumns];
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;
a[1][0] = 4;
a[1][1] = 5;
a[1][2] = 6;
a[2][0] = 7;
a[2][1] = 8;
a[2][2] = 9;
a[3][0] = 10;
a[3][1] = 11;
a[3][2] = 12;
for (int i=numColumns-1; i>-1;i--)
{
cout << a[numRows-1][i] << endl;
}
A very simple program which prints the lower "row of the matrix". 一个非常简单的程序,它打印下面的“矩阵行”。 ie 12,11,10. 即12,11,10。
Now I am trying to do the equivalent with a int*. 现在我试图用int *做等效的。
What I have been told by my classmates is to think it like this: 我的同学告诉我的是这样想:
array[i][j] == p[numColumns*i+j]
If that is correct, shouldn't the following be equivalent to what I'm looking for: 如果这是正确的,那么以下内容不应该等同于我正在寻找的内容:
int* p = reinterpret_cast<int*> a;
for (int i=numColumns-1; i>-1;i--)
{
cout << p[numColumns*(numRows-1)+i] << endl;
}
Thanks. 谢谢。
int array[3][5]
is NOT an abstraction (in the C++ language) for int array[3*5]
. int array[3][5]
不是int array[3*5]
的抽象(在C ++语言中)。 The standard says that a 2 dimensional array (and N-dimensional arrays in general) are arrays of arrays. 标准说二维数组(和一般的N维数组)是数组的数组。 That array[3][5]
is an array of three elements, where each element is an array containing 5 elements (integers in this case). 该array[3][5]
是一个由三个元素组成的数组,其中每个元素是一个包含5个元素的数组(在本例中为整数)。 C++'s type system does make that distinction. C ++的类型系统确实做出了这种区分。
According to the C++ standard, and array T array[N]
is a contiguous block of memory containing the N elements of type T. So that means that a multidimensional array, let's say int array[3][5] will be a continuous block of memory containing 3 int[5]
arrays, and each int[5]
array is a contiguous block of 5 ints
. 根据C ++标准,数组T array[N]
是一个连续的内存块,包含类型为T的N个元素。这意味着一个多维数组,假设int array [3] [5]将是一个连续的块包含3个int[5]
数组的内存,每个int[5]
数组是5个ints
的连续块。
On my machine, the memory ends up laid out exactly as you would expect - identical to int array[3*5]
. 在我的机器上,内存最终完全按照您的预期布局 - 与int array[3*5]
。 The way the memory is treated is different however, due to the type system (which distinguishes between int[]
and int[][]
). 然而,由于类型系统(区分int[]
和int[][]
),处理内存的方式不同。 This is why you need to use a reinterpret_cast
which essentially tells your compiler "take this memory and without doing any conversion, treat it like this new type". 这就是为什么你需要使用reinterpret_cast
,它实质上告诉你的编译器“占用这个内存而不进行任何转换,把它当成这种新类型”。
I'm not completely sure if this memory layout is guaranteed however. 我不完全确定这种内存布局是否有保证。 I couldn't find anything in the standard stating that arrays can't be padded. 我无法在标准中找到任何表明数组无法填充的内容。 If they can be padded (again, I'm not sure) then it's possible that the int[5]
array is not actually 5 elements long (a better example would be char[5]
, which I could see being padded to 8 bytes). 如果它们可以填充(再次,我不确定)那么int[5]
数组实际上可能不是5个元素长(更好的例子是char[5]
,我可以看到填充到8个字节)。
Also there is an appreciable difference between int*
and int**
since the latter doesn't guarantee contiguous memory. int*
和int**
之间也有明显的区别,因为后者不保证连续的内存。
EDIT: The reason that C++ distinguishes between int[3*5]
and int[3][5]
is because it wants to guarantee the order of the elements in memory. 编辑:C ++区分int[3*5]
和int[3][5]
的原因是因为它想要保证内存中元素的顺序。 In C++ int[0][1]
and int[0][2]
are sizeof(int)
apart in memory. 在C ++中, int[0][1]
和int[0][2]
在内存中是sizeof(int)
。 However in Fortran, for example, int[0][0]
and int[1][0]
are sizeof(int)
apart in memory because Fortran uses column major representation. 但是在Fortran中, int[0][0]
和int[1][0]
在内存中的sizeof(int)
,因为Fortran使用列主要表示。
Here's a diagram to help explain: 这是一个帮助解释的图表:
0 1 2
3 4 5
6 7 8
Can be made into an array that looks like {0,1,2,3,4,5,6,7,8} or an array that looks like: {0,3,6,1,4,7,2,5,8}. 可以做成一个看起来像{0,1,2,3,4,5,6,7,8}的数组或一个看起来像这样的数组:{0,3,6,1,4,7,2, 5,8}。
Hint: in your original code, the type of a
is more similar to int**
, so you shouldn't cast it to int*
. 提示:在你的原代码的类型, a
是更类似于int**
,所以你不应该投它来int*
。 It is a pointer to pointer to something. 它是指向某事物的指针 。
If you want to access it like an 1-D array, then a
has to be defined as an 1-D array as well. 如果你想像1-D数组那样访问它,那么a
也必须被定义为1-D数组。
@rwong: Really? @rwong:真的吗? I thought that multi-dimensionals arrays were just an "abstraction" for us, since the following are equivalent: 我认为多维数组只是我们的“抽象”,因为以下是等价的:
int array[3][5];
int array[3*5];
Anyways, I detemined what was wrong. 无论如何,我决定出了什么问题。 As usual it was not my code, but copy-pasting someone's code and working from there. 像往常一样,它不是我的代码,而是复制粘贴某人的代码并从那里开始工作。
What I had was this: 我有的是这个:
for(int i=numRows-1; i>-1 ;i++)
{
cout << p[numColumns*numRows-1+i] << endl;
}
Is funny because I did not copy-paste my code from VS, but actually wrote it from scratch to "illustrate" my error. 很有趣,因为我没有从VS复制粘贴我的代码,但实际上从头开始编写它来“说明”我的错误。
Lesson to be learnt here ;) 这里要学到的经验;)
Edit: I'm still not sure about what rwong explained here. 编辑:我仍然不确定rwong在这里解释了什么。 Would anyone care to elaborate? 有人会关心详细说明吗?
另一种方式来想一想:因为a
是类似于int**
,有一部分a
,它类似于一个int*
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.