Арифметика указателя C на символах - PullRequest
1 голос
/ 28 февраля 2011

У меня следующий код, который вылетает в строке, где я инициализирую ch:

    char * p = "Test";
    char ch = *p++;
    printf("Here : %s\n%c", p, ch);

Однако следующий код не имеет проблем:

    char * p = "Test";
    char ch = *p++;
    ch++;
    printf("Here : %s\n%c", p, ch);

Ответы [ 5 ]

5 голосов
/ 28 февраля 2011

В первой ситуации вы пытаетесь изменить T в строке «Test», скомпилированной в программу, которая содержится в той части памяти, которую ваш код не должен изменять (обычно;В некоторых средах это разрешено, но обычно это не так).Это потому, что (*p)++ означает (условно говоря) *p = *p + 1 (например, получить символ, на который указывает p, увеличить его и записать обратно), и, конечно, *p указываетк скомпилированному «Test».

Ваша вторая версия не имеет этой проблемы, потому что вы увеличиваете ch, который вам разрешено изменять .Ваша вторая версия фактически увеличивает две разные вещи;сначала он делает char ch = *p++;, который получает символ в *p, а затем увеличивает p (теперь он указывает на «e» в «Тесте»), а затем вы делаете ch = ch++.(Вы, вероятно, имели в виду просто ch++;, поскольку ++ работает непосредственно со своим операндом.)

4 голосов
/ 28 февраля 2011

Проблема сводится к приоритету оператора и использованию скобок ().

char ch = (*p)++;

Эта строка будет (пытаться) увеличивать символ по адресу, сохраненному в p

char ch = *p++;

Этот параметр устанавливает ch равным символу по адресу, сохраненному в p, затем увеличивает адрес, сохраненный в p.Оператор ++ имеет приоритет над оператором разыменования указателя, поэтому он будет выполнен первым.Чтобы было понятно, вторая строка эквивалентна:

char ch = *(p++);
1 голос
/ 28 февраля 2011

Этот код:

(*p)++

пытается увеличить значение, на которое указывает p.p указывает на строку константных символов "Test", которую нельзя изменить.

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

Ваш первый пример увеличивает значение на *p. Поскольку p указывает на строковую константу, это не допускается многими компиляторами.

Ваш второй пример увеличивает указатель, а не значение, на которое он указывает.

0 голосов
/ 28 февраля 2011

Первая версия делает это:

char * p = "Test";  //this should really be const char *
*p = *p + 1;  //CRASH! attempthing to modifiy the contents of a string literal
char ch = *p;
ch = ch++;  //This is excessive, ch++ on it's own would do the same
printf("Here : %s\n%c", p, ch);

Пока вторая версия делает это:

char * p = "Test"; //still should be const char *
char ch = *p;
p++; //p now points to "est"
ch = ch++;
printf("Here : %s\n%c", p, ch);  //prints est\nU
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...