Разница подобного типа указателей - PullRequest
2 голосов
/ 22 января 2012

Разница двух указателей одного типа всегда одна.

#include<stdio.h>
#include<string.h>
int main(){
int a = 5,b = 10,c;
int *p = &a,*q = &b;
c = p - q;
printf("%d" , c);
return 0;
}

Output is 1.

Я не понимаю причины

Ответы [ 4 ]

9 голосов
/ 22 января 2012

Поведение не определено.

C99 6.5.6 В параграфе 9 сказано:

Когда вычтены два указателя, оба должны указывать на элементытот же самый объект массива, или один после последнего элемента объекта массива;В результате получается разница индексов двух элементов массива.

Пункт 7 в том же разделе гласит:

Для целей этих операторов указатель наобъект, который не является элементом массива, ведет себя так же, как указатель на первый элемент массива длиной один с типом объекта в качестве его типа элемента.

Раздел 4, абзац 2говорит:

Если требование «должен» или «не должен», которое появляется вне ограничения, нарушается, поведение не определено.Неопределенное поведение иначе обозначено в этом международном стандарте словами «неопределенное поведение» или пропуском любого явного определения поведения.Нет разницы в акценте между этими тремя;все они описывают «поведение, которое не определено».

3.4.3 определяет термин «неопределенное поведение» как:

поведение при использовании непереносимой или ошибочной программыконструировать или ошибочных данных, для которых этот международный стандарт не предъявляет никаких требований

ПРИМЕЧАНИЕ Возможные неопределенные варианты поведения варьируются от полного игнорирования ситуации с непредсказуемыми результатами до поведения во время перевода или выполнения программы документированным образом, характерным для среды (сили без выдачи диагностического сообщения), чтобы прекратить перевод или выполнение (с выдачей диагностического сообщения).

С учетом объявления:

int a = 5, b = 10, c;

это вероятночто оценка &b - &a даст разумный результат, такой как 1 или -1.(Разумные результаты всегда являются возможным признаком неопределенного поведения; оно не определено, не требует аварийного завершения.) Но компилятор не обязан помещать a и b в какие-либо конкретные места в памяти относительно друг друга, и дажеесли это так, вычитание не гарантированно будет значимым.Оптимизирующий компилятор может свободно преобразовывать вашу программу таким образом, чтобы предполагал , что ее поведение хорошо определено, что приводит к коду, который может вести себя произвольно плохим образом, если это предположение нарушается.&b - &a, вы фактически обещаете компилятору, что это значимая операция.Как сказал Генри Спенсер: «Если вы лжете компилятору, он получит месть».

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


О, я упоминал, что поведение не определено?

5 голосов
/ 22 января 2012

На самом деле поведение вашей программы не определено.Вывод на вашей платформе / компиляторе будет 1, но это может быть просто что-то еще.

4 голосов
/ 22 января 2012

Этот код демонстрирует неопределенное поведение, поскольку арифметика указателя определяется только тогда, когда оба операнда находятся в одном и том же массиве или структуре.

Значение 1 появляется потому, что компилятор поместил a и b рядом друг с другом в памяти. Другой компилятор может сделать что-то другое. Действительно, тот же компилятор может сделать что-то другое в следующий раз, когда вы измените код.

0 голосов
/ 22 января 2012

C компилятор знает размер каждого типа.например, предположим, что P является указателем типа int, который ссылается на address 0x0010.если вы добавите P на 1 (P ++ или P = P + 1), тогда значение P будет 0x0014.

По вашему вопросу переменные a и b объявлены тандемами, в physical memory они являются тандемами, а глава каждого из них имеет 4 bytes difference с другими.В этой ситуации компилятор знает, что размер int составляет 4 байта.когда вы вычитаете 2 int указатель, компилятор divide the result by 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...