В чем разница между префиксными и постфиксными операторами?
Следующий код печатает значение 9. Почему? Вот return(i++)
вернет значение 11 и из-за --i
само значение должно быть 10, кто-нибудь может объяснить, как это работает?
#include<stdio.h>
main()
{
int i= fun(10);
printf("%d\n",--i);
}
int fun (int i)
{
return(i++);
}
12 ответов
Существует большая разница между постфиксной и префиксной версиями ++
,
В префиксной версии (т.е. ++i
), значение i
увеличивается, и значение выражения является новым значением i
,
В постфиксной версии (т.е. i++
), значение i
увеличивается, но значение выражения является исходным значением i
,
Давайте проанализируем следующий код построчно:
int i = 10; // (1)
int j = ++i; // (2)
int k = i++; // (3)
i
установлен в10
(легко).- Две вещи на этой линии:
i
увеличивается до11
,- Новая ценность
i
копируется вj
, Такj
теперь равняется11
,
- Две вещи на этой линии:
i
увеличивается до12
,- Первоначальная стоимость
i
(который11
) копируется вk
, Такk
теперь равняется11
,
Итак, после запуска кода, i
будет 12, но оба j
а также k
будет 11
То же самое относится и к постфиксным и префиксным версиям --
,
Префикс:
int a=0;
int b=++a; // b=1,a=1
перед присвоением значение будет увеличено.
Postfix:
int a=0;
int b=a++; // a=1,b=0
сначала присвойте значение "a" значению "b", затем увеличьте значение "a"
Функция возвращается раньше i
увеличивается, потому что вы используете оператор пост-исправления (++). Во всяком случае, прирост i
не является глобальным - только для соответствующей функции. Если бы вы использовали оператор предварительной фиксации, это было бы 11
а затем уменьшается до 10
,
Итак, вы вернетесь i
как 10 и уменьшить его в функции printf, которая показывает 9
не 10
как ты думаешь.
По факту return (i++)
вернется только 10.
Операторы ++ и - могут быть помещены до или после переменной с различными эффектами. Если они раньше, то они будут обработаны, возвращены и, по сути, будут обрабатываться точно так же, как (i-1) или (i+1), но если вы поместите ++ или - после i, то возврат будет существенно
return i;
i + 1;
Таким образом, он вернет 10 и никогда не будет увеличивать его.
Есть два примера, иллюстрирующих разницу
int a , b , c = 0 ;
a = ++c ;
b = c++ ;
printf (" %d %d %d " , a , b , c++);
- Здесь c имеет значение 0 c с шагом 1, затем присваивает значение 1 значению so
a = 1
и значениеc = 1
следующее утверждение
c = 1
б затем увеличить с на 1, так что значениеb = 1
и значениеc = 2
в
printf
заявление у нас естьc++
это означает, что оригинальное значение c, равное 2, будет напечатано, а затем увеличится на 1, так чтоprintf
заявление напечатает1 1 2
и значение с теперь 3
Вы можете использовать http://pythontutor.com/c.html
int a , b , c = 0 ;
a = ++c ;
b = c++ ;
printf (" %d %d %d " , a , b , ++c);
- Здесь в
printf
заявление++c
сначала увеличим значение c на 1, затем назначим новое значение 3 для c, такprintf
заявление напечатает1 1 3
Давайте сделаем это как можно проще.
let i = 1
console.log('A', i) // 1
console.log('B', ++i) // 2
console.log('C', i++) // 3
console.log('D', i) // 4
A) Печатает значение i B) Сначала i увеличивается, затем console.log запускается с i, поскольку это новое значение C) Console.log запускается с i в его текущем значении, тогда i будет увеличено D) Печатает значение из меня
Короче говоря, если вы используете предварительное сокращение, то есть (++i), я обновлюсь до выполнения строки. Если вы используете пост-сокращение, т.е. (i++), текущая строка будет работать так, как если бы я еще не был обновлен, тогда i увеличивается, поэтому в следующий раз, когда ваш интерпретатор перейдет через i, он будет увеличен.
Постфиксный прирост ++
не увеличивает значение своего операнда до тех пор, пока он не будет оценен. Значение i++
является i
,
Приращение префикса увеличивает значение его операнда до его оценки. Значение --i
является i - 1
,
Увеличение / уменьшение префикса изменяет значение до вычисления выражения. Постфиксный приращение / уменьшение меняет значение после.
Итак, в вашем случае, fun(10)
возвращает 10, и печать --i
печать i - 1
, что составляет 9.
i++ - постинкремент. Приращение происходит после того, как значение возвращено.
Во-первых, обратите внимание, что параметр функции с именем i
и переменная с именем i
в main()
две разные переменные. Я думаю, что это не имеет большого значения для настоящей дискуссии, но важно знать.
Во-вторых, вы используете оператор postincrement в fun()
, Это означает, что результатом выражения является значение перед i
увеличивается; конечное значение 11 из i
просто отбрасывается, и функция возвращает 10. Переменная i
обратно в main, будучи другой переменной, присваивается значение 10, которое вы затем уменьшаете, чтобы получить 9.
Объяснение:
Шаг 1: int fun(int);
Здесь мы объявляем прототип функции fun()
,
Шаг 2: int i = fun(10);
Переменная i объявляется как целочисленный тип и результат fun(10)
будет храниться в переменной i
,
Шаг 3: int fun(int i){ return (i++); }
Внутри fun()
мы возвращаем значение return(i++)
, Возвращается 10
, так как i++
является пост-инкриментным оператором.
Шаг 4: Затем управление возвращается к основной функции и значение 10
присваивается переменной i
,
Шаг 5: printf("%d\n", --i);
Вот --i
Обозначается предварительным сносом. Следовательно, он печатает значение 9
,
Это связано с тем, как работает оператор постинкремента. Возвращает значение i, а затем увеличивает его.
На самом деле, когда вы используете postfix, т.е. i ++, для возврата используется начальное значение i, а не увеличенное. После этого значение i увеличивается на 1. И это происходит с любым оператором, использующим i ++, т.е. сначала в выражении используется начальное значение i, а затем оно увеличивается.
И полная противоположность происходит в префиксе. Если бы вы вернули ++ i, то возвращается увеличенное значение, т.е. 11, потому что сначала добавляется 1, а затем возвращается.
fun(10) возвращает 10. Если вы хотите, чтобы он возвращал 11, тогда вам нужно использовать ++i, а не i++.
int fun(int i)
{
return ++i;
}