Арифметика указателей в C
Рассмотрим следующий фрагмент кода:
int (*p)[3];
int (*q)[3];
q = p;
q++;
printf("%d, %d\n", q, p);
printf("%d\n", q-p);
Я знаю, что арифметика указателя является интеллектуальной, что означает, что операция q++
продвигает q
достаточное количество байтов вперед, чтобы указать на следующий массив из 3 целых чисел, поэтому меня не удивляет, что первая печать: "12, 0
', что означает, что приращение q
увеличило его на 12.
Но второй отпечаток меня удивляет. Он печатает 1!
Так зачем же печатать 1 вместо 12? это просто озадачивает меня.
Ответы
Ответ 1
Как и оператор приращения ++
, оператор вычитания -
с указателями также учитывает размер объектов, на которые указывают. В частности, возвращаемый результат - это количество разностей байтов в значениях указателя, деленное на размер объекта, на который указывает объект (12, в вашем примере). Таким образом, разница составляет 12 байт, деленная на размер 12 или 1.
Ответ 2
Если вы действительно хотите узнать разницу, приведите каждый указатель к (char *), а затем к (int), а затем вычтите. Это должно дать вам ответ.
Этот код дает вам абсолютное значение:
printf("%d\n", abs((int)((char*)q) - (int)((char*)p)));
Не забудьте включить math.h.
Изменить:
Как указано в комментарии, нам не нужен двойной бросок. Кастинг каждого указателя указателя на int и затем вычитание дает тот же ответ, что и (ненужное) двойное литье выше.
printf("%d\n", abs((int)(q) - (int)(p)));