Не понимаю, почему while (* ptr ++) введите while l oop для значения 0 (ограничитель строки) - PullRequest
1 голос
/ 24 января 2020

У меня проблема с приведенным ниже тривиальным примером кода: (в Visual Studio 2015)

Пожалуйста, игнорируйте часть, указав на буквальную константу, возможные предупреждения или ошибки в компиляторе newwer, который не является чего я не понимаю.

Моя проблема в том, почему он печатает '0' и как работает l oop, пытаясь использовать отладчик и printf. Мое понимание проблемы заключается в следующем:

  1. перемещает ptr для указания на 'e'

  2. проверяет содержимое ptr, которое является 'e' it не 0, поэтому он входит, пока l oop

  3. возвращается к строке условия, перемещает ptr в 'l'
  4. проверяет * ptr, это не 0, входит ... бла-бла для букв l, o

Затем он увеличивает ptr после 'o' и получает '\ 0', после чего по моим логикам c он НЕ должен входить в l oop , но я делаю, и больше не входит после еще одного шага, когда он указывает на терминатор на мусор?!?

Я просмотрел 2 другие темы, эту топику c о приоритете оператора и это случай с while (* ptr), проходящим через терминатор , но я не понимаю из второго ПОЧЕМУ он входит в l oop, а потом увеличивает значение указателя? для того, что я понимаю, порядок - сначала увеличить указатель, затем получить значение с помощью *

#include <cstdio>
#include<stdlib.h>

int main(void) {
    char* str = "hello";
    char* ptr = str;
    char least = 127;
    while (*ptr++) {
        printf("%c-", *ptr);
        least = ((*ptr) < (least)) ? (*ptr) : (least);
    }
    printf("%d\n", least);
}

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Внутри l oop вы не используете тот же символ, который вы тестировали в условии while.

Так как ptr++ является постинкрементом, возвращается текущее значение ptr и затем увеличивает его. Поэтому, когда ptr указывает на символ o, а вы делаете

while (*ptr++)

, он проверяет 'o', который не равен нулю, поэтому он вводит l oop. Но после теста он увеличивает ptr, чтобы указать на следующий символ, поэтому теперь он указывает на '\0'. Затем он печатает этот символ и устанавливает least.

Вы должны увеличить указатель после обработки . Вы можете сделать это, переместив ptr++ в конец тела l oop. Или вы можете использовать for l oop вместо while:

for (ptr = str; *ptr; ptr++)
0 голосов
/ 24 января 2020

Последний вызов printf выводит конечный ноль строкового литерала в виде целого числа.

Для ясности рассмотрим строковый литерал с одним действительным символом, например "A".

Перед первой итерацией while l oop

while (*ptr++)
{
    printf("%c-", *ptr);
    least = ((*ptr) < (least)) ? (*ptr) : (least);
}

указатель ptr указывает на символ 'A' строкового литерала. Это выражение

*ptr++

можно представить как

char c = *ptr;
++ptr;

Таким образом, управление переходит к телу l oop, потому что 'A' не равно нулю. Тем временем указатель ptr был увеличен после оценки состояния. Так что теперь он указывает на завершающий ноль '\ 0' строкового литерала.

Так как 0 меньше 123, тогда переменная меньше всего получает значение 0.

    least = ((*ptr) < (least)) ? (*ptr) : (least);

В следующем итерация l oop ptr по-прежнему указывает на конечный ноль. Таким образом, элемент управления обходит тело l oop, и ноль выводится в следующем операторе после l oop.

из стандарта C (6.5.2.4 Операторы приращения и уменьшения после записи)

2 Результатом оператора post-x ++ является значение операнда . Как побочный эффект, значение объекта операнда увеличивается (то есть к нему добавляется значение 1 соответствующего типа).

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