Массивы не указатели.Указатели не являются массивами.
Возможно, было бы яснее сказать, что массив объекты не являются указателями объекты , и наоборот.
Когда выобъявлять int *arr
, arr
является указателем объекта.Это все, что есть;это не может быть и никогда не будет массивом.
Когда вы выполняете arr = malloc(10 * sizeof *arr);
, (если malloc()
не дает сбоя, что вы всегда должны проверять), arr
теперь указывает на intобъект.Этот объект оказывается первым элементом массива int из 10 элементов (созданного с помощью вызова malloc
).Обратите внимание, что существует такая вещь, как указатель на массив, но это не так.
Массивы, в самом реальном смысле, не являются типами первого класса в C. Вы можете создавать и манипулировать массивом.объекты, как вы можете с любым другим типом объектов, но вы редко будете иметь дело с массивом значения напрямую.Вместо этого вы будете иметь дело с элементами объекта массива косвенно, через указатели на эти элементы.А в случае с объявлением arr
, приведенным выше, вы можете выполнить арифметику с указателем на первый элемент, чтобы получить указатели на другие элементы (и у вас должен быть какой-то другой механизм, чтобы запомнить, сколько там элементов).
Любое выражение типа массива в большинстве случаев неявно преобразуется в указатель на первый элемент массива (исключения: операнд унарного оператора &
, операнд оператора sizeof
истроковый литерал в инициализаторе, используемый для инициализации массива (под) объекта).Это правило заставляет казаться так, как будто массивы и указатели взаимозаменяемы.
Оператор индексации массива []
фактически определен для работы с указателями, а не с массивами.a[b]
- это просто другой способ написания *((a)+(b))
.Если a
является именем объекта массива, он сначала преобразуется в указатель, как я описал выше.
Я настоятельно рекомендую прочитать раздел 6 comp.lang.c FAQ .(Ссылка на первую страницу, а не непосредственно на раздел 6, потому что я хотел бы призвать людей просмотреть все это.)
Я упомянул, что есть указатели на массивы.Учитывая, что int foo[10];
, &foo[0]
является указателем на int, но &foo
является указателем на весь массив.Оба указывают на одно и то же место в памяти, но они разных типов и ведут себя совершенно по-разному в арифметике указателей.