简体   繁体   English

关于C中的指针

[英]About pointers in C

I started to read a few articles about pointers in C and I've got one example that I don't understand. 我开始阅读一些关于C中指针的文章,我有一个我不明白的例子。

The example is from here: http://en.wikibooks.org/wiki/C_Programming/Pointers_and_arrays 示例来自: http//en.wikibooks.org/wiki/C_Programming/Pointers_and_arrays

Here it is: 这里是:

Let's look at a slightly different problem. 让我们看一个稍微不同的问题。 We want to have a two dimensional array, but we don't need to have all the rows the same length. 我们想要一个二维数组,但我们不需要让所有行都具有相同的长度。 What we do is declare an array of pointers. 我们所做的是声明一个指针数组。 The second line below declares A as an array of pointers. 下面的第二行将A声明为指针数组。 Each pointer points to a float. 每个指针指向一个浮点数。 Here's some applicable code: 这是一些适用的代码:

float  linearA[30];
 float *A[6];

 A[0] = linearA;              /*  5 - 0 = 5 elements in row  */
 A[1] = linearA + 5;          /* 11 - 5 = 6 elements in row  */
 A[2] = linearA + 11;         /* 15 - 11 = 4 elements in row */
 A[3] = linearA + 15;         /* 21 - 15 = 6 elements        */
 A[4] = linearA + 21;         /* 25 - 21 = 4 elements        */
 A[5] = linearA + 25;         /* 30 - 25 = 5 elements        */

 A[3][2] = 3.66;          /* assigns 3.66 to linearA[17];     */
 A[3][-3] = 1.44;         /* refers to linearA[12];           
                             negative indices are sometimes useful.
                             But avoid using them as much as possible. */

My question is why A[0] is a pointer only to five elements and not to ALL of linearA , since the name of an array is a pointer to its first member. 我的问题是为什么A[0]只是指向五个元素的指针,而不是指向所有的linearA ,因为数组的名称是指向其第一个成员的指针。

And A[1] = linearA + 5; 并且A[1] = linearA + 5; is 6 elements in a row -- for the same reason? 是连续6个元素 - 出于同样的原因? Isn't A[1] supposed to be a pointer to the 6th member of linearA ? 不是A[1]应该是指向linearA的第6个成员的linearA吗?

Can someone explain where is my mistake? 有人能解释我的错误在哪里吗?

Except in a few exceptions, in C an array name is converted to a pointer to the first element of the array. 除少数例外情况外,在C中,数组名称转换为指向数组第一个元素的指针。 linearA is an array 30 of float and in the expression: linearAfloat的数组30,在表达式中:

A[0] = linearA;

it is converted to a pointer to float . 它被转换为指向float的指针。

A is an array 6 of pointer to float . A是指向float的指针的数组6。 The element of A are of type pointer to float . A的元素是float的类型指针。 So A[0] is a pointer to float and not a pointer to an array. 因此A[0]是指向float的指针而不是指向数组的指针。

And A[i][j] in C is equivalent to *(A[i] + j) so A[i][j] is a float (dereferencing a pointer to float yields a float ). 并且C中的A[i][j]等价于*(A[i] + j)因此A[i][j]是一个float (取消引用指向float的指针会产生一个float )。

A[0] is a pointer to the 1st element of linearA . A[0]是指向linearA的第一个元素的linearA Since linearA is a contiguous array, this pointer actually allows to access any of the linearA 30 elements by adding an appropriate offset. 由于linearA是一个连续的数组,因此该指针实际上允许通过添加适当的偏移量来访问任何linearA 30元素。 However in this piece of code you emulate a 2D array by pointing to different offsets in the linearA array. 但是,在这段代码中,您可以通过指向linearA数组中的不同偏移来模拟2D数组。 The result is 2D-like array addressing: A[n] brings you to the location (ie offset in the linearA ) of your n-th row and A[n][m] brings you to the m-th element inside this row. 结果是类似2D的数组寻址: A[n]将您带到第n行的位置(即linearA A[n][m]中的偏移量), A[n][m]将您带到此行内的第m个元素。

It's because this line sets up an array of 6 pointers to float : 这是因为这一行设置了一个包含6个float的数组:

float *A[6];

And this line sets the first of those pointers to the first element of the 30. 这一行设置了第一个指向30的第一个元素的指针。

A[0] = linearA; 

Therefore each element of A points to a subsection of the original array. 因此,A的每个元素都指向原始数组的子部分。 You have to assign them though - they'll initially point to random addresses. 你必须分配它们 - 它们最初会指向随机地址。

The first one is the initial address ( &linearA[0] ) and the next five are the following ones. 第一个是初始地址( &linearA[0] ),接下来的五个是以下的地址。 These are accessible as A[0][0] to A[0][5] . 这些可以作为A[0][0]A[0][5] Because of the way arrays correspond to pointers, you can keep going up, so long as you don't exceed the 30th. 由于数组对应指针的方式,只要你不超过30,你就可以继续上升。

