如何在C code,它从1打印到1000没有循环或条件语句工作? [英] How does the C code that prints from 1 to 1000 without loops or conditional statements work?
问题描述
我发现 C
code的<一个href=\"http://stackoverflow.com/questions/4568645/printing-1-to-1000-without-loop-or-conditionals/4583502#4583502\">prints从1到1000,而不循环或条件的:
但我不明白它是如何工作的。任何人都可以顺利通过code和解释每行?
的#include&LT;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;无效的主要(诠释J){
的printf(%d个\\ N,J);
(安培;主+(安培;出口 - &安培;主)*(J / 1000))(J + 1);
}
永远不要写code类的。
有关 J&LT; 1000
,焦耳/ 1000
是零(整数除法)。所以:
(安培;主+(安培;出口 - &安培;主)*(J / 1000))(J + 1);
相当于:
(安培;主+(安培;出口 - &安培;主)* 0)(J + 1);
这是:
(安培;主)(J + 1);
其中要求主
与 J + 1
。
如果Ĵ== 1000
,那么同样的思路出来的:
(安培;主+(安培;出口 - &安培;主)* 1)(J + 1);
这可以归结为
(安培;出口)(J + 1);
这是退出(J + 1)
并保留节目。
(安培;出口)(J + 1)
和退出(J + 1)
基本上是相同的东西 - 报价C99§6.3.2.1/ 4:
一个函数标志是具有函数型的前pression。除非它是
sizeof操作符的操作数的或一元和放大器;运营商的,功能与标志
键入函数返回类型转换为具有输入指向一个前pression
函数返回类型
块引用>
退出
是函数标志。即使没有一元&安培;
地址的运营商,它被视为一个函数指针。 (在&放大器;
只是使它显式)和函数调用在§6.5.2.2/ 1和描述如下:
这表示调用的函数应具有类型前pression 函数指针返回void或大于一个数组类型返回其他的对象类型。
块引用>所以
退出(J + 1)
工作,因为函数类型的指针到函数类型的自动转换,而( &安培;出口)(J + 1)
的作品,以及用显式转换为指针,以功能型话虽这么说,上面的code为不符合(
主
从以下两个参数或根本没有),而&安培;退出 - &放大器;主
根据§6.5.6/ 9,我相信,不确定的:
当两个指针相减,应都指向同一个数组对象,或者一个过去的数组对象的最后一个元素的元素; ...
块引用>加法
(&放大器;主+ ...)
将本身有效的,并且可以使用,如果的量加入是零,因为§6.5.6/ 7说:
有关这些操作符的目的,一个指向的对象是不是一个一个元件
阵列的行为相同的指针长度的一个的阵列与第一元件
类型对象作为其元素的类型。
块引用>所以加入零到
&放大器;主
将是确定(但没有太大用处)I've found
C
code that prints from 1 to 1000 without loops or conditionals : But I don't understand how it works. Can anyone go through the code and explain each line?#include <stdio.h> #include <stdlib.h> void main(int j) { printf("%d\n", j); (&main + (&exit - &main)*(j/1000))(j+1); }
解决方案Don't ever write code like that.
For
j<1000
,j/1000
is zero (integer division). So:(&main + (&exit - &main)*(j/1000))(j+1);
is equivalent to:
(&main + (&exit - &main)*0)(j+1);
Which is:
(&main)(j+1);
Which calls
main
withj+1
.If
j == 1000
, then the same lines comes out as:(&main + (&exit - &main)*1)(j+1);
Which boils down to
(&exit)(j+1);
Which is
exit(j+1)
and leaves the program.
(&exit)(j+1)
andexit(j+1)
are essentially the same thing - quoting C99 §6.3.2.1/4:A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
exit
is a function designator. Even without the unary&
address-of operator, it is treated as a pointer to function. (The&
just makes it explicit.)And function calls are described in §6.5.2.2/1 and following:
The expression that denotes the called function shall have type pointer to function returning void or returning an object type other than an array type.
So
exit(j+1)
works because of the automatic conversion of the function type to a pointer-to-function type, and(&exit)(j+1)
works as well with an explicit conversion to a pointer-to-function type.That being said, the above code is not conforming (
main
takes either two arguments or none at all), and&exit - &main
is, I believe, undefined according to §6.5.6/9:When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; ...
The addition
(&main + ...)
would be valid in itself, and could be used, if the quantity added was zero, since §6.5.6/7 says:For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
So adding zero to
&main
would be ok (but not much use).这篇关于如何在C code,它从1打印到1000没有循环或条件语句工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!