数组指向衰减并将multidimensional array传递给函数
我知道一个数组衰减到一个指针,如果一个声明
char things[8];
然后在其他地方使用的things , things是一个指向数组中的第一个元素的指针。
另外,从我的理解,如果一个声明
char moreThings[8][8];
那么moreThings 不是指向char的types指针,而是types“指向char的指针数组”,因为衰减只发生一次。
当更多的moreThings传递给一个函数(比如用原型void doThings(char thingsGoHere[8][8])来实现的时候,堆栈实际上是怎么回事?
如果moreThings不是指针types,那么这真的还是一个通过引用? 我想我一直认为moreThings仍然代表了multidimensional array的基地址。 如果doThings把input的thingsGoHere ,它自己把它传递给另一个函数呢?
规则非常多,除非指定一个数组input为const那么该数组将永远是可修改的?
我知道types检查的东西只发生在编译时,但我仍然困惑什么在技术上被视为通过引用传递(即只有当types指针的parameter passing,或指针数组是通过 – 通过引用以及?)
对不起,这个问题到处都是,但是由于我很难理解这个问题,所以很难说清楚一个确切的问题。
你有一点点错误: moreThings也衰减到指向第一个元素的指针,但由于它是一个字符数组的数组,第一个元素是一个“8字符数组”。 所以腐烂的指针是这样的:
char (*p)[8] = moreThings;
指针的值当然与&moreThings[0][0]的值相同,也就是第一个元素的第一个元素的值,同样也是&a ,但是types在每种情况下都是不同的。
下面是一个例子,如果char a[N][3] :
+===========================+===========================+==== |+--------+--------+-------+|+--------+--------+-------+| || a[0,0] | a[0,1] | a[0,2]
a[1,0] | a[1,1] | a[1,2]|| … |+——–+——–+——-+++——–+——–+——-++ … | a[0] | a[1] | +===========================+===========================+==== a ^^^ ||+– &a[0,0] |+—–&a[0] +——-&a
-
&a:整个字符数组的数组地址,它是一个char[N][3] -
&a[0],与第一个元素的地址相同,它本身就是char[3] -
&a[0][0]:第一个元素的第一个元素的地址,它是一个char
这表明不同的对象可能具有相同的地址,但是如果两个对象具有相同的地址和相同的types,则它们是相同的对象。
“arrays地址和多维arrays指针”
让我们先从一维数组开始:
-
宣言
char a[8];创build一个8个元素的数组。
这里a元素的 地址,而不是数组的地址 。 -
char* ptr = a;是正确的expression式,因为ptr是指向char的指针,可以解决第一个元素。 -
但是expression式
ptr = &a是错的 ! 因为ptr无法寻址数组。 -
&数组的一个手段地址。 真正的
a和&a是相同的,但在语义上是不同的,一个是char的地址,另一个是8个字符的数组地址。 -
char (*ptr2)[8];这里ptr2 is pointer to an array of 8 chars,这次ptr2=&a是一个有效的expression式。 -
&a数据types是char(*)[8],而atypes是char[8],在大多数操作中简单地衰减到char*,例如char* ptr = a;要更好地理解阅读:
char *str和char str[]之间的区别以及如何在内存中存储?
第二种情况,
-
声明
char aa[8][8];创build一个8x8大小的二维数组。 -
任何二维数组也可以看作一维数组,其中每个数组元素是一维数组 。
-
aa是第一个元素的地址,它是8个字符的数组。 expression式ptr2 = aa是有效和正确的。 -
如果我们声明如下:
char (*ptr3)[8][8]; char ptr3 = &aa; //is a correct expression同样的,
moreThings在你的声明中char moreThings[8][8];包含8个元素的char数组的第一个元素地址。要更好地理解阅读:
char* str[]和char str[][]之间的区别以及如何在内存中存储?
知道以下内容会很有趣:
-
morething是8个字符数组的地址。 -
*morething是第一个元素的地址是&morething[0][0]。 -
&morething是8 x 8的二维数组的地址。以上三者的地址值相同,但语义上各不相同。
-
**morething是第一个元素的值更多morething[0][0]。为了更好地理解: 当
str被声明为char str[10]时,&str和str之间的区别?
此外,
-
void doThings(char thingsGoHere[8][8])只是voiddoThings(char (*thingsGoHere)[8]),因此接受任何二维数组,而第二维为8。
关于C和C ++中的variablestypes:(我想添加回答)
- C ++ 中的C ++概念没有任何引用 。 如果它在C中使用,那就意味着作者在谈论指针variables。
- C支持
pass by Addresspass by value。 -
C ++支持
Pass by address,pass by valuepass by Reference,也pass by Reference。阅读: 指针variables和引用variables
最后,
- 名称数组是常量标识符不可变。
恰好Kerrek解释说,
除此之外,我们可以通过下面的例子来certificate:
#include <stdio.h> int main () { int a[10][10]; printf (".. %p %p\n", &a, &a+1); printf (".. %p %p \n ", &a[0], &a[0]+1); printf (".. %p %p \n ", &a[0][0], &a[0][0] +1); }
输出是:
.. 0x7fff6ae2ca5c 0x7fff6ae2cbec = 400 bytes difference .. 0x7fff6ae2ca5c 0x7fff6ae2ca84 = 40 bytes difference .. 0x7fff6ae2ca5c 0x7fff6ae2ca60 = 4 bytes difference.
&a +1 – >通过添加整个数组大小来移动指针。 即:400字节
&a [0] + 1 – >通过添加列的大小来移动指针。 即:40个字节。
&a [0] [0] +1 – >通过添加元素的大小(例如4个字节)来移动指针。
[int大小是4个字节]
希望这可以帮助。 🙂