数组指针衰变并通过多维数组对功能(Array to pointer decay and passin

2019-06-18 09:46发布

我知道,一个数组衰变为指针,例如,如果一个声明

char things[8];

再后来所用things别的地方, things是一个指针阵列中的第一个元素。

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

char moreThings[8][8];

然后moreThings 不是类型的指针到char但类型的“指向char的阵列”,因为衰减只发生一次。

moreThings被传递给函数(原型说void doThings(char thingsGoHere[8][8])什么是真正回事栈?

如果moreThings是指针类型的不是,那么这是真的还是一个传递引用? 我想我一直认为moreThings仍代表的多维数组的基址。 如果doThings了输入thingsGoHere和它本身传递给另一个函数?

是规则相当多,除非一个指定数组输入作为const ,则阵列将永远是修改?

我知道类型检查的东西只发生在编译的时候,但我仍然感到困惑的是什么引用技术上算作合格(即是它,只有当指针类型的参数传递,或将指针数组是pass-通过引用,以及?)

对不起,是一个小遍这个问题的地方,但因为我的理解这个困难的,很难说出一个精确的查询。

Answer 1:

你得到了它稍有不妥: moreThings也衰减到指针的第一个元素,但因为它是字符数组的数组,第一个元素是“8个字符数组”。 所以腐烂的指针就是这种类型的:

char (*p)[8] = moreThings;

指针的当然是相同的值&moreThings[0][0]即,第一元件的第一元件,并且也相同的&a ,但类型是不同的一个在每种情况下。

下面是一个例子,如果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]a :所述第一元件的地址,它是一个本身char[3]

  • &a[0][0]第一元件,第一元件的地址,该地址是一个char

这表明,不同的对象可以有相同的地址,但如果两个对象具有相同的地址相同类型的,那么他们是同一个对象。



Answer 2:

“阵列地址和指向多维数组”

让我们开始与1- d阵列的第一:

  • 声明char a[8]; 创建8个元件的阵列。
    在这里, a拳头元素的地址 ,但不是数组的地址

  • char* ptr = a; 是正确的表达如ptr是字符指针和可以解决第一个元素。

  • 但表达ptr = &a错误的 ! 因为ptr不能解决的阵列。

  • &一个装置阵列的地址。 真正的价值a&a是相同的,但两者的语义是不同的,一个是其他炭的地址为8个字符的数组的地址。

  • char (*ptr2)[8]; 这里ptr2 is pointer to an array of 8 chars ,而这个时间ptr2=&a是有效的表达式。

  • 数据类型的&achar(*)[8]和类型achar[8]简单地衰变成char*在大多数操作例如char* ptr = a;

    为了更好地理解阅读: 区别char *strchar str[]并在内存中如何既店?

第二种情况下,

  • 声明char aa[8][8]; 创建的2-d阵列8x8的大小。

  • 任何2-d阵列也可以被看作1-d阵列,其中每个阵列元素是1-d阵列

  • aa是8个字符数组第一个元素的地址。 表达ptr2 = aa是有效的和正确的。

  • 如果我们声明如下:

     char (*ptr3)[8][8]; char ptr3 = &aa; //is a correct expression 

    同样的,
    moreThings在声明char moreThings[8][8]; 包含8个是元件的字符数组拳头元件的地址。

    为了更好地理解阅读: 区别char* str[]char str[][]并在内存中如何既店?


这将是有趣的了解:

  • morething是8字符数组的地址。

  • *morething是第一元素的地址&morething[0][0]

  • &morething是8×8 2-d阵列的地址。

    而所有上述三个地址值是相同的,但在语义上都是不同的。

  • **morething是第一个元素的值被morething[0][0]

    为了更好地理解阅读: 区别&strstr ,在str被声明为char str[10]

更进一步,

  • void doThings(char thingsGoHere[8][8])是什么,但空隙doThings(char (*thingsGoHere)[8])因此接受任何阵列是二维的与所述第二尺寸为8。

关于类型的C和C ++变量:(我想在回答补充)

  • 没有什么是通过参考在C中传递其C ++概念。 如果它在C中,这意味着撰文谈论指针变量。
  • C支持pass by Addresspass by value
  • C ++支持Pass by addresspass by value和也pass by Reference

    阅读: 指针变量和引用变量

在末尾,

  • 名称的数组中是恒定的标识符不变量。


Answer 3:

通过Kerrek很好解释,

除此之外,我们可以通过下面的例子证明这一点:

#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. 

&一个1 - >通过将整个阵列尺寸移动指针。 即:400个字节

&一个[0] + 1 - >通过将列的大小移动指针。 即:40个字节。

4个字节: - &一个[0] [0] 1>通过将元件即的大小移动指针。

[INT大小为4个字节]

希望这可以帮助。 :)



文章来源: Array to pointer decay and passing multidimensional arrays to functions