Печать адреса первого элемента двумерного массива в C - PullRequest
0 голосов
/ 06 апреля 2020
#include <stdio.h>

int main ()  
{
    int  arr[4][5] = {{1, 2, 3, 4, 5},
                      {6, 7,8, 9, 10},
                      {11, 12, 13, 14, 15},
                      {16, 17,18, 19, 20}
                     };
    printf("%p\n", arr);
    printf("%p\n",*arr);

    return(0);
}

Я сомневаюсь, что когда я печатаю arr и * arr, он печатает одно и то же значение. Почему это происходит?

Ответы [ 3 ]

2 голосов
/ 06 апреля 2020

потому что вы должны знать, что имя любого массива означает, что первый адрес этого массива скажет

 int arr[4]; 
printf("%p",arr);// the same as printf("%p",&arr[0]); 

, а в отношении 2D-массива также имя массива действует как визуальный указатель, который указывает на адрес первый элемент в массиве

int arr[4][5]; 
printf("%p",&arr[0][0]);//the same as printf("%p",arr);=printf("%p"*arr);
```````````````
1 голос
/ 06 апреля 2020

arr - это массив массивов int. Согласно правилу преобразования массива в указатель, arr в printf(“%p\n”, arr); будет затухать, указывая на его первый элемент. Первый элемент массива arr имеет тип int [5], то есть массив 5 int. Поэтому будет напечатан адрес первого элемента массива arr (адрес arr[0]).

Разыменование, arr вернет первый элемент arr. Этот первый элемент имеет тип int [5], как обсуждалось ранее. Таким образом, *arr вернет массив из 5 int, но, опять же, согласно правилу преобразования массива в указатель *arr будет затухать, чтобы указывать на его первый элемент, который является arr[0][0].

Итак, фактически сначала printf печатает адрес массива arr[0], а позже печатает адрес элемента arr[0][0].

Чтобы понять, почему оба эти адреса одинаковы, я бы предложил вам прочитать эту запись .

0 голосов
/ 06 апреля 2020
printf("%p\n", arr);
printf("%p\n",*arr);

В первом примере arr распадается на указатель на первый элемент в первом измерении двумерного массива arr (первый массив int из 5 элементов - тип (* 1005) *)) который также распадается на указатель на свой первый элемент, который a[0][0].

. Во втором примере вы явно обращаетесь к первому элементу первого измерения (тип int[5] - int массив из 5 элементов), и этот также распадается на указатель на свой первый элемент, который снова равен a[0][0].

Таким образом, оба результата имеют одинаковый результат - доступ и печать адреса первого элемента первого массива в первом измерении arr - arr[0][0].


Примечание то, что вам нужно привести указатель к void, чтобы программа C -стандарт-соответствовала, поскольку стандарт подразумевает, что спецификатор формата %p должен иметь связанный аргумент типа void*:

printf("%p\n", (void*) arr);
printf("%p\n", (void*) *arr);

Цитата из ISO: IEC 9899: 2018 (C18), раздел 7.21.6.1/8:

"p - Аргумент должен быть указателем на void . Значение указателя преобразуется в последовательность печатных символов способом, определяемым реализацией. "

...