Что не так с этим примером со строковым литералом? - PullRequest
0 голосов
/ 21 ноября 2018

Я читаю ответ с этого сайта, который говорит, что следующее не определено

char *fubar = "hello world";
*fubar++; // SQUARELY UNDEFINED BEHAVIOUR!

, но разве сначала не делается fubar++, что означает перемещение указателя на e, иЗатем выполняется *(), что означает извлечение e из.Я знаю, что это должно быть задано в чате (я добрый человек), но там никого нет, поэтому я прошу здесь, чтобы привлечь внимание.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Показанный код явно не неопределенное поведение, так как *fubar++ в некоторой степени равен char result; (result = *fubar, fubar++, result), то есть он увеличивает указатель, а не разыменованное значение, и результатом выражения является(разыменование) значение *fubar до увеличения указателя.*fubar++ фактически дает вам значение символа, на которое изначально указывает fubar, но вы просто не используете этот «результат» и игнорируете его.

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

char *fubar = "hello world";
(*fubar)++;

Это потому, что это увеличивает значение, на которое указывает fubar, и тем самым манипулирует строковым литералом -> неопределенное поведение.

При замене строкилитерал с массивом символов, затем все снова в порядке:

int main() {

    char test[] = "hello world";
    char* fubar = test;
    (*fubar)++;
    printf("%s\n",fubar);
}

Вывод:

iello world
0 голосов
/ 21 ноября 2018

Расположение ++ является ключом: если это суффикс (как в этом случае), то приращение происходит после .

Также из-за приоритета оператора вы увеличиваете указатель .

Так что получается, что указатель fubar является разыменованием (в результате 'h', который затем игнорируется), а затем переменной указателя fubar увеличивается, чтобы указывать на 'e'.

Короче говоря: *fubar++ в порядке и действителен.

Если это было (*fubar)++, тогда это было бы неопределенным поведением, с тех порон будет пытаться увеличить первые символы строки.И литеральные строки в C являются массивами только для чтения символов, поэтому попытка изменить символ в литеральной строке будет неопределенным поведением .


.выражение *fubar++ по существу равно

char *temporary_variable = fubar;
fubar = fubar + 1;
*temporary_variable;  // the result of the whole expression
...