问题描述
这是用C写的可以在一个Hello World程序任何人都请提供它是如何工作的解释?
原来的code(语法高亮故意丢失):
INT I;主要(){为(;我[]<我;我++){ - 我;}];阅读('-'-'-',我+++地狱\\
!0,世界\\ n,'/'/'/'));}读取(J,I,P){写(J / P + P,I --- J,I / I);}
稍微干净:
INT I;
主要()
{
为(;我[]<我;我++){ - 我;}];阅读(' - ' - ' - ',我+ +你好,世界\\ n!,'/'/'/'));
}读(J,I,P)
{
写(J / P + P,我 - - J,I / I);
}
的循环条件
I []<我;我++){ - 我;}]
这前pression发生的事实,即数组索引是可交换的C.它相当于优势。
<我;我++){ - 我;}[I]
所以循环将结束时,在位置的字符 I
是 \\ 0
,即在年底字符串,这是14个字符长的(这恰好是相同的长度,你好,世界!\\ n)。因此,为
循环条件可以改写为:
我!= 14
字符运算
阅读(' - ' - ' - ',我+ +!你好,世界\\ n,'/'/'/')
字符
是一个整数类型,因此:
-
- - -
0 -
'/'/'/'
1阅读(0,I + +你好,世界!\\ n,1)
固定所有的编译器警告(如隐含的int指针转换),并简化上述事情之后,code变为:
的#include<&unistd.h中GT;INT I = 0;无效READ2(INT,CHAR *,INT);诠释的main()
{
同时,(我!= 14)
{
READ2(0,I + +你好,世界\\ n!,1);
} 返回0;
}无效READ2(诠释J,字符*我,诠释P)
{
写(焦耳/ P + P,我 - - J,1);
}
(我改名读
到 READ2
来避免与UNIX 读冲突的code>功能。)
请注意,Ĵ
和 P
参数 READ2
是不需要的,因为该功能总是被其中j = 0且p称为= 1
的#include<&unistd.h中GT;INT I = 0;无效READ2(字符*);诠释的main()
{
同时,(我!= 14)
{
READ2(我+ +你好,世界\\ n!);
} 返回0;
}无效READ2(字符* I)
{
写(1,我 - ,1);
}
呼叫写(1,我 - ,1)
从写1个字符我
文件描述符1 (标准输出)。而且是后减多余的,因为这 I
是永远不会再次引用的局部变量。所以这个函数等同于的putchar(* I)
。
主循环内内联 READ2
函数给出
的#include<&stdio.h中GT;INT I = 0;诠释的main()
{
同时,(我!= 14)
{
的putchar(*(我+ +你好,世界\\ n!));
} 返回0;
}
有关其意义是显而易见的。
This classic ioccc entry is a Hello World program written in C. Can anyone please provide an explanation of how it works?
Original code (syntax highlighting intentionally missing):
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\ o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
Slightly cleaner:
int i;
main()
{
for ( ; i["]<i;++i){--i;}"]; read('-' - '-', i++ + "hello, world!\n", '/' / '/'));
}
read(j, i, p)
{
write(j / p + p, i-- - j, i / i);
}
for loop condition
i["]<i;++i){--i;}"]
This expression takes advantage of the fact that array indexing is commutative in C. It is equivalent to.
"]<i;++i){--i;}"[i]
So the loop will terminate when the character at position i
is \0
, i.e., at the end of the string, which is 14 characters long (which happens to be the same length as "hello, world!\n"). So the for
loop condition can be rewritten as:
i != 14
character arithmetic
read('-' - '-', i++ + "hello, world!\n", '/' / '/')
char
is an integer type, and thus:
'-' - '-'
is 0'/' / '/'
is 1read(0, i++ + "hello, world!\n", 1)
After fixing all the compiler warnings (like implicit int to pointer conversion), and simplifying the things mentioned above, the code becomes:
#include <unistd.h>
int i = 0;
void read2(int, char*, int);
int main()
{
while (i != 14)
{
read2(0, i++ + "hello, world!\n", 1);
}
return 0;
}
void read2(int j, char* i, int p)
{
write(j / p + p, i-- - j, 1);
}
(I renamed read
to read2
to avoid conflicting with the Unix read
function.)
Note that the j
and p
arguments to read2
are unneeded, as the function is always called with j=0 and p=1.
#include <unistd.h>
int i = 0;
void read2(char*);
int main()
{
while (i != 14)
{
read2(i++ + "hello, world!\n");
}
return 0;
}
void read2(char* i)
{
write(1, i--, 1);
}
The call write(1, i--, 1)
writes 1 character from i
to file descriptor 1 (stdout). And the postdecrement is superfluous because this i
is a local variable never referenced again. So this function is equivalent to putchar(*i)
.
Inlining the read2
function within the main loop gives
#include <stdio.h>
int i = 0;
int main()
{
while (i != 14)
{
putchar(*(i++ + "hello, world!\n"));
}
return 0;
}
for which the meaning is obvious.
这篇关于面试的Hello World解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!