2009-04-17 2 views
12

Рассмотрим следующий фрагмент кода:Указатель Арифметика В 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? это просто озадачивает меня.

ответ

27

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

+0

Так что нет способа взять два указателя и получить разницу в байтах? –

+8

Нарисуйте указатели на (char *), тогда вы получите разницу в байтах. –

+4

@Leif: Или просто умножьте разницу на sizeof (your_type). –

4

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

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

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

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

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

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

Почему двойной литой? –

+0

Это не работает надежно, если sizeof (int) Idelic

Смежные вопросы