Нахождение разницы между адресами элементов в массиве

У меня есть вопрос о пересмотре экзамена по арифметике указателей, и одна часть, в которой мы вычитаем адрес двух переменных массива, для меня не имеет смысла.

На самом деле один массив равен другому. Я понимаю отдельные выходы для каждой переменной массива, и в этом случае разница между двумя адресами составляет 16, учитывая int = 4 байта в этой ОС.

Я не понимаю, почему вычитание дает 4. Моя логика заключалась бы в том, что они находятся на 4 позиции в массиве, но для меня это не имеет смысла.

int main(void)
{

int oddNums[5] = {1, 3, 5, 7, 9};
int *ip = oddNums;

printf("&oddNums[4] %d - ip %d= %d\n",&oddNums[4], ip,  &oddNums[4] - ip);
/*prints &oddNums[4] 2686740 - ip 2686724= 4*/

   return EXIT_SUCCESS;
}

person Community    schedule 26.08.2014    source источник


Ответы (2)


Вычитание возвращает 4, потому что оно возвращает свой результат в виде sizeof(<array-element>). Это сделано для того, чтобы вычитание было обратным сложению, которое также влияет на размер элемента массива.

Напомним, что если a - это массив, а i - целое число, тогда a+i совпадает с &a[i], поэтому при добавлении необходимо учитывать размер элемента. Чтобы следовать правилам математики, вычитание также должно делить размер элемента.

Это значительно упрощает арифметику указателей, поскольку операции сложения и вычитания заботятся о размере элемента массива. Без этого правила нужно было бы продолжать делить или умножать результаты сложения или вычитания на размер элемента, чтобы получить адрес желаемого элемента или смещение. Это подвержено ошибкам, и это также трудно читать. Наконец, это создало бы кошмар обслуживания в ситуациях, когда вы изменяете размер элемента с одного байта на несколько байтов, а тот, кто кодировал алгоритм, забыл умножить или разделить на sizeof.

person Sergey Kalinichenko    schedule 26.08.2014

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

Это похоже на добавление указателя к целому числу: это означает продвижение указателя на это количество элементов.

Убедитесь, что вы думаете об «указателе» как о чем-то, что говорит вам, где найти объект определенного типа. (В отличие от того, чтобы думать об этом как о целом числе, представляющем адрес памяти).

person M.M    schedule 26.08.2014