我找到了C
个代码,prints from 1 to 1000 without loops or conditionals个:
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
我找到了C
个代码,prints from 1 to 1000 without loops or conditionals个:
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
对于j<1000
,j/1000
是零(整数除法).因此:
(&main + (&exit - &main)*(j/1000))(j+1);
相当于:
(&main + (&exit - &main)*0)(j+1);
即:
(&main)(j+1);
它用j+1
打main
.
如果为j == 1000
,则相同的行将显示为:
(&main + (&exit - &main)*1)(j+1);
这可以归结为
(&exit)(j+1);
这是exit(j+1)
并且离开了程序.
(&exit)(j+1)
和exit(j+1)
本质上是一样的——引用C99§6.3.2.1/4:
函数指示符是具有函数类型的表达式.除非是在
exit
是一个函数指示符.即使没有运算符的一元&
地址,它也被视为指向函数的指针.(&
只是明确了这一点.)
和函数调用在§6.5.2.2/1及以下说明:
表示被调用函数的表达式应具有返回void或返回数组类型以外的对象类型的类型pointer to function.
因此,exit(j+1)
可以工作,因为函数类型可以自动转换为指向函数的指针类型,而(&exit)(j+1)
也可以与显式转换为指向函数类型的指针一起工作.
也就是说,上面的代码是不一致的(main
要么接受两个参数,要么根本没有参数),我认为根据§6.5.6/9,&exit - &main
是未定义的:
当减go 两个指针时,数组对象的最后一个元素之后为both shall point to elements of the same array object或1;.
由于§6.5.6/7规定:
在这些运算符中,指向不是
因此,将0添加到&main
是可以的(但没有多大用处).