#include<stdio.h>
int test(int *x);
void main(){
int arr[2][3], a;
arr[1][2] = 2;
printf("%dn", test((int *)arr));
printf("%dn", *(*(arr+1)+2));
}
int test(int *prr){
int a;
a = *(*(prr+1)+2);
return a;
}
上面的代码给了我以下错误:
error: invalid type argument of unary ‘*’ (have ‘int’)
a = *( *(prr+1)+2);
^
,但是同样的声明在main函数中也可以使用:
printf("%dn", *( *(arr+1)+2)).
当我用*((arr+1*3) + 2)
替换它时,3 是第二次元的大小,在功能测试中,它工作了,我不明白是怎么做到的??我真的很想知道原因。请帮助! !
为什么在传递给函数时需要对二维数组进行类型转换,而不是对一维数组进行类型转换?
我使用了http://www.geeksforgeeks.org/pass-2d-array-parameter-c/的帮助,但原因不在那里。
在main
函数中,arr
是int
数组的数组。*(*(arr+1)+2)
相当于*(arr[1] + 2) = arr[1][2]
。arr[1]
是一个数组,将衰变为指向第一个元素arr[1][0]
的指针。
test中,prr
是指向int
的指针。*(prr+1)+2
相当于*(prr[1] + 2)
。prr[1]
是一个int
。这使得表达式prr[1] + 2
变成了int
。一元*
操作符的操作数必须是指针变量。
将函数原型更改为
int test(int x[][3]);
并使函数调用为
printf("%dn", test(arr));
函数test(int *prr)
prr
指向整数而不是数组。所以*(Prr+1)
是一个整数,但是'*'一元运算符只适用于指针。
好了,简单介绍一下数组和指针。
经验法则1:数组和指针几乎总是可以互换的,但也有例外!对于一维数组,可以这样声明:-
int arr[10];
声明了一个名为arr
的变量,该变量可以保存10个整数元素。
我也可以类似地使用指针表示法,使用指针变量或使用数组名称(arr
)本身来表示这个数组。
printf ("%d", arr[2]); // Array method : will print out the third element, indexing starts from 0
经验法则2:数组名(无论是1D 2D 3D 4D)总是衰变成指针或地址。
printf ("%lu", arr) //will print out the base address of the array, i.e address of the first element
如何使用指针打印值?简单地说,使用*
操作符解引用它。
printf("%d", *arr) //Pointer notation - will print the first value
如何使用另一个变量引用数组?
int *ptr = arr; //Pointer notation - just simply write the array name as it decays into an address
printf("%d", *ptr); //Pointer notation - prints the first element
很多人说int *ptr是指向数组的指针。
实际上它不是。它实际上是一个指向整数的指针,而不是数组。为什么?
因为我们首先存储了数组第一个整数的地址,然后可以通过对指针进行自增来遍历它。因此,在实指针中存储的是一个整数(第一个整数)的地址。
现在,来看看二维数组:-
声明: -
int arr[2][3]; // arrays of 2 rows and 3 columns, total 6 elements
与上述规则相同,意味着:-
printf("%d", arr[0][1]); //prints the second element of the first row.
printf("%lu", arr) //prints the base address of the 2D array
指向指针表示法:-
printf("%d", *(*(arr + 0) + 1); // how this works?
arr包含地址。为其添加一个整数,使您跳转到该行。
arr + 1 // gives the second row, i.e. arr is currently pointing to the first element of second row.
现在,进一步向它添加一个整数,将使您跳到特定行的指定列。
((arr + 1) // second row + 2 ) // will you skip to third element of the second row
这是语言提供的隐式指针表示法,当您选择将数组名称视为指针时。
现在来到你的问题:-显式指针表示法:-
你想要实现的是,将二维数组的基址存储在一个指针中。
如何正确地做?
int (*ptr)[3]; //reading it goes like this - ptr is a pointer to a 1D array of 3 ints
这里的3指定2D数组的列数。
所以它所做的是,试图将第一个 1D数组的基数地址(这意味着第0行基数地址)存储到指针中。
其余部分保持不变。
int (*ptr)[3] = arr; // storing the 2D array in ptr
现在,您可以将它用作普通指针(指针表示法适用于它)
(ptr + 1) //now ptr is pointer to the Second 1D array of that 2D array or you can say to the second row's first element.
在函数中捕获数组的另一种方法如下:-
我用得很少。
int main()
{
int arr[2][2];
fun(arr);
}
void fun(int catch[][])
{
}
// This is simple to understand and as well as to relate. Now, again catch can be used as pointer or as an array. It depends on you :)
void fun1(int (*ptr)[2])
{
//my way
printf("%d", ptr[1][1]);
printf("%d", *(*(ptr + 1) + 1));
//answer will be the same
}
//Ptr now contains that 2D array base address, again can be used as an array or a pointer :)
在您的函数main
中,arr
是int
的二维数组,因此,这是有效的-
printf("%dn", *(*(arr+1)+2)); // you dereference it twice to get value
但是在函数test
中,参数类型是int *
,因此,这个表达式-
a = *( *(prr+1)+2); // prr is of type int *
在两次对int *
解引用时出现错误。只有一个间接层次,因此您需要取消引用一次。同样,你也可以通过直接传递二维数组来实现同样的效果,而不需要强制转换。
像这样-
int test(int **prr){
// you code
}
在main
中你可以这样命名-
int x = test(arr);