Вопрос: Но я слышал, что char a[] эквивалентно char *a.

Ответ:
Ничего подобного. (То, что Вы слышали, касается формальных параметров функций, см. вопрос 2.4.)Массивы — не указатели. Объявление массива "char a[6];" требует определенного места для шести символов, которое будет известно под именем "a". То есть, существует место под именем "a", в которое могут быть помещены 6 символов. С другой стороны, объявление указателя "char *p;" требует места только для самого указателя. Указатель будет известен под именем "p" и может указывать на любой символ (или непрерывный массив символов).

Как обычно, лучше один раз увидеть, чем сто раз услышать. Объявление
  char a[] = "hello";
  char *p = "world";

породит структуры данных, которые могут быть представлены так:
     +---+---+---+---+---+---+
  a: | h | e | l | l | o |\0 |
     +---+---+---+---+---+---+

     +-----+     +---+---+---+---+---+---+
  p: |  *------> | w | o | r | l | d |\0 |
     +-----+     +---+---+---+---+---+---+

Важно понимать, что ссылка типа х[3] порождает разный код в зависимости от того, массив х или указатель.
Если взять приведенную выше декларацию, то, когда компилятор встречается с выражением а[3], он генерирует код, позволяющий переместиться к месту под именем "a", перемещается на три символа вперед и затем читает требуемый символ.
В случае выражения p[3] компилятор генерирует код, чтобы начать с позиции "p", считывает значение указателя, прибавляет к указателю 3 и, наконец, читает символ, на который указывает указатель.
В нашем примере и a[3] и p[3] оказались равны 'l', но компилятор получает этот символ по-разному. (Смотри также вопросы 17.19 и 17.20.)
Автор: Кодт    Оценить