5

Как объяснить выход кода ниже:C - выходное описание printf ("% d% d n", k = 1, k = 3);

include <stdio.h> 

int main(void) { 
    int k; 
    printf("%d %d\n",k=1,k=3); 
    return 0; 
} 

Ideone Link

Мое мышление было то, что 1 будет назначен k переменной, а затем 1 будет напечатан. Аналогично 3 будет назначен k, а выход будет 3.

Ожидаемый выход

1 3 

Фактический выход

1 1 

Я экстраполяцией

int a; 
if (a = 3) { 
    ... 
} 

равно

if (3) { 
    ... 
} 

Пожалуйста, дайте мне знать, где я буду не так?

+0

@CinCout К сожалению, я заметил это позже. –

ответ

7

Проблема в том, что порядок оценки аргументов функции не определен, и нет никакой точки последовательности между оценкой или аргументами. Таким образом, это утверждение

printf("%d %d\n",k=1,k=3) 

undefined behavior вызывает, как вы пытаетесь изменить ту же переменную несколько раз без точки последовательности между ними.

Как только запускается программа, вызывающая UB, и (если) есть выход, это никак не может быть оправдано, выход может быть любым.

+1

Это нормально, одно задание напечатает значение 'k', т. Е. 3. –

+0

Я думаю, что этот ответ неверен http://stackoverflow.com/a/9514591/5473170. Вы можете проверить это. –

+0

@SurajJain Это не лучший, но выглядит хорошо. Почему это было неправильно? –

-4

Я ожидаю, что причина, по которой вы видите 1 1, состоит в том, что два оператора присваивания выполняются, управление передается printf.

printf("%d %d\n",k=1,k=3); 

Таким образом, в ответ на понижающий голосов, да, это это неопределенное поведение, и поэтому вы не должны рассчитывать на такое поведение продолжается. Однако с точки зрения определения, почему выход был 1 1, а не 1 3, мы могли заключить, что назначение 3 могло быть опрокинуто последующим присвоением 1.

Когда вызывается printf, стек вызовов содержит две записи, содержащие окончательное значение k, которое равно 1.

Вы можете проверить это, заменив их функцией, которая что-то печатает, когда она выполняется.

Пример кода:

#include <stdio.h> 

int test(int n) { 
    printf("Test(%d)\n", n); 
    return n; 
} 

int main(void) { 
    int k; 
    printf("%d %d\n",k=test(1), k=test(3)); 
    return 0; 
} 

Выход:

Test(3) 
Test(1) 
1 1 
+0

Это плохое объяснение по гораздо более надуманной причине –

+1

@ q.Then Poor - это мягкое слово, это неправильно. –

+0

Мне действительно любопытно, как мое объяснение неверно. Является ли аргумент просто множественным присвоением UB? – Scovetta