c -为什么声明*(*(arr+1)+2)不工作,当我传递一个2d数组函数(tes).t


#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函数中,arrint数组的数组。*(*(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中,arrint的二维数组,因此,这是有效的-

 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);

相关内容

  • 没有找到相关文章

最新更新