简体   繁体   English

帮助指针算术

[英]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.

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