Разница между * ptr [10] и (* ptr) [10]

Для следующего кода:

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

Что он должен печатать? Я ожидаю здесь значение мусора, но результат 1.
(для которого я заключаю, что инициализация этого пути указательным массивом i.e 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]);

Он дает ошибку сегментации.

Ответ 1

int *ptr[10];

Это массив из 10 int* указателей, а не как вы предполагали бы, указатель на массив из 10 int s

int (*ptr)[10];

Это указатель на массив из 10 int

Я считаю, что те же, что и int *ptr;, в том, что оба могут указывать на массив, но данная форма может ТОЛЬКО указывать на массив из 10 int s

Ответ 2

int (*ptr)[10];

- указатель на массив из 10 целых чисел.

int *ptr[10];

- массив из 10 указателей.

Причина segfault:

* PTR = а; Е ( "% d", * PTR [1]);

Здесь вы назначаете адрес массива a - ptr, который указывает на элемент a[0]. Это эквивалентно: *ptr=&a[0];

Однако при печати вы получаете доступ к ptr[1], который является неинициализированным указателем, который является undefined и тем самым дает segfault.

Ответ 3

int(*)[10] - это указатель на массив int с 10 членами. т.е. указывает на int a[10].

где as 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;
}

Ответ 4

int (*p)[10] - это указатель на массив из 10 целых чисел в каждой строке, то есть может быть любое количество строк. в основном его можно использовать для указания на 2D-массив, и размеры могут быть доступны путем увеличения i для *(p+i)[10], который аналогичен a[i][10], здесь 'i=1,2,3...' для доступа к 1,2,3.. rows.

где as, int *p[10] - массив из 10 целых указателей.

Если массив является двухдифференцированным i.e, например

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 элементов в каждой строке i.e, 1-е измерение), как (*ptr)[10] = &b. В printf("%d",(*ptr)[1]);, как указано (*ptr), тот же, что и *(ptr+0), оценивает первое измерение, т.е. b[0][0], значение которого равно 0., чтобы получить доступ к 2-му измерению массива b[1][0], выражение будет **(ptr+1) или *(ptr+1)[0] или *(*(ptr+i)+j); // where i=1 and j=0 дает первый элемент второго измерения, т.е. 10.

Я ответил так долго, чтобы понять это легко.

Ответ 5

int (* p) [10] означает, что p теперь является указателем на целочисленный массив размера 10.

int * p [10] означает, что p представляет собой массив из 10 целых указателей.

Ответ 6

Для (*ptr)[10] есть только два варианта использования:

  • при работе с двумерными массивами;
  • Массивы фиксированной длины typedef.

Поскольку первый случай уже был объяснен Шри Харша Пуньясамудрамом, Я собираюсь объяснить более экзотический вариант использования.

    #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 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 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;
}