Арифметика указателя с массивом char в c - PullRequest
2 голосов
/ 21 февраля 2011

Почему, если я увеличиваю строку массива, я получаю сообщение об ошибке, а если я передаю значение функции, я могу заставить ее работать? Объект строкового массива уже не является указателем на элементы массива?

, например

void foo(char *a){
    printf("%c", *a);
    a++; // this works
    printf("%c", *a);
}

int main(){
    char a[] = "ciao";
    a++; // I get the error
    foo(a);
    return 1;
}

спасибо!

Ответы [ 3 ]

7 голосов
/ 21 февраля 2011

Поскольку массивы являются , а не указателями. Они могут распадаться на указатели при определенных обстоятельствах (таких как передача функции, как вы можете видеть в своем коде), но, хотя они остаются массивом, вы не можете увеличивать их.

Что вы можете сделать, чтобы создать указатель из массива, например, изменив:

foo(a);

до:

foo(&(a[1]));

, который будет передавать явный указатель на второй символ вместо неявного указателя на первый символ, который происходит с foo(a);.

Раздел 6.3.2.1 C99 («Значения, массивы и обозначения функций»), пункт 3 имеет окончательную причину, по которой вы не можете делать то, что пытаетесь сделать:

За исключением случаев, когда это операнд оператора sizeof или унарный оператор &, или строковый литерал, используемый для инициализации массива; выражение с типом «массив типа» преобразуется в выражение с типом «указатель на тип», которое указывает на начальный элемент объекта массива и не является lvalue.

Это то, что "не lvalue" останавливает вас. Вы не можете изменить его, если оно не lvalue (так названо, потому что они обычно появляются слева от операторов присваивания).

Причина, по которой вы можете выполнять свою первую функцию, заключается в разделе 6.7.5.3 («Объявление функций»), параграф 7:

Объявление параметра в виде «массива типа» должно быть скорректировано на «квалифицированный указатель на тип»

Другими словами, параметр в функции является указателем lvalue, который можно изменить.

2 голосов
/ 21 февраля 2011

Тип вашего foo's a - это указатель, который вы можете увеличивать.

Тип вашего основного a - это массив, который вы не можете увеличивать.

Когда вы вызываете foo,адрес вашего массива передается как новая переменная типа указателя.Вы можете увеличить это значение, не затрагивая оригинал.

1 голос
/ 21 февраля 2011

Вы можете попробовать определить a следующим образом:

char* a = "ciao";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...