17

对于以下代码:

    int (*ptr)[10];
    int a[10]={99,1,2,3,4,5,6,7,8,9};
    ptr=&a;
    printf("%d",(*ptr)[1]);

它应该打印什么?我期待这里的垃圾值,但输出是1.
(为此我得出结论,以这种方式初始化指针数组,即ptr[10]开始按顺序指向元素a[10])。

但是这个代码片段呢:

int *ptr[10];
int a[10]={0,1,2,3,4,5,6,7,8,9};
*ptr=a;
printf("%d",*ptr[1]);

它给出了分段错误。

4

6 回答 6

19

int *ptr[10];

这是一个由 10 个int*指针组成的数组,不像你想象的那样,一个指向 10 ints数组的指针

int (*ptr)[10];

这是一个指向 10 个数组的指针int

我相信int *ptr;两者都可以指向一个数组,但是给定的形式只能指向一个 10 ints的数组

于 2012-12-17T08:39:56.270 回答
10
int (*ptr)[10];

是一个指向 10 个整数数组的指针。

int *ptr[10];

是一个包含 10 个指针的数组。

段错误的原因:

*ptr=a; printf("%d",*ptr[1]);

在这里,您正在分配指向元素的a数组ptr地址a[0]。这相当于:*ptr=&a[0];

但是,当您打印时,您访问ptr[1]的是一个未初始化的指针,它是未定义的行为,因此会产生段错误。

于 2012-12-17T08:45:57.190 回答
4

int(*)[10]是指向具有 10 个成员的 int 数组的指针。即它指向int a[10].

int *[10]整数指针数组在哪里

#include <stdio.h>
int main()
{

int *ptr[10];
int a[10]={0,1,2,3,4,5,6,7,8,9};

printf("\n%p  %p", ptr[0], a);

*ptr=a; //ptr[0] is assigned with address of array a.

printf("\n%p  %p", ptr[0], a); //gives you same address

printf("\n%d",*ptr[0]); //Prints zero. If *ptr[1] is given then *(ptr + 1) i.e ptr[1] is considered which is uninitialized one.

return 0;
}
于 2012-12-17T08:40:14.023 回答
1

int (*p)[10] 意味着 p 现在是一个指向大小为 10 的整数数组的指针。

int *p[10] 表示 p 是一个由 10 个整数指针组成的数组。

于 2012-12-17T08:42:30.967 回答
1

int (*p)[10]是指向每行中包含 10 个整数的数组的指针,即可以有任意数量的行。基本上它可以用来指向一个二维数组,并且可以通过递增来访问维度i,这与这里访问*(p+i)[10]的相同。a[i][10]'i=1,2,3...'1,2,3.. rows

其中,int *p[10]是一个由 10 个整数指针组成的数组。

如果数组是二维的,例如

b[2][10]={{0,1,2,3,4,5,6,7,8,9},{10,11,12,13,14,15,16,17,18,19}}; 基本上, (*ptr)[10] // where the higher dimension index is omitted i.e, 2可以用作指向数组的二维指针(每行包含 10 个元素,即第一维),如(*ptr)[10] = &b. 在printf("%d",(*ptr)[1]);as provided中,与对第一个维度的计算结果(*ptr)相同,即值为 0。同样,要访问数组的第二个维度,表达式将是或或给出第二个维度的第一个元素,即 10。*(ptr+0)b[0][0]b[1][0]**(ptr+1)*(ptr+1)[0]*(*(ptr+i)+j); // where i=1 and j=0

我已经回答了很长时间,所以很容易理解。

于 2017-08-15T07:07:11.980 回答
0

仅有的两个用例(*ptr)[10]是:

  • 使用二维数组时;
  • typedef 固定长度数组。

由于第一个案例已经在上面由 Sreeharsha Punyasamudram 解释过,我将解释更奇特的用例。

    #include <stdio.h>

typedef int arr1d10[10];
typedef int arr2d3[3][3];

void test1d0(arr1d10 *arr)
{
    /* This is the same as the case with function test1d1(). */
    printf("Element: %d\n", (*arr)[0]);
}

void test1d1(int (*arr)[10])
{
    /* As arr is a pointer to an array of 10 integers, pointer arithmetic will work with the size of an array of 10 integers, i.e. 
       when you increment arr it will increment by sizeof(arr1d10), which is 40 bytes.
       That's why when you dereference it, you can't simply do arr[1], because it will increment arr by 40 bytes forward.
       Also when dereferencing it, because it thinks it points to a whole array it will give you that array - it's address.
       This is another reason you can't do just arr[i], because those will be just addresses.
       The correct way is to dereference it once(*arr)), to get the address (think of implicitely casting to int*) and then you can do as usually (*arr)[1]).
    */
    printf("Element: %d\n", (*arr)[1]);
}

void test2d0(arr2d3 *arr2d)
{
    /* This is a little more complicated, but the principle is the same as above. */
    printf("Element: %d\n", (*arr2d)[0][0]);
}

void test2d1(int (*arr2d)[3][3])
{
    printf("Element: %d\n", (*arr2d)[0][1]);
}

int main(void)
{
    arr1d10 arr1d = {0, 1, 2};
    arr2d3 arr2d = { {0,1},{2,3},{3,4}};
    int (*p1d)[10] = &arr1d; 
    int (*p2d)[3][3] = &arr2d;

    printf("********** PRINT 1D array **********\n");
    test1d0(&arr1d);
    test1d1(&arr1d);
    test1d0(p1d);
    test1d1(p1d);

    printf("********** PRINT 2D array **********\n");
    test2d0(&arr2d);
    test2d1(&arr2d);
    test2d0(p2d);
    test2d1(p2d);

    return 0;
}
于 2018-07-21T18:12:42.227 回答