Кто-то сказал мне, что этот бит кода печатает 29. Почему это?
int *a = 17;
printf("%d", a+3);
Потому что при добавлении к указателю он добавляет размер объекта. В данном случае размер объекта 4 (sizeof(int) == 4) -- значит 17 + 3 * 4 == 29.
. Указатели на языке C не могут быть инициализированы с помощью целые значения, за единственным исключением выражения интегральной константы, которое принимает значение целого нуля. 17
не удовлетворяет этому требованию.
Ваш код недействителен. Он ничего не «печатает». Вопрос вообще не имеет смысла. Любые попытки проанализировать этот вопрос с точки зрения арифметики указателей нелепы и просто бесполезная трата времени.
6.5.16.1 Простое присвоение
Ограничения
Одно из следующих должно выполняться: 93)
- левый операнд имеет квалифицированный или неквалифицированный арифметический тип, а правый имеет арифметический тип;
- левый операнд имеет уточненную или неквалифицированную версию структуры или типа объединения совместимый с типом права;
- оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимых типов, а тип, на который указывает слева, имеет все квалификаторы типа, на который указывает right;
- один операнд является указателем на объект или неполный тип, а другой - указателем на квалифицированная или неквалифицированная версия void, а тип, на который указывает слева, имеет все квалификаторы типа, на который указывает правый:
- левый операнд является указателем, а правый - константой нулевого указателя; или
- левый операнд имеет тип _Bool, а правый - указатель.
93) Асимметричный вид этих ограничений относительно квалификаторов типа связан с преобразованием (указано в 6.3.2.1), который изменяет lvalues на «значение выражения», которое удаляет любой тип квалификаторы из категории типа выражения.
a+3 == a + (3 * sizeof(int)) == a + 12 == 17 + 12 == 29
Все знают, что ответ 23, по крайней мере на 6809.
a+3 == a + (3 * sizeof(int)) == a + 6 == 17 + 6 == 23
может распечатать что угодно ... вы устанавливаете указатель на место '17' в памяти ...
.