2012-02-19 5 views
0

Я пытаюсь понять основы программирования C и я вроде новичок в C, я не в состоянии понять, почему выход моей программы:Что означает ++ в C?

1 2 
1 1 

Очень хорошо, я понимаю, вывод первый printf(), но я, похоже, не получаю логику позади второго printf(). Почему он не может отображать 1 2?

#include <stdio.h> 

int main() 
{ 
    int a = 1, b = 2; 

    printf("%d %d\n", a, b); 
    printf("%d %d\n", a, a++); 

    return 0; 
} 
+1

http://stackoverflow.com/questions/24853/what-is-the-difference-between-i-and-i –

+1

Какой компилятор ты используешь? С GCC v4.6.2 я получаю '2 1' для второй линии! [А также с GCC v4.3.4] (http://ideone.com/6dr0H) – Johnsyweb

+4

Я удалил тег C++; это пахнет как C. Вы не должны сливать эти два. –

ответ

5

a++ является post-incrementinga. То есть значение a копируется до его возврата, а затем увеличивается.

Как я упоминал в комментариях, I get a different result to you, по причине, которую я объясняю ниже.

Если добавить printf("%d\n", a);, после последнего вызова printf() вы увидите 2, потому что a теперь увеличивается.

Если вы хотите увидеть 1 2, вы можете pre-incrementa (то есть увеличить его, а затем использовать его), но вам нужно ввести точку последовательности для этого будет гарантированно работать, потому что порядок вычисления аргументов функции является не определено стандартом, и вы хотите использовать a дважды:

printf("%d ", a); 
printf("%d\n", ++a); 

See it run!

+1

Нет, вы должны использовать два отдельных оператора 'printf', потому что порядок оценки аргументов функции не указан. Вы могли бы просто увидеть «2 2». –

+0

@ChrisLutz: Я редактировал свой ответ, вы набрали это. – Johnsyweb

2

сообщение Increment, increament после использования

#include <stdio.h> 
int main() 
    { 
     in a = 1, b = 2; 

     printf("%d %d\n", a, b); // 1 1 
     printf("%d %d\n", a, a++); // 1 1 
     printf("$d", a); // 2 
     return 0; 

     } 

Ниже Преинкремент:

#include <stdio.h> 
int main() 
    { 
     in a = 1, b = 2; 

     printf("%d %d\n", a, b); // 1 1 
     printf("%d %d\n", a, ++a); // Could Be "1 1" OR "1 2"... sequence is undefined here. 
     printf("$d", a); // 2 
     return 0; 

     } 
+4

Чтобы повторить сказанное выше: 'printf ("% d% d \ n ", a, ++ a);' - неопределенное поведение. Вероятно, вы получите «1 2» или «2 2», но все может произойти. – bames53

0

На самом деле, ++ х и х ++ приращение х таким же образом. Единственное отличие состоит в том, что ++ x возвращает ссылку на x и x ++ возвращает предыдущее значение как временное. Неверное объяснение «с добавлением после его использования».

+1

C (который, несмотря на тег C++, является тем, что действительно используется OP), не имеет ссылок. '++ x' возвращает lvalue и' x ++ 'значение rvalue, хотя использование lvalue из' ++ x' явно ужасная идея. –

+0

Независимо от того, используется ли временное время, зависит от ISA ЦП. (Да, так происходит в наши дни.) –

3

Выражение a++ принимает значение текущего значения a и в качестве побочного эффекта с шагомa на 1. экспрессирующего ++a вычисляет текущее значение a + 1, а в качестве стороны с шагом эффекта a на 1.

Если бы вы написали

a = 1; 
printf("%d\n", a++); 

вы получите выход 1, потому что вы просите за текущее значение от a. Если бы вы написали

a = 1; 
printf("%d\n", ++a); 

вы получите выход 2, потому что вы просите ценности a + 1.

Теперь, что важно помнить (особенно с ++a) является то, что побочный эффект фактически обновление a не должно произойти сразу же после того, как выражение было оценено; это должно произойти только до следующей последовательности (которая в случае вызова функции после оценивается все аргументов).

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

Заявление

printf("%d %d\n", a, a++); 

нарушает вторую часть этого ограничения, поэтому поведение этого утверждения является неопределенным. Ваш вывод может быть любой из 1 1, 1 2, в суффозии желтый и т.д.