以下是我的代码:
#include<stdio.h>
int i =5;
int main(i)
{
if(i<10)
printf(" %d\n",printf("%d",i+main(++i)));
return 0;
}
(同时在Ideone.com和Codeblocks中)
10 2
9 1
8 1
7 1
6 1
5 1
4 1
3 1
2 1
有人可以解释这个输出背后的原因吗?我期望91,81,....,51。此外,递归main()是否会导致意外输出?
PS:这是我在在线论坛中找到的一个程序。
答案 0 :(得分:4)
首先,“implict int”规则在很久以前就被取缔了。 int main(i) { ...
不是有效的函数声明。代码不能在兼容的C编译器中编译。
其次,表达式i+main(++i)
没有足够的顺序。它会导致未定义的行为。如果没有在这些操作之间进行适当的排序,则读取变量i
并在同一表达式中独立修改变量i
是非法的。在这种情况下,语言没有定义行为。
实际上,我们不知道在i
修改i+main(++i)
的值之后或之后是否会读取++i
中第一个i
的值。语言不保证它。您的i
等于1
。对于i
的值,不清楚i+main(++i)
表达式的第一次评估是否等同于1+main(2)
或2+main(2)
。这就是你的实验中发生的事情。您出于某种原因假设在i
递增之前将读取第一个i
。实际上,它以另一种方式起作用。
P.S。形式上,C语言(而不是C ++)似乎允许手动调用main
。但是,您遇到的问题与main
递归无关。
答案 1 :(得分:0)
拼图中有许多未定义的位,但printf
是输出的关键。其他人详细说明了i+main(++i)
表达式的非法性,所以让我们看看printf
来分析输出:
printf(" %d\n",printf("%d",i+main(++i)));
有两个printf
语句,其中必须首先评估printf("%d",i+main(++i))
以便向另一个语句提供输出。所以选择未定义的值并将其插入%d
。从现在开始,定义了行为。
man printf
- 返回值:
Upon successful return, these functions return the number of characters printed
鉴于第一种情况printf("%d",i+main(++i))
输出10
,打印的两个字符的返回值为2
。 2
的值传递给printf(" %d\n",..
,第一次传递的输出为:
10 2
在第二次传递中选择未定义的行为,i+main(++i)
的值为9
。 printf("%d",i+main(++i))
的回报现在是1
,给出了第二行输出:
9 1
依此类推......我无法解释未定义的10, 9, 8, ...
,但其余的都是有道理的。
答案 2 :(得分:-1)
main的参数,即变量i,假设为int,它在本地接管全局i。作为main的参数,第一次调用它时它的值为#34;参数个数&#34; +1。所以,如果你运行你的程序没有参数,第一次调用main开始于1.尝试用一些参数运行你的程序,你会得到不同的结果。
对我来说
./a.out a b c
10 2
9 1
8 1
7 1
6 1
5 1
了解评估顺序很棘手。考虑以下程序及其输出,可能会更清楚编译器正在做什么(或不做)。
#include<stdio.h>
int f(int x) {
printf("f with x = %d\n", x);
return x;
}
int g(int x) {
printf("g with x = %d\n", x);
return x;
}
int main()
{
int i;
i = 0;
printf("%d\n", f(++i) + i + g(++i));
i = 0;
printf("%d\n", (f(++i) + i) + g(++i));
i = 0;
printf("%d\n", f(++i) + (i + g(++i)));
}
输出
f with x = 1
g with x = 2
4
f with x = 1
g with x = 2
4
f with x = 1
g with x = 2
5