Since original code was removed from the question and reformatted one been substituted instead, i start with the code as it was given by the topic starter.
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);}
Start with recovering the structure. Add spaces and line breaks where they belong to. Remember that C assumes int
data type when not specified.
int i;
/* int */ main()
{
for( ; i["]<i;++i){--i;}"];
read( '-' - '-',
i++ + "hello, world!\n",
'/' / '/') );
}
/* int */ read( /* int */ j,i,p)
{
write( j/p + p, i-- - j, i/i );
}
Take note that in C the language:
- there is no "character" type. A letter is just a (typically 8 bits) integer. Thus
'-' - '-'
is zero and '/' / '/'
is 1 (just like i/i
later)
- there is no "string" type - that is just a pointer to "character"
- arrays and pointers are the same thing by definition
- no-sized (byte-sized) pointers and integers are implicitly converted to each other.
Note: in comments below people argue that in C array are not pointers but are just implicitly typecasted to pointers. That is probably true in theory, yet doesn't seem to have any practical implication for this certain code. But still, a bullet 3 is perhaps formulated incorrectly by book.
Also let us assume that all global variables are zero-initialized.
Thus i["]<i;++i){--i;}"]
is 0[pointer to some string], then 1[pointer to some string], etc. Effectively being the i-th character of the string.
It is used in a for-loop at the second parameter place - the condition checker. So actually this can be re-formulated as
for( ; "]<i;++i){--i;}"[i] != '\0'; read... );
or by definition of C for loop
while ( "]<i;++i){--i;}"[i] != 0 ) { read ...; }
It is not a coinsidence, that both lines have equally 14 characters:
"hello, world!\n"
"]<i;++i){--i;}"
That makes it just a loop for each character in string, you could re-formulate it as
for i := 0 to 14-1 do
Glue this all together and the program turns into
int i;
/* int */ main()
{
for( i=0; i<strlen("hello, world!\n"); i++)
{
read( 0, & "hello, world!\n"[i], 1);
}
}
Is it a bit easier? Now moving to the function itself... and to C file handles. By UNIX standard, the following text files are pre-defined:
- 0 - STDIN - read from keyboard
- 1 - STDOUT - print to display/printer/log-file/etc
- 2 - STDERR - emergency print about error conditions
Thus:
/* int */ read( j = 0, i = pointer-to-letter-to-print, p = 1)
{
write( j/p + p, // 0/1 + 1 == 1 == STDOUT
i-- - j, // == i itself due to j == 0;
// -- is POST-decrement and does not affect the calculation
i/i /*== 1 as long as i != 0 - meaning print only single character*/ );
}
Gluing this together again:
int i;
int my_read( int j, char * pChar, int p)
{
write( STDOUT, pChar, 1 );
pChar--; // does not affect anything, as mentioned above
}
const char msg[] = "hello, world!\n";
int main(void)
{
for( i=0; i<strlen(msg); i++)
{
my_read( 0, &msg[i], 1);
}
}
Can you figure out how this snippet works now? ;-)
Just add spaces and new lines - the proper code structure formatting - and it becomes easy-peesy :-)