Я пытаюсь что-то очень простое, должно быть, просто, но это как-то портит меня …
Я пытаюсь понять влияние ++ на массивы, когда они рассматриваются как указатели и указатели, когда рассматриваются как массивы.
Так,
int main()
{
int a[4] = { 1, 4, 7, 9 };
*a = 3;
*(a+1) = 4;
*++a = 4; //compiler error
}
1: Так что в *(a+1)=4
мы устанавливаем [1] = 4; //Счастливый
Но когда *++a = 4;
Я бы ожидал, что указатель a будет увеличен на единицу, поскольку ++ предшествует *, а затем * запускается, и мы устанавливаем его равным 4. Но этот код просто не работает … Почему это так?
Другая проблема:
int main()
{
int* p = (int *)malloc(8);
*p = 5;
printf("%d", p[0]);
*++p = 9; //now this works!
printf("%d", p[1]); //garbage
printf("%d", p[0]); //prints 9
}
2: Сейчас * ++ p = 9; работает нормально, но на самом деле не ведет себя как массив. Как два разных? Это просто увеличивает p и делает его равным 9. Если я печатаю p [0], он теперь печатает 9, и я вижу, что, хотя больше не могу получить к нему доступ через p [0], * (p-1) показывает 5 все еще там. Так что индексируя указатель с помощью [0], куда именно он указывает? Что изменилось?
Большое спасибо всем экспертам!
Имена массивов не изменяются lvalue, поэтому операция ++ не применяется, следовательно ++a
которые пытаются изменить a
ошибка времени компиляции (где a
это имя массива).
Заметка *(a + 1)
а также *a++
не такие же, a + 1
является действительной инструкцией, так как просто добавить 1
но не модифицирует a
сама, тогда как ++a
(это эквивалентно a = a + 1
) попробуйте изменить отсюда ошибку.
Обратите внимание, что «имена массивов» не указатель. Указатели являются переменными, а имена массивов — нет. Конечно, когда вы присваиваете имя массива указателю, то в большинстве выражений имена массивов переходят в адрес первого элемента. например
int *p = a;
Заметка p
указывает на первый элемент массива (a[0]
).
Читать некоторые исключения, когда имя массива не затухает в указателе на первый элемент?
Выражение a[i]
эквивалентно *(a + i)
, где a
может быть указателем или именем массива. Следовательно, в вашем втором примере p[i]
является допустимым выражением.
Дополнительно, *++p
действует, потому что, потому что p
это указатель (переменная) во втором примере кода.
int a[4] = { 1, 4, 7, 9 };
int *pa=a;
Существует одно различие между именем массива и указателем, которое необходимо учитывать. Указатель является переменной, поэтомуpa=a
а также pa++
законны Но имя массива не является
переменная; такие конструкции, как a=pa
а также a++
незаконны
int* p = (int *)malloc(8);
Не приводить результат malloc ()
Использовать индекс с указателем
p[1]=9; // p[1]==*(p+1)