数组指向衰减并将multidimensional array传递给函数

我知道一个数组衰减到一个指针,如果一个声明

char things[8]; 

然后在其他地方使用的thingsthings是一个指向数组中的第一个元素的指针。

另外,从我的理解,如果一个声明

 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 *strchar 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]时, &strstr之间的区别?

此外,

  • void doThings(char thingsGoHere[8][8])只是void doThings(char (*thingsGoHere)[8]) ,因此接受任何二维数组,而第二维为8。

关于C和C ++中的variablestypes:(我想添加回答)

  • C ++ 的C ++概念没有任何引用 。 如果它在C中使用,那就意味着作者在谈论指针variables。
  • C支持pass by Address pass by value
  • C ++支持Pass by addresspass by value pass 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个字节]

希望这可以帮助。 🙂