But you can assign A[n] to any part of the array you like. 但是你可以将A[n]分配给你喜欢的数组的任何部分。 As long as it's part of the original array, it will point that member, and the next 5 (or however many you want). 只要它是原始数组的一部分,它就会指向该成员,以及接下来的5个(或者你想要的多少)。

For example, by pointing A[1] to &linearA[6] , you would effectively be setting up a two dimensional array (it would resemble one, but not behave as one). 例如,通过将A[1]指向&linearA[6] ,您将有效地设置一个二维数组(它将类似于一个,但不会表现为一个)。

My question is why A[0] is a pointer only to five elements and not to ALL of linearA, since the name of an array is a pointer to its first member. 我的问题是为什么A [0]只是指向五个元素的指针,而不是指向所有的linearA,因为数组的名称是指向其第一个成员的指针。

you setup A[0] to point to linearA which is the first float in the array, A[0] is a pointer and thus doesn't know anything about what it points to part from an address. 你设置A[0]指向linearA ,它是数组中的第一个浮点数, A[0]是指针,因此不知道它指向地址的部分。 So A[0] is not a pointer to only five elements it points to where the array starts and has no concept of where the array ends. 因此A[0]不是指向数组开始的五个元素的指针,并且没有数组结束位置的概念。

And A[1] = linearA + 5; 并且A [1] = linearA + 5; is 6 elements in a row -- for the same reason? 是连续6个元素 - 出于同样的原因? Isn't A[1] supposed to be a pointer to the 6th member of linearA? 不是A [1]应该是指向linearA的第6个成员的指针吗?

yes A[1] points to the sixth element but as said before its a starting address. A[1]指向第六个元素,但正如它在起始地址之前所说的那样。

The example you posted shows a somewhat esoteric technique called Iliffe vector , which is one possible way to implement jagged arrays in C. A jagged array is a matrix in which each row has a different length. 您发布的示例显示了一种称为Iliffe向量的稍微深奥的技术,这是在C中实现锯齿状数组的一种可能方式。锯齿状数组是每行具有不同长度的矩阵。

Since arrays are one-dimensional in C, you are creating a single array linearA containing all the elements, which is interpreted as a sequence of rows, each of a different size. 由于数组在C中是一维的,因此您创建一个包含所有元素的单个数组linearA ,它被解释为一系列行,每行都有不同的大小。 The pointer array A contains pointers to the first element of each row that allow you to access elements using row and column indices. 指针数组A包含指向每行第一个元素的指针,允许您使用行和列索引访问元素。

The code displays several interesting features of C pointers and arrays: 代码显示了C指针和数组的几个有趣特性:

linearA + 5

Pointer arithmetic: adding an integer to a pointer (or array) gives you a pointer pointing n elements after the original pointer. 指针算术:向指针(或数组)添加一个整数,为您提供指向原始指针后n个元素的指针。

A[3][2] = 3.66;

This nice syntax allows you to think of this structure as a two-dimensional matrix. 这个漂亮的语法允许您将此结构视为二维矩阵。

Also, and this is probably the main point of the example, pointers and arrays are interchangeable . 此外,这可能是示例的要点, 指针和数组是可以互换的 Here, A[3] is a pointer to float, since A was defined as an array of pointers to floats; 这里, A[3]是指向float的指针,因为A被定义为指向浮点数的指针数组; appending [2] gives us the element 2 places after the one pointed by the original pointer. appending [2]为我们提供了原始指针指向的元素之后的2个元素。 This is similar to the pointer arithmetic above, only in this case the pointer is dereferenced. 这与上面的指针算法类似,只是在这种情况下指针被解除引用。 Actually, array access is defined in terms of pointers so X[5] is equivalent to *(X+5) . 实际上,数组访问是根据指针定义的,所以X[5]相当于*(X+5)

A[3][-3]

This shows that there is nothing stopping you from accessing an element outside of a given row. 这表明没有什么能阻止您访问给定行之外的元素。 In this case, you are accessing the element 3 places before the one pointed by A[3] . 在这种情况下,您将访问A[3]指向的元素之前的3个元素。 This is something that is rarely needed, and it only works in this case because you built the matrix to have contiguous elements. 这是很少需要的东西,它只适用于这种情况,因为你构建了矩阵以具有连续的元素。 Usually, accessing elements outside the allocated range of an array will crash your program. 通常,访问分配的数组范围之外的元素会使程序崩溃。

Finally, to answer your question: 最后,回答你的问题:

And A[1] = linearA + 5; 并且A[1] = linearA + 5; is 6 elements in a row -- for the same reason? 是连续6个元素 - 出于同样的原因? Isn't A[1] supposed to be a pointer to the 6th member of linearA ? 不是A[1]应该是指向linearA的第6个成员的linearA吗?

As pointers and arrays are interchangeable, A[1] is both a pointer to the sixth element in linearA and an array starting from the sixth element in linearA . 作为指针和数组是可互换的, A[1]两个指针在第六元件linearA 从在第六元素开始的阵列linearA There is nothing in the language saying that the latter is 6 elements long, you have to implement that logic in your code. 语言中没有任何内容表示后者长度为6个元素,您必须在代码中实现该逻辑。

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

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