简体   繁体   English

多维数组:指针不指向自己的地址吗?

[英]Multidimensional arrays: don't the pointers point to their own addresses?

I'm a student learning C, trying to wrap my head around something. 我是一名学习C的学生,试着把头脑包裹起来。

Let's say you have some multidimensional array int multi[2][2] . 假设你有一些多维数组int multi[2][2] The value of multi will be a pointer to the address of multi[0] . multi的值将是指向multi[0]地址的指针。 For simplicity, let's say that address is 1000. Dereferencing multi[0] extracts another address, this address the address of multi[0][0] . 为简单起见,假设地址为1000.解除引用multi[0]提取另一个地址,这解决了multi[0][0]的地址。 Dereferencing that, in turn, gets us the value (or returns the address for assignment if on the left side.) 取消引用,反过来,获取值(或者如果在左侧则返回分配地址。)

Now, multi + 1 returns the address of the second pointer. 现在, multi + 1返回第二个指针的地址。 Let's say that we have 4 byte ints (of which there are two per nested array), so the address returned by multi + 1 will be 1008. This address will contain the address of multi[1][0] , which will be 1008. 假设我们有4个字节的整数(其中每个嵌套数组有两个),因此multi + 1返回的地址将为1008.该地址将包含multi[1][0]的地址,该地址为1008 。

So here I see a pattern: doesn't this mean that the address in multi[0] , multi[1] , and so forth, contains a pointer to its own address ? 所以在这里我看到一个模式:这是不是意味着multi[0]multi[1]等中的地址包含指向自己地址的指针?

Arrays and pointers are different. 数组和指针是不同的。 This topic is often presented poorly in books. 这个主题在书中经常表现不佳。

In the case of int multi[2][2] , this is a block of 4 contiguous ints. int multi[2][2]的情况下,这是一个包含4个连续整数的块。 There are no pointers involved. 没有涉及指针。 C's type system divides this block up into two sub-arrays, each containing 2 ints. C的类型系统将该块分成两个子阵列,每个子阵列包含2整数。

These expressions: multi , multi[0] denote arrays. 这些表达式: multimulti[0]表示数组。 When you use an expression that denotes an array, in a context other than sizeof or & , then a conversion is performed, and the result of that conversion is a pointer to the first element of the array. 当您使用表示数组的表达式时,在sizeof&之外的上下文中,将执行转换,并且该转换的结果是指向数组的第一个元素的指针。

