Неоднозначность в разнице адресов в массиве

#include <stdio.h>
main()
{
    int a[] ={ 1,2,3,4,5,6,7};
    char c[] = {' a','x','h','o','k'};
    printf("%d ", (&a[3]-&a[0]));
}

Вывод программы равен 3. Однако разница в выводах значений, полученных ниже, составляет 12. Может кто-нибудь объяснить двусмысленность.

#include <stdio.h>
main()
{
    int a[] ={ 1,2,3,4,5,6,7};
    char c[] = {' a','x','h','o','k'};
    printf("%d     %d ", &a[3],&a[0]);
}

person Suraj Menon    schedule 20.10.2012    source источник


Ответы (4)


Это называется арифметикой указателей. Результатом являются значения, разделенные на sizeof(int)

Если разница в байтах 12, а размер int равен 4, то результат 12/4=3

Кстати, при печати адресов используйте спецификатор формата %p:

printf("%p     %p ", &a[3],&a[0]);
person MByD    schedule 20.10.2012
comment
как printf("%d %d ", &a[3],&a[0]); печатает разницу? Я думаю, он должен печатать a[3] и a[0]. - person Yogendra Singh; 20.10.2012
comment
Прочитайте вопрос ОП. разница между напечатанными адресами равна 12. - person MByD; 20.10.2012

В первом случае к указателю применяется оператор '-', и результат измеряется в количестве элементов, а не в абсолютных адресах. Проверьте это: Арифметика указателя.

person SomeWittyUsername    schedule 20.10.2012

вы печатаете адрес

#include<stdio.h>
main()
{
 int a[] ={ 1,2,3,4,5,6,7};
char c[] = {' a','x','h','o','k'};
printf("%d     %d ", &a[3],&a[0]);

}

результат

-1085768040     -1085768052 

кодовая панель

и для первого ответа Биньямин Шарет идеален

person NullPoiиteя    schedule 20.10.2012

Прежде всего, компилятор автоматически переводит a[i] в *(a+i) (см. https://stackoverflow.com/a/1995156/226621 интересное последствие этого). Итак, &a[i] совпадает с &*(a+i) или a+i. Это означает, что:

&a[3]-&a[0]

такой же как

(a+3) - (a+0)

который 3. Это также означает, что для p и q, оба из которых являются указателями на некоторый тип T (т. е. *p и *q имеют тип T), и когда p-q допустимо, это дает вам количество элементов типа T между p и q . Компилятор автоматически преобразует разницу в значениях p и q и разделит эту разницу на sizeof(T), чтобы получить правильное число.

Поэтому, когда вы печатаете значения отдельных указателей, а затем самостоятельно вычитаете эти значения (например, в уме), вы получите число, которое в sizeof(T) раза больше "слишком большого".

На вашей машине 12 / sizeof(int) == 3, что означает, что sizeof(int) равно 4.

Кстати, для вывода значений указателя следует использовать спецификатор %p:

printf("%p %p\n", (void *)&a[3], (void *)&a[0]);
person Alok Singhal    schedule 20.10.2012