[英]Pointer arithmetic and 2-D array in c?
I am new to C and got stuck on "How to pass multidimensional array to a function". 我是C的新手并且坚持“如何将多维数组传递给函数”。 I do understand that you have to pass column size so that if you want to go from a[0][0]
to a[1][0]
it can calculate the size of 1-D array and can jump over it. 我知道你必须传递列大小,这样如果你想从a[0][0]
到a[1][0]
它可以计算一维数组的大小,并可以跳过它。
I have written a small program: 我写了一个小程序:
#include<stdio.h>
void foo(char[][2]);
int main()
{
char arr[2][2] = {'a','b','c','d'};
foo(arr);
return 0;
}
void foo(char temp[][2])
{
temp++;
printf("%c",*temp);
}
I expected that this code will print the letter c
, since temp
initially points to 'a'
and once we increment it, it will skip over first 1-d array and go to first element of second 1-d array which is 'c'
. 我期望这段代码会打印字母c
,因为temp
最初指向'a'
,一旦我们递增它,它将跳过第一个1-d数组并转到第二个1-d数组的第一个元素'c'
。 But it does not work that way I guess. 但是我认为这种方式不起作用。
Please explain the how compiler computes these addresses. 请解释编译器如何计算这些地址。
The pointer arithmetic is good. 指针算术很好。 You just forgot to dereference *temp
, which has type char[2]
. 你忘了取消引用*temp
,它有char[2]
类型。
Change it to **temp
, and you'll get an output c
. 将其更改为**temp
,您将获得输出c
。
For function argument char temp[][2]
, temp
decays to a pointer. 对于函数参数char temp[][2]
, temp
衰减为指针。 But only for the first (outer) dimension. 但仅限于第一(外)维度。 So it is effectively a pointer to array [2]
of char
. 所以它实际上是一个指向char
数组[2]
的指针 。
Incrementing the pointer will advance it to the next outer index, as you already assumed. 正如您已经假设的那样,递增指针将使其前进到下一个外部索引。
So, you either have to use (*temp)[0]
or **temp
to get the first element. 因此,您必须使用(*temp)[0]
或**temp
来获取第一个元素。 **temp
works, because *temp
is an array itself, so it decays to a pointer to the first element of the inner array. **temp
有效,因为*temp
是一个数组本身,所以它衰减到指向内部数组的第一个元素的指针。 The second (left) *
then dereferences this pointer: c
. 第二个(左) *
然后取消引用这个指针: c
。
Note that, allthough it uses the same syntax like char **temp
, they are fundamentally different. 请注意,虽然它使用与char **temp
相同的语法,但它们根本不同。 A pointer is not an array and here, incrementing temp
will only advance by the size of a pointer, which is not what you want. 指针不是一个数组,在这里,递增temp
只会前进一个指针的大小,这不是你想要的。
Note that the initializer would better be according to the 2-simensional nature: 请注意,初始化程序最好是根据2维性质:
{ { 'a', 'b' } , { 'c', 'd' } }
This ensures you get the correct values for the inner arrays and is good practice. 这可以确保您获得内部数组的正确值,这是一种很好的做法。 Omitting a value in the non-nested form will result in wrong sequence for the inner array. 省略非嵌套表单中的值将导致内部数组的序列错误。 When having enabled the recommended warnings ( -Wall
) at least , gcc warns about missing braces. 当至少启用了推荐警告( -Wall
) 时 ,gcc会警告缺少大括号。
Except when it is the operand of the sizeof
or unary &
operator, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element in the array. 除了当它是的操作数sizeof
或一元&
操作员,或者是一个字符串被用来初始化一个声明另一个数组,类型“的N元件阵列的表达 T
将被转换(“衰变”)”,以“指向T
指针”类型的表达式,表达式的值将是数组中第一个元素的地址。
In main
, the type of the expression arr
in the function call foo(arr)
is "2-element array of 2-element array of char
"; 在main
,函数调用foo(arr)
中的表达式arr
的类型是“2元素数组char
的2元素数组”; since it isn't the operand of the sizeof
or unary &
operators, it "decays" to an expression of type "pointer to 2-element array of char
", or char (*)[2]
. 因为它不是sizeof
或一元&
运算符的操作数,所以它“衰变”为类型为“指向2元素char
数组的指针”或char (*)[2]
的表达式。
Thus, the parameter temp
is type char (*)[2]
, and it points to the first element of arr
. 因此,参数temp
是char (*)[2]
,它指向arr
的第一个元素。 The parameter declaration char temp[][2]
is equivalent to char (*temp)[2]
. 参数声明char temp[][2]
等同于char (*temp)[2]
。 The expression *temp
is equivalent to temp[0]
, and both have type "2-element array of char
" ( char [2]
). 表达式*temp
等同于temp[0]
,并且都具有类型“ char
2元素数组”( char [2]
)。 The expression temp + 1
gives you the address of the next 2-element array of char
, so *(temp + 1)
is equivalent to temp[1]
. 表达式temp + 1
为您提供下一个2元素char
数组的地址,因此*(temp + 1)
等效于temp[1]
。
Here's a table to summarize all of that: 这是一个总结所有这些的表格:
Expression Type Decays To Value
---------- ---- --------- -----
arr char [2][2] char (*)[2] &arr[0][0]
*arr char [2] char * arr[0]
&arr char (*)[2][2] n/a &arr[0][0]
arr[i] char [2] char * &arr[i][0]
*arr[i] char n/a arr[i][0]
&arr[i] char (*)[2] n/a &arr[i][0]
arr[i][j] char n/a arr[i][j]
temp char (*)[2] n/a &arr[0][0]
*temp char [2] char * arr[0]
&temp char (**)[2] n/a addr of temp variable
temp[i] char [2] char * &arr[i][0]
*temp[i] char n/a arr[i][0]
&temp[i] char (*)[2] n/a &arr[i][0]
temp[i][j] char n/a arr[i][j]
arr + 1 char [2][2] char (*)[2] &arr[1][0]
*(arr + 1) char [2] char * arr[1]
temp + 1 char (*)[2] n/a &arr[1][0]
*(temp + 1) char [2] char * arr[1]
arr[0][0] char n/a 'a'
arr[0][1] char n/a 'b'
arr[1][0] char n/a 'c'
arr[1][1] char n/a 'd'
**temp char n/a 'a'
*temp[0] char n/a 'a'
temp[0][0] char n/a 'a'
**(temp + 1) char n/a 'c'
*temp[1] char n/a 'c'
temp[1][0] char n/a 'c'
So, in your print statement, you would write either 所以,在你的print语句中,你会写
printf("%c", **temp); // temp == &arr[1][0] after temp++
or 要么
printf("%c", *temp[0]); // temp[0] == arr[1] after temp++
or 要么
printf("%c", temp[0][0]); // temp[0][0] == arr[1][0] after temp++
The expressions arr
, &arr
, *arr
, arr[0]
, &arr[0]
, *arr[0]
, and &arr[0][0]
all yield the same value - the address of the first element of arr
(remember that the address of the array and the address of the first element of the array are the same). 表达式arr
, &arr
, *arr
, arr[0]
, &arr[0]
, *arr[0]
和&arr[0][0]
都产生相同的值 - arr
的第一个元素的地址(记住,数组的地址和数组的第一个元素的地址是相同的)。 They just differ in type. 他们的类型不同。
Note that &temp
gives us a different value than &arr
. 请注意, &temp
为我们提供了与 &arr
不同的值。 Since temp was declared as a pointer, not an array, &temp
gives us the address of the pointer variable. 由于temp被声明为指针而不是数组,因此&temp
为我们提供了指针变量的地址。
A picture may help: 图片可能会有所帮助:
+---+
arr: |'a'| arr[0][0] <------------------+ before temp++
+---+ |
|'b'| arr[0][1] |
+---+ |
|'c'| arr[1][0] <--+ after temp++ |
+---+ | |
|'d'| arr[1][1] | |
+---+ | |
... | |
+---+ | |
temp: | |---------------+---------------+
+---+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.