递归主函数分析

时间:2015-01-06 17:15:23

标签: c gcc gcc4.7

我在学习C语言面试问题时在一些网页上看过以下课程,我想知道我的分析是否正确?

 #include<stdio.h>
 #include<stdlib.h>

 void main(int j)
 {
     printf("%d\n",j);
     (&main + (&exit - &main)*(j/1000))(j+1);
 }

我的分析是,最初主要的参数是参数计数,所以首先将1打印在屏幕上,接下来有一个递归条件调用main (&main + (&exit - &main)*(j/1000))(j+1);在此{ {1}}大于&exit,因此我们在此处获得一些值,它与&main相乘意味着直到j/1000小于j 1000的值将为零,最终调用(&exit - &main)*(j/1000)函数,以便打印main中的数字。

一旦1,2,3,-----1000变为j1001的值将变为(&exit - &main)*(j/1000),地址将为(&exit - &main)*1,即(&main + &exit - &main)(j+1);函数的地址所以程序得到退出打印exit

这是我对这个程序的分析我想知道我对这个程序的分析是否正确。

3 个答案:

答案 0 :(得分:1)

程序具有未定义的行为,因为没有为函数指针定义加法operator -

此外,结果对象文件中的函数顺序未定义。

函数main也应该有返回类型int。

答案 1 :(得分:0)

j/1000仅在j >= 1000

时返回1

然后

(&main + (&exit - &main)*(j/1000))

将成为

&main + &exit - &main = &exit;

直到那时

main()将被递归调用

(j+1)作为参数

答案 2 :(得分:0)

前几天我遇到了同样的例子并且花了很多时间来理解它。我很高兴看到其他人遇到相同的例子,如果不是同一个网页:)

让我们逐行分析代码

第一行

 void main(int j)

我想如果您将上面的行更改为void main(int argc),您可能会知道j 将保持与argc完全相同的1值,因为在执行程序时不会输入任何参数 实际上main()函数中的第一个参数将始终包含输入到程序中的参数数量,包括程序名称

所以,如果我写

./exeProgram // j contains 1

j将包含1,但如果您使用额外的参数执行它  将保留2

 ./exeProgram arg1 // j contains 2

第二行

 printf("%d\n",j);

这是一个打印j值的简单指令,所以让我们转到第三行 最重要的

第三行

 (&main + (&exit - &main)*(j/1000))(j+1);

这里的声明试图再次执行main() 再次(以递归方式)执行指令 in a specific number of time

让我们看一下&main + (&exit - &main)*(j/1000)这个词: 由于(&exit - &main)*(j/1000)是一个整数而j,所以将执行的第一个术语将是1000,因此结果总是一个整数,但问题是当j成立时1 ... 99中的值< 1000 j/1000的返回值 0

所以 [1..99] 之间的j

&main + (&exit - &main)*(j/1000)变为&main + (&exit - &main)*(0) 除了&main

之外什么都没有

**

这里的问题是减去两个不指向同一个数组的指针被认为是未定义的行为!!

**

我将继续分析,因为这个想法和递归方法很好,可以在其他工作环境中使用!

现在为j=1000

&main + (&exit - &main)*(j/1000)变为&main + (&exit - &main)*(1) &main+&exit-&main&exit

所以让我们总结一下

if(j>=1 && j<=99)
&main(j) // will be executed when j<=99 and j>=1
else
&exit(j) // will be executed when j=1000

当程序达到1000值时,它将执行函数exit()并停止执行它! :)

请注意,无需在&main之前添加exit,因为函数名称始终指向其地址。