Инкрементные указатели в C ++ - PullRequest
1 голос
/ 11 мая 2011

Почему два следующих сегмента кода не эквивалентны?

void print (char* s) {
  if (*s == '\0')
     return;
    print(s+1);
   cout << *s;
}

void print (char* s) {
  if (*s == '\0')
     return;
    print(++s);
   cout << *s;
}

Ответы [ 4 ]

7 голосов
/ 11 мая 2011

Оператор ++ увеличивает значение указателя, но затем возвращает исходное значение ... так что print(s++) будет печатать значение s до приращения, поскольку даже если оно добавляет значение от 1 до s, делая значение, хранящееся в s равным s+1, оно все равно возвращает исходное значение s в качестве результата операции. С другой стороны, print(s+1) печатает значение после приращения, но, что очень важно, не изменяет исходное значение s. Таким образом, результат оператора s+1 - это просто новое временное значение указателя ... исходное значение s не изменяется.

Более того, поскольку вы увеличили и изменили значение s с помощью оператора ++, когда вы вызываете cout, вы теперь печатаете значение там, куда указывает новый указатель (это может привести к сбой или ошибка сегментации, если вы неосторожны и в новой ячейке памяти нет доступной пользователю памяти, на которую указывает s). При s+1 значение s остается неизменным, поэтому результат cout будет таким, куда первоначально указывал s.


Edit:

Как указывает Майкл, это на самом деле рекурсивная функция, поэтому второй пример просто продолжает вызывать print() с тем же аргументом, поскольку, как уже упоминалось ранее, возвращаемое значение из s++ является исходным значением s , Это означает, что в какой-то момент вы получите переполнение стека и просто произойдет сбой, если только значение, на которое указывает s, уже не является символом NULL.

1 голос
/ 11 мая 2011

Так как похоже, что ОП изменилось print(s++) на print(++s), что сильно отличается, вот объяснение этой новой версии.

В первом примере у вас есть:

print(s+1);
cout << *s;

s + 1 не изменяет s.Таким образом, если s равно 4, а вы print(s+1), впоследствии s все равно будет 4.

print(++s);
cout << *s;

В этом случае ++ s изменяет локальное значение s.Это увеличивает его на 1. Поэтому, если это было 4 до print(++s), это будет 5 после.

В обоих случаях значение, эквивалентное s + 1, будет передано вфункция print, заставляющая печатать следующий символ.

Таким образом, разница между двумя функциями заключается в том, что первая будет рекурсивно печатать символ # 0, затем 1, 2, 3, ..., а втораяфункция печатает 1, 2, 3, 4, ... (пропускает первый символ и затем печатает «\ 0»).

Пример:
Для версии s+1, print("hello")приведет к h e l l o
Для версии ++s, print("hello") приведет к e l l o \0

1 голос
/ 11 мая 2011
  1. Оба выражения s++ и s+1 относятся к увеличению позиции самого указателя, а не к значению, содержащемуся в позициях указателя

  2. Значение s++ равно s, а значение s+1 на одну позицию дальше, чем s!

  3. Значение s послевыполнение s++ на одну позицию дальше, чем было раньше.После использования s+1 значение s остается неизменным.

Поэтому порядок, в котором они печатают буквы, меняется на обратный!

0 голосов
/ 11 мая 2011

Я попытаюсь объяснить пример до и после приращения, из которого вы можете решить вопрос, размещенный самостоятельно.

#include <iostream>

void foo(int num)
{
    std::cout << num << "\n" ;
}

int main()
{
    int number = 10 ;

    foo( number++ ) ;
    foo( ++number ) ;
    foo( number + 1 ) ;

    getchar() ;

    return 0 ;
}

Выход:

10
12
13

Почему 10?

foo( number++ ) ;

Постинкремент операция выполняется для число . Это означает, что значение число сначала передается в foo, а затем значение число увеличивается при возврате foo. Таким образом, после возврата функции число равно 11.

Почему 12?

foo( ++number ) ;

Предварительное увеличение Операция выполняется для число . Это означает, что даже перед вызовом foo значение number увеличивается до 12. А затем оно передается foo. Таким образом, даже после возврата функции число по-прежнему равно 12.

Почему 13?

Это просто прямо вперед. Значение число не изменяется, но передается значение, добавляющее 1 к значению число . В этом процессе число не изменяется. Таким образом, даже после возврата функции число по-прежнему равно 12.

Надеюсь, что это поможет решить проблему самостоятельно (хотя в вашем случае это упражнение карандашом):)

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