This pointer is an rvalue , ie it has the same sort of status as x + y : it's a value you can work with, but it doesn't consume any storage (at least, it's not stored as part of the array); 这个指针是一个右值 ,即它与x + y具有相同的状态:它是你可以使用的值,但它不消耗任何存储空间(至少,它不存储为数组的一部分); and you can't use the & operator on it. 而你不能使用&运算符。

The value of multi will be a pointer to the address of multi[0] multi的值将是指向multi [0]地址的指针

If multi , which is an array, is used in an expression, it is converted to a pointer to multi[0] , the value of which is the address of multi[0] . 如果在表达式中使用multi (数组),则将其转换为指向multi[0]的指针,其值为multi[0]的地址。 An array, when used in an expression, is always converted to a pointer to its first element ... thus arrays in C aren't first class objects and cannot be passed to functions (only their addresses can) or assigned ( memcpy is used to copy arrays). 在表达式中使用时,数组总是转换为指向其第一个元素的指针...因此,C中的数组不是第一类对象,不能传递给函数(只有它们的地址可以)或赋值(使用memcpy )复制数组)。

Dereferencing multi[0] extracts another address, this address the address of multi[0][0] 解除引用multi [0]提取另一个地址,这解决了multi [0] [0]的地址

There's no "extraction". 没有“提取”。 dereferencing multi[0] yields an array, which is converted to a pointer to its first element. 取消引用multi[0]产生一个数组,该数组将转换为指向其第一个元素的指针。 The value of this pointer is the address of multi[0][0] . 该指针的值是multi[0][0]的地址。 All of these addresses have the same value, because they point to exactly the same place in memory ... the first of four int s. 所有这些地址都具有相同的值,因为它们指向内存中完全相同的位置...四个int第一个。

Now, multi + 1 returns the address of the second pointer. 现在,multi + 1返回第二个指针的地址。

Again, there is no pointer in memory . 同样, 内存中没有指针 multi + 1 refers to an array ... the second of two arrays of two int s. multi + 1指的是一个数组...两个int的两个数组中的第二个。 Using that array in an expression converts it to a pointer to its first element, multi[1][0] . 在表达式中使用该数组转换为指向其第一个元素multi[1][0]的指针。

Let's say that we have 4 byte ints (of which there are three per nested array), so the address returned by multi + 1 will be 1012. 假设我们有4个字节的整数(每个嵌套数组有3个),因此multi + 1返回的地址为1012。

Er, you declared int multi[2][2] , which is two arrays each of which contains two arrays. 呃,你声明了int multi[2][2] ,这是两个数组,每个数组包含两个数组。 So multi + 1 is 1008. 所以multi + 1是1008。

This address will contain the address of multi[1][0], which will be 1012. 该地址将包含multi [1] [0]的地址,该地址为1012。

It makes no sense to talk about addresses containing addresses. 谈论包含地址的地址是没有意义的。 pointers contain addresses, but we have no pointers in memory here, we only have int s. 指针包含地址,但我们在内存中没有指针,我们只有int multi[1][0] is an int and its address is 1008. multi[1] is an array of int s and its address is also 1008 ... of course, because its address is the same as the address of its first element. multi[1][0]是一个int ,它的地址是1008. multi[1]是一个int数组,它的地址也是1008 ...当然,因为它的地址与它的第一个地址相同元件。

So here I see a pattern: doesn't this mean that the address in multi[0], multi[1], and so forth, contains a pointer to its own address? 所以在这里我看到一个模式:这是不是意味着multi [0],multi [1]等中的地址包含指向自己地址的指针?

There are no addresses in multi[0] and multi[1] , there are arrays (of int s). multi[0]multi[1]中没有地址,有数组int s)。 arrays have addresses, but in this case they don't contain addresses. 数组地址,但在这种情况下,它们不包含地址。 The way to "see a pattern" is to think in terms of what's in memory. “看模式”的方法是根据记忆中的内容来思考。 Here, you simply have a block of 4 int s -- two arrays of two int s each; 在这里,你只需要一个4个int的块 - 两个两个int的数组; arrays have no overhead or other extraneous content in C, they just have the data ... what you declare is what you get. 数组在C中没有开销或其他无关内容,它们只有数据......你声明的是你得到的。 The array is an abstraction , a grouping of items determined by its type and size, which exist only at compile-time and in the mind of the programmer. 数组是一个抽象 ,一个由其类型和大小决定的项目组,只存在于编译时和程序员的脑海中。 Thus, multi[0] contains an array , in the abstract model of a C program, but all there is in memory is four int s, the first two of which comprise that array. 因此, multi[0]在C程序的抽象模型中包含一个数组 ,但是内存中的所有内容都是四个int ,前两个包含该数组。

The situation would be different with 情况会有所不同

int* multi[2];

There you have an array of two pointers to int ; 你有一个两个指向int的数组; each pointer will point to an array of int s (once you set it to the address of an array of int s, usually obtained from malloc ). 每个指针都指向一个int数组(一旦你将它设置为int数组的地址,通常从malloc获得)。 Once you allocate memory for the subarrays and assign the two pointers, you can use this multi much the way you use the multi above, but the type, size, and memory layout of multi[0] and multi[1] are quite different in the two cases. 一旦为子阵列分配存储器并分配两个指针,则可以使用此multi使用多方式multi的上方,但类型,大小和的存储器布局multi[0]multi[1]是在完全不同的这两个案子。

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

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