Поскольку массивы являются , а не указателями. Они могут распадаться на указатели при определенных обстоятельствах (таких как передача функции, как вы можете видеть в своем коде), но, хотя они остаются массивом, вы не можете увеличивать их.
Что вы можете сделать, чтобы создать указатель из массива, например, изменив:
foo(a);
до:
foo(&(a[1]));
, который будет передавать явный указатель на второй символ вместо неявного указателя на первый символ, который происходит с foo(a);
.
Раздел 6.3.2.1 C99 («Значения, массивы и обозначения функций»), пункт 3 имеет окончательную причину, по которой вы не можете делать то, что пытаетесь сделать:
За исключением случаев, когда это операнд оператора sizeof
или унарный оператор &
, или
строковый литерал, используемый для инициализации массива; выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», которое указывает на начальный элемент объекта массива и не является lvalue.
Это то, что "не lvalue" останавливает вас. Вы не можете изменить его, если оно не lvalue (так названо, потому что они обычно появляются слева от операторов присваивания).
Причина, по которой вы можете выполнять свою первую функцию, заключается в разделе 6.7.5.3 («Объявление функций»), параграф 7:
Объявление параметра в виде «массива типа» должно быть скорректировано на «квалифицированный указатель на тип»
Другими словами, параметр в функции является указателем lvalue, который можно изменить.