Печать указателя на элемент трехмерного массива с использованием арифметики указателя - PullRequest
2 голосов
/ 27 апреля 2020

Я тестирую, как использовать имя массива с указателем арифметики c для доступа к массиву elemnets, и я пришел с этой программой:

#include <stdio.h>

int main(){

    // definition of array using designators
    int a[2][2][2] = {
        [0] = {[0] = {1, 2}, [1] = {3, 4}},
        [1] = {[0] = {5, 6}, [1] = {7, 8}}
    };

    printf("7th  element (pointer):  %p\n", *(*(a + 1) + 1) + 0);
    printf("8th  element (pointer):  %p\n", *(*(a + 1) + 1) + 1);

    return 0;
}

Хотя программа работает и печатает все правильно:

7th  element (pointer):  0x7ffd4b09a1c8
8th  element (pointer):  0x7ffd4b09a1d0

Я получаю предупреждения во время компиляции, говоря что-то подобное для каждой строки, где я использую %p заполнитель внутри printf():

warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=]
  printf("7th  element (pointer):  %p\n", *(*(a + 1) + 1) + 0);
                                   ~^     ~~~~~~~~~~~~~~~~~~~
                                   %ls

Так что на первый взгляд это выглядит Я должен просто привести указатели к (void *), и если я сделаю это и изменить строку:

printf("8th  element (pointer):  %p\n", *(*(a + 1) + 1) + 1);

С этой строкой:

printf("8th  element (pointer):  %p\n", (void *)(*(a + 1) + 1) + 1);

я получу предупреждение:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
  printf("8th  element (pointer):  %p\n", (void *)(*(a + 1) + 1) + 1);
                                                             ^

и компилятор вычисляет другой адрес для 8-го элемента, и этот адрес всего на 1 байт больше, чем предыдущий адрес элемента mnet:

7th  element (pointer):  0x7ffd9e5e1bf8
8th  element (pointer):  0x7ffd9e5e1bf9

Я также пытался это исправить вот так (добавил еще одну фигурную скобку) :

printf("8th  element (pointer):  %p\n", (void *)((*(a + 1) + 1) + 1));

и предупреждение пропало, но адрес по-прежнему рассчитывается по-другому:

7th  element (pointer):  0x7ffca6c6c468
8th  element (pointer):  0x7ffca6c6c470

Похоже, что нужен компилятор тип указателя для расчета адресов и если я приведу его Я не могу рассчитать адрес. Кто-нибудь знает, что я могу сделать, чтобы убрать предупреждение и правильно рассчитать адрес?

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Если вам нужно, чтобы арифметика c была на int*, а значение, которое нужно рассматривать как void*, приведите значение после , вы выполняете арифметику:

printf("7th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 0));
printf("8th  element (pointer):  %p\n", (void *)((int*)*(*(a + 1) + 1) + 1));
0 голосов
/ 27 апреля 2020

Вы можете сохранить указатель в отдельной переменной и передать его в printf:

void *ptr7th = (*(*(a + 1) + 1) + 0);
void *ptr8th = (*(*(a + 1) + 1) + 1);
printf("7th  element (pointer):  %p\n", ptr7th);
printf("8th  element (pointer):  %p\n", ptr8th);

, используя g cc, версия 9.3.0 с параметром -Wall не возвращает никакого предупреждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...