I know that an array decays to a pointer, such that if one declared
我知道一个数组会衰减到一个指针,如果一个声明了
char things[8];
and then later on used things
somewhere else, things
is a pointer to the first element in the array.
之后在其他地方使用的东西,是指向数组中第一个元素的指针。
Also, from my understanding, if one declares
而且,据我的理解,如果有人宣布
char moreThings[8][8];
then moreThings
is not of type pointer to char but of type "array of pointers to char," because the decay only occurs once.
此外,more不是指向char的类型指针,而是指向char的指针数组,因为衰减只发生一次。
When moreThings
is passed to a function (say with prototype void doThings(char thingsGoHere[8][8])
what is actually going on with the stack?
当更多的东西被传递给一个函数时(比如使用原型void doThings(char thingsGoHere[8][8])),堆栈实际上发生了什么?
If moreThings
is not of pointer type, then is this really still a pass-by-reference? I guess I always thought that moreThings
still represented the base address of the multidimensional array. What if doThings
took input thingsGoHere
and itself passed it to another function?
如果moreThings不是指针类型,那么这真的是一个引用传递吗?我想我一直认为更多的东西仍然是多维数组的基本地址。如果doThings接收输入内容并将其传递给另一个函数呢?
Is the rule pretty much that unless one specifies an array input as const
then the array will always be modifiable?
规则是,除非将数组输入指定为const,否则数组始终是可修改的吗?
I know that the type checking stuff only happens at compile time, but I'm still confused about what technically counts as a pass by reference (i.e. is it only when arguments of type pointer are passed, or would array of pointers be a pass-by-reference as well?)
我知道类型检查只在编译时发生,但是我仍然搞不清楚什么技术上被认为是传递引用(也就是说,它只在传递类型指针的参数时发生,或者指针的数组也会被传递引用吗?)
Sorry to be a little all over the place with this question, but because of my difficulty in understanding this it is hard to articulate a precise inquiry.
很抱歉在这个问题上有点跑题了,但是由于我在理解这个问题上有困难,所以很难给出一个精确的问题。
3 个解决方案
#1
22
You got it slightly wrong: moreThings
also decays to a pointer to the first element, but since it is an array of an array of chars, the first element is an "array of 8 chars". So the decayed pointer is of this type:
你可能会觉得有点不对:moreThings也会衰减到指向第一个元素的指针,但是因为它是一个chars数组的数组,所以第一个元素是一个“8 chars数组”。衰减指针是这样的
char (*p)[8] = moreThings;
The value of the pointer is of course the same as the value of &moreThings[0][0]
, i.e. of the first element of the first element, and also the same of &a
, but the type is a different one in each case.
指针的值当然与&moreThings[0][0]的值相同,即第一个元素的第一个元素的值,也与&a的值相同,但是类型在每种情况下都是不同的。
Here's an example if char a[N][3]
:
这里有一个例子,如果char [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
: address of the entire array of arrays of chars, which is achar[N][3]
&: chars数组的整个数组的地址,即char[N][3]
-
&a[0]
, same asa
: address of the first element, which is itself achar[3]
bb&a b1,与第一个元素的地址相同,它本身就是一个char[3]
-
&a[0][0]
: address of the first element of the first element, which is achar
[0][0]:第一个元素的第一个元素的地址,它是一个char。
This demonstrates that different objects may have the same address, but if two objects have the same address and the same type, then they are the same object.
这说明不同的对象可能有相同的地址,但是如果两个对象有相同的地址和相同的类型,那么它们就是相同的对象。
#2
12
"ARRAY ADDRESS AND POINTERS TO MULTIDIMENSIONAL ARRAYS"
Lets we start with 1-D array first:
我们先从一维数组开始:
-
Declaration
char a[8];
creates an array of 8 elements.
And herea
is address of fist element but not address of array.声明char[8];创建一个包含8个元素的数组。这里a是第一个元素的地址,不是数组的地址。
-
char* ptr = a;
is correct expression asptr
is pointer to char and can address first element.char * ptr =一个;是正确的表达式,因为ptr是指向char的指针,可以处理第一个元素。
-
But the expression
ptr = &a
is wrong! Becauseptr
can't address an array.但是“ptr = &a”的表达是错误的!因为ptr不能处理数组。
-
&a means address of array. Really Value of
a
and&a
are same but semantically both are different, One is address of char other is address of array of 8 chars.&a是指数组的地址。a和&a的值其实是一样的,但在语义上都是不同的,一个是char的地址,另一个是8 chars数组的地址。
-
char (*ptr2)[8];
Hereptr2 is pointer to an array of 8 chars
, And this timeptr2=&a
is a valid expression.char(* ptr2)[8];这里ptr2是指向一个8字符数组的指针,而这次ptr2=&a是一个有效的表达式。
-
Data-type of
&a
ischar(*)[8]
and type ofa
ischar[8]
that simply decays intochar*
in most operation e.g.char* ptr = a;
数据类型的&a是char(*)[8],类型a是char[8],在大多数操作中都只是衰变为char*,例如char* ptr = a;
To understand better read: Difference between
char *str
andchar str[]
and how both stores in memory?要更好地理解:char *str和char str[]之间的区别以及两者如何存储在内存中?
Second case,
第二个案例,
-
Declaration
char aa[8][8];
creates a 2-D array of8x8
size.声明字符aa[8][8];创建一个8x8大小的二维数组。
-
Any 2-D array can also be viewed as 1-D array in which each array element is a 1-D array.
任何二维数组也可以看作一维数组,其中每个数组元素都是一维数组。
-
aa
is address of first element that is an array of 8 chars. Expressionptr2 = aa
is valid and correct.aa是第一个元素的地址,它是一个包含8个字符的数组。表达式ptr2 = aa有效且正确。
-
If we declare as follows:
如果我们声明如下:
char (*ptr3)[8][8]; char ptr3 = &aa; //is a correct expression
Similarly,
moreThings
in your declarationchar moreThings[8][8];
contain address of fist element that is char array of 8 elements.类似地,在你的声明中还有更多的东西[8][8];包含第一个元素的地址,它是8个元素的char数组。
To understand better read: Difference between
char* str[]
andchar str[][]
and how both stores in memory?要更好地理解:char* str[]和char str[][]之间的区别以及这两者如何存储在内存中?
It would be interesting to know:
如果知道:
-
morething
is an address of 8 char array .morething是8字符数组的地址。
-
*morething
is an address of first element that is&morething[0][0]
.更多的东西是第一个元素的地址,它是[0][0]。
-
&morething
is an address of 2-D array of 8 x 8.更重要的是一个2-D数组的地址,8 x 8。
And address values of all above three are same but semantically all different.
这三者的地址值是相同的,但在语义上是完全不同的。
-
**morething
is value of first element that ismorething[0][0]
.*more是第一个元素的值也就是[0][0]。
To understand better read: Difference between
&str
andstr
, whenstr
is declared aschar str[10]
?为了更好地理解阅读:当str被声明为char str[10]时,与str和str之间的区别?
Further more,
此外,
-
void doThings(char thingsGoHere[8][8])
is nothing but voiddoThings(char (*thingsGoHere)[8])
and thus accepts any array that is two dimensional with the second dimension being 8. - void doThings(char thingsGoHere[8][8])只是void doThings(char (*thingsGoHere)[8]),因此它接受任何二维数组,而二维数组的第二个维度是8。
About type of variables in C and C++: (I would like to add in answer)
关于C和c++中的变量类型:(我想补充一下)
- Nothing is pass by reference in C its C++ concept. If its used in C that means author talking about pointer variable.
- 在c++概念中,没有什么是通过引用来传递的。如果它在C中使用,那意味着作者在谈论指针变量。
- C supports
pass by Address
andpass by value
. - C支持按地址和值传递。
-
C++ supports
Pass by address
,pass by value
and alsopass by Reference
.c++支持按地址传递、按值传递和按引用传递。
Read: pointer variables and reference variables
读取:指针变量和引用变量。
At the end,
最后,
- Name Of an array is constant identifier not variable.
- 数组的名称是常量标识符而不是变量。
#3
4
Nicely explained by Kerrek,
很好地解释为Kerrek,
In addition to that, we can prove it by the following example:
除此之外,我们可以用下面的例子来证明:
#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);
}
The Output is :
的输出是:
.. 0x7fff6ae2ca5c 0x7fff6ae2cbec = 400 bytes difference
.. 0x7fff6ae2ca5c 0x7fff6ae2ca84 = 40 bytes difference
.. 0x7fff6ae2ca5c 0x7fff6ae2ca60 = 4 bytes difference.
&a +1 -> Moves the pointer by adding whole array size. ie: 400 bytes
>通过增加整个数组大小来移动指针。即:400字节
&a[0] + 1 -> Moves the pointer by adding the size of column. ie: 40 bytes.
[0] + 1 ->通过增加列的大小来移动指针。即:40个字节。
&a[0][0] +1 -> Moves the pointer by adding the size of element ie: 4 bytes.
[0][0] +1 ->通过增加元素ie: 4字节的大小来移动指针。
[ int size is 4 bytes ]
[int大小为4字节]
Hope this helps. :)
希望这个有帮助。:)
#1
22
You got it slightly wrong: moreThings
also decays to a pointer to the first element, but since it is an array of an array of chars, the first element is an "array of 8 chars". So the decayed pointer is of this type:
你可能会觉得有点不对:moreThings也会衰减到指向第一个元素的指针,但是因为它是一个chars数组的数组,所以第一个元素是一个“8 chars数组”。衰减指针是这样的
char (*p)[8] = moreThings;
The value of the pointer is of course the same as the value of &moreThings[0][0]
, i.e. of the first element of the first element, and also the same of &a
, but the type is a different one in each case.
指针的值当然与&moreThings[0][0]的值相同,即第一个元素的第一个元素的值,也与&a的值相同,但是类型在每种情况下都是不同的。
Here's an example if char a[N][3]
:
这里有一个例子,如果char [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
: address of the entire array of arrays of chars, which is achar[N][3]
&: chars数组的整个数组的地址,即char[N][3]
-
&a[0]
, same asa
: address of the first element, which is itself achar[3]
bb&a b1,与第一个元素的地址相同,它本身就是一个char[3]
-
&a[0][0]
: address of the first element of the first element, which is achar
[0][0]:第一个元素的第一个元素的地址,它是一个char。
This demonstrates that different objects may have the same address, but if two objects have the same address and the same type, then they are the same object.
这说明不同的对象可能有相同的地址,但是如果两个对象有相同的地址和相同的类型,那么它们就是相同的对象。
#2
12
"ARRAY ADDRESS AND POINTERS TO MULTIDIMENSIONAL ARRAYS"
Lets we start with 1-D array first:
我们先从一维数组开始:
-
Declaration
char a[8];
creates an array of 8 elements.
And herea
is address of fist element but not address of array.声明char[8];创建一个包含8个元素的数组。这里a是第一个元素的地址,不是数组的地址。
-
char* ptr = a;
is correct expression asptr
is pointer to char and can address first element.char * ptr =一个;是正确的表达式,因为ptr是指向char的指针,可以处理第一个元素。
-
But the expression
ptr = &a
is wrong! Becauseptr
can't address an array.但是“ptr = &a”的表达是错误的!因为ptr不能处理数组。
-
&a means address of array. Really Value of
a
and&a
are same but semantically both are different, One is address of char other is address of array of 8 chars.&a是指数组的地址。a和&a的值其实是一样的,但在语义上都是不同的,一个是char的地址,另一个是8 chars数组的地址。
-
char (*ptr2)[8];
Hereptr2 is pointer to an array of 8 chars
, And this timeptr2=&a
is a valid expression.char(* ptr2)[8];这里ptr2是指向一个8字符数组的指针,而这次ptr2=&a是一个有效的表达式。
-
Data-type of
&a
ischar(*)[8]
and type ofa
ischar[8]
that simply decays intochar*
in most operation e.g.char* ptr = a;
数据类型的&a是char(*)[8],类型a是char[8],在大多数操作中都只是衰变为char*,例如char* ptr = a;
To understand better read: Difference between
char *str
andchar str[]
and how both stores in memory?要更好地理解:char *str和char str[]之间的区别以及两者如何存储在内存中?
Second case,
第二个案例,
-
Declaration
char aa[8][8];
creates a 2-D array of8x8
size.声明字符aa[8][8];创建一个8x8大小的二维数组。
-
Any 2-D array can also be viewed as 1-D array in which each array element is a 1-D array.
任何二维数组也可以看作一维数组,其中每个数组元素都是一维数组。
-
aa
is address of first element that is an array of 8 chars. Expressionptr2 = aa
is valid and correct.aa是第一个元素的地址,它是一个包含8个字符的数组。表达式ptr2 = aa有效且正确。
-
If we declare as follows:
如果我们声明如下:
char (*ptr3)[8][8]; char ptr3 = &aa; //is a correct expression
Similarly,
moreThings
in your declarationchar moreThings[8][8];
contain address of fist element that is char array of 8 elements.类似地,在你的声明中还有更多的东西[8][8];包含第一个元素的地址,它是8个元素的char数组。
To understand better read: Difference between
char* str[]
andchar str[][]
and how both stores in memory?要更好地理解:char* str[]和char str[][]之间的区别以及这两者如何存储在内存中?
It would be interesting to know:
如果知道:
-
morething
is an address of 8 char array .morething是8字符数组的地址。
-
*morething
is an address of first element that is&morething[0][0]
.更多的东西是第一个元素的地址,它是[0][0]。
-
&morething
is an address of 2-D array of 8 x 8.更重要的是一个2-D数组的地址,8 x 8。
And address values of all above three are same but semantically all different.
这三者的地址值是相同的,但在语义上是完全不同的。
-
**morething
is value of first element that ismorething[0][0]
.*more是第一个元素的值也就是[0][0]。
To understand better read: Difference between
&str
andstr
, whenstr
is declared aschar str[10]
?为了更好地理解阅读:当str被声明为char str[10]时,与str和str之间的区别?
Further more,
此外,
-
void doThings(char thingsGoHere[8][8])
is nothing but voiddoThings(char (*thingsGoHere)[8])
and thus accepts any array that is two dimensional with the second dimension being 8. - void doThings(char thingsGoHere[8][8])只是void doThings(char (*thingsGoHere)[8]),因此它接受任何二维数组,而二维数组的第二个维度是8。
About type of variables in C and C++: (I would like to add in answer)
关于C和c++中的变量类型:(我想补充一下)
- Nothing is pass by reference in C its C++ concept. If its used in C that means author talking about pointer variable.
- 在c++概念中,没有什么是通过引用来传递的。如果它在C中使用,那意味着作者在谈论指针变量。
- C supports
pass by Address
andpass by value
. - C支持按地址和值传递。
-
C++ supports
Pass by address
,pass by value
and alsopass by Reference
.c++支持按地址传递、按值传递和按引用传递。
Read: pointer variables and reference variables
读取:指针变量和引用变量。
At the end,
最后,
- Name Of an array is constant identifier not variable.
- 数组的名称是常量标识符而不是变量。
#3
4
Nicely explained by Kerrek,
很好地解释为Kerrek,
In addition to that, we can prove it by the following example:
除此之外,我们可以用下面的例子来证明:
#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);
}
The Output is :
的输出是:
.. 0x7fff6ae2ca5c 0x7fff6ae2cbec = 400 bytes difference
.. 0x7fff6ae2ca5c 0x7fff6ae2ca84 = 40 bytes difference
.. 0x7fff6ae2ca5c 0x7fff6ae2ca60 = 4 bytes difference.
&a +1 -> Moves the pointer by adding whole array size. ie: 400 bytes
>通过增加整个数组大小来移动指针。即:400字节
&a[0] + 1 -> Moves the pointer by adding the size of column. ie: 40 bytes.
[0] + 1 ->通过增加列的大小来移动指针。即:40个字节。
&a[0][0] +1 -> Moves the pointer by adding the size of element ie: 4 bytes.
[0][0] +1 ->通过增加元素ie: 4字节的大小来移动指针。
[ int size is 4 bytes ]
[int大小为4字节]
Hope this helps. :)
希望这个有帮助。:)