У меня есть следующий код

void main(void) {
    int data = 0x5555;
    int* dataptr = &data;
    int** dataptrptr = &dataptr;
    int*** dataptrptrptr = &dataptrptr;
    printf("%d\n", ***dataptrptrptr);
}

data находится по адресу 0xabcd

dataptr находится по адресу 0x1234

dataptrptr находится по адресу 0x8888

dataptrptrptr находится по адресу 0xffff

*((*dataptrptrptr) + 4) 0x8888 + 4 = 0x888c читает эффективный адрес?

Кроме того, является ли значение выражения **dataptrptrptr 0x1234?

2
WJL 22 Апр 2020 в 21:18
Откуда вы знаете адреса этих (машинно-зависимых) переменных? Вы написали программу для их вывода? Или это гипотезы? В любом случае, для соседних переменных высока вероятность того, что они не отличаются так сильно, как в приведенных примерах.
 – 
Pierre François
22 Апр 2020 в 21:26
4
В любом случае добавление 4 к указателю в C увеличивает его значение не на 4, а на 4 * sizeof (*int).
 – 
Pierre François
22 Апр 2020 в 21:40
1
«добавление 4 к ЭТОМУ указателю». Я бы в основном согласился, если бы вы использовали определенный артикль.
 – 
Jeff Holt
22 Апр 2020 в 21:52
2
... добавляет в 4 раза размер того, на что указывает.
 – 
Weather Vane
22 Апр 2020 в 21:52
1
Арифметика указателя означает, что компилятор знает размер данных, на которые указывают, и умножает индекс на размер данных. Если вы говорите addr + N, вы сообщаете компилятору, что вам нужно значение Nth, начинающееся с addr. Если там что-то есть или нет, это полностью ваша проблема, а не компилятора
 – 
geckos
23 Апр 2020 в 00:06

1 ответ

Считывается ли эффективный адрес *((*dataptrptrptr) + 4) 0x8888 + 4 = 0x888c?

Может быть - это зависит

*dataptrptrptr равно 0x8888, однако адреса не являются простыми целыми числами.

Добавление 4 к 0x8888 в виде целых чисел равно 0x888C.

В качестве указателя добавление 4 к int** 0x8888 формирует указатели адреса 4 int** дальше в памяти.

Если указатель int ** имеет длину 8 байт и если адреса увеличиваются на байтовый адрес, ожидаемая сумма равна int** 0x88A8.

Если указатель int ** имеет длину 4 байта и если адреса увеличиваются на байтовый адрес, ожидаемая сумма равна int** 0x8898.

Если указатель int ** состоит из N байтов и если int ** находится в специальном месте в памяти, где адрес представлен фрагментами из N байтов, ожидаемая сумма это int** 0x888C.

Но существуют и другие возможности: 0x8890, pointer_street:0x0004, неопределенное поведение и т. д.

Математика указателей не является целочисленной математикой.


Значением выражения **dataptrptrptr является указатель int * 0x1234.

2
chux - Reinstate Monica 23 Апр 2020 в 00:10