2D和1D数组中指针的区别

时间:2018-01-16 22:18:33

标签: c arrays pointers

我今天练习了一些C代码,特别是带有返回函数和指针的数组。 我发现了一些令人困惑的代码,并想知道原因。

所以我首先有一个函数可以打印出数组中的所有元素。

void function(int *arr)
{
    ...
    printf("%d, arr[i]);
}

现在主要是我有一个2D数组和一维数组。

int array2D[2][2] = {{1,2}, {3,4}};
int array1D[3] = {1,2,3};

function(*array2D); // Why do I need here the derefernce pointer
function(array1D);  // why I don't need here the deference pointer

在另一个案例中:

void disp( int *num)
{
    printf("%d ", *num);
}

int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    for (int i=0; i<10; i++)
    {
        /* Passing addresses of array elements*/
        disp(&arr[i]); // why i need here & and above in the function not
    }
}

现在这让我很困惑。有人可以解释一下吗?

2 个答案:

答案 0 :(得分:4)

第一行

function(*array2D);

相当于

function(array2D[0]);

所以你传递的是第一个数组[1,2]。在C中,数组衰减为指针 当它传递给函数时。

但是,您的function函数 1 也应该获得 数组的元素。

void function(int *arr, size_t len)
{
    size_t i;
    for(i = 0; i < len; ++i)
        printf("%d\n", arr[i]);
}

然后你可以称之为 2

int array2D[2][2] = { { 1,2} ,{3,4}};
int array1D[3] = {1,2,3};

function(*array2D, sizeof *array2D / sizeof **array2D);
function(array1D, sizeof array1D / sizeof *array1D);
  disp (&arr[i]); // why i need here & and above in the function not

因为arr[i]会为您提供存储在i位置的值,disp 需要一个指针,所以你使用& - 运算符返回的地址 位于i的数组,也相当于arr + i

1 不要打电话给你的职能function。从技术上讲,这是有效的名称,但它 如果你给你的函数更明确的名称,那么会更好 阅读这个名字,你知道这些功能是做什么的。

2 请注意sizeof array / sizeof *array仅适用于数组。如果你有 函数,你期望一个数组,你只会得到一个指向数组的指针。 在这种情况下,您还需要传递数组的长度。

答案 1 :(得分:0)

我们已经习惯了int mike[10]衰减到int *这一事实,它指向数组中的第一件事。所以似乎int sam[5][10]也可能衰减到int * 指向数组的第一个元素。但int sam[5][10]不是&#34;二维数组的int&#34;衰减到一个int指针,它是一个由十个整数组成的五个数组的数组。 sam中的第一件事是五个数组中的第一个,所以sam衰减到指向十个整数数组的指针,该类型写为int (*)[10],尽管很少写的。

所以你的array2D衰减到不同于整数指针的类型,这就是你的调用function(array2D);创建类型不匹配的原因。但是,您的通话function(*array2D);确实有效,因为(如上所述)*array2Darray2D[0]相同,后者是一个整数数组,并且会衰减到int *

对于第二种情况,arr是一个数组,但arr[i]int,因为它只是数组中的一个位置。 &符运算符指向它运行的内容,因此&arr[i]是一个指针,并且调用有效。