Арифметика указателя в C - PullRequest
12 голосов
/ 17 апреля 2009

Рассмотрим следующий фрагмент кода:

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? это просто озадачивает меня.

Ответы [ 2 ]

27 голосов
/ 17 апреля 2009

Как и оператор приращения ++, оператор вычитания - с указателями также учитывает размер объектов, на которые он указывает. В частности, возвращаемый результат - это разница в количестве байтов в значениях указателя, деленная на размер объекта, на который указывает указатель (в вашем примере 12). Таким образом, разница составляет 12 байтов, разделенных на размер 12 или 1.

4 голосов
/ 17 апреля 2009

Если вы действительно хотите узнать разницу, приведите каждый указатель к (char *), затем к (int) и затем вычтите Это должно дать вам ответ.

Этот код дает вам абсолютное значение:

printf("%d\n", abs((int)((char*)q) - (int)((char*)p)));

Не забудьте включить math.h.

Edit: Как указано в комментарии, нам не нужно двойное приведение. Приведение каждого указателя к int и вычитание дает тот же ответ, что и (ненужное) двойное приведение выше.

printf("%d\n", abs((int)(q) - (int)(p)));
...