Как отмечалось в комментариях и в ближайшее дубликата вопрос (Is this undefined behaviour in C? If not, predict the output logically.), результаты от обоих этих программы не полностью определены стандартом C - они производят «неуказанное поведение», потому что порядок оценки терминов в заявлении return
первого и printf()
во втором не указывается языком и по прихоти компилятор. (Обратите внимание, что это «неопределенное поведение», а не «неопределенное поведение», а не формальное «неопределенное поведение» - см. Обсуждение в комментариях. Это не «поведение, определяемое реализацией», но реализация не требуется для документирования того, что он делает.)
Это означает, что результаты, данные любой реализацией, являются «специфическими для реализации» в терминах вопроса. Различные реализации могут законно давать разные ответы.
Первая программа:
#include <stdio.h>
int f(int *a,int *b,int c) {
if(c == 0) return 1;
else {
*a = *a + 1;
*b = *b - 1;
c = c - 1;
return (*a + f(a,b,c) + *b);
}
}
int main() {
int a = 3,b = 3,c = 3;
printf("%d\n",f(&a,&b,c));
return 0;
}
Проблематика часть return (*a + f(a,b,c) + *b);
потому, что *a
может быть оценена до или после того, как вызов рекурсивной функции, и f()
изменяет значения, которые a
и b
точка поэтому порядок оценки вопросы. Различные компиляторы могут законно производить разные результаты. Один и тот же компилятор может производить разные результаты в разное время или под разными флагами оптимизации или по своему выбору. И *a
, и *b
могут быть оценены перед вызовом, или после вызова, либо либо можно было бы оценить раньше, а другое после - и это просто называет 4 правдоподобных альтернатива.
Вторая программа:
#include <stdio.h>
int f(int *x,int *y,int *z) {
*x = *x + 1;
*y = *y + 1;
*z = *z + 1;
return 0;
}
int main() {
int a=0,b=0,c=0;
printf("%d %d %d\n",a,f(&a,&b,&c),b);;
return 0;
}
Проблема в том, что последовательность, в которой a
, f(&a, &b, &c)
и b
оцениваются для вызова printf()
не определяется стандартом, и вы получите разные результаты в зависимости от последовательность, выбранная компилятором. Вы показали, что GCC и Clang дают разные результаты - оба этих результата приемлемы в соответствии со стандартом, и так много других.
См. Также [Является ли это неопределенным поведением в C? Если нет, прогнозируйте вывод логически.] (Http://stackoverflow.com/questions/41775973) и (если вы пользователь 10K) [Как работает данный код C?] (Http://stackoverflow.com/ вопросы/41775508/how-the-given-c-code-works) - теперь удалены. –
Обе программы зависят от порядка, в котором термины выражений оцениваются, и этот порядок не санкционирован стандартом C. Во втором примере допустимы результаты как от GCC, так и от Clang; их даже довольно легко объяснить. Но вы не можете рассчитывать на получение результата - или даже на получение одного из двух результатов (возможны и другие результаты). –
Вы получили и приняли ошибочные ответы. –