[此贴子已经被作者于2005-1-22 16:59:38编辑过]
--------------------------------------------------------- [glow=255,green,2]______[/glow] [glow=255,blue,2]—————[/glow]
[此贴子已经被作者于2005-1-22 16:59:38编辑过]
那么就解释一下吧: // prob.1
f(i) { // 逻辑条件表达式 a && b 在 a 为真时才去检验b的值。 // 这里在 i 为真的时候,才去执行后面的部分。为真也就是不为 0 i && (f(i/10),printf("%d\n",i)); // 而后半部分是一个逗号表达式。以这种形式出现 a,b // 从左往右依次执行。逗号表达式的返回值为最右侧的值 b // 不过这里对这个值并不关心。 // 这里出现了递归,把i的值除10,其实就是十进制数中去掉个位数字 // 这里的调用次序是先递归,后输出, // 所以可以得到短的数字在前面,而整个数字在后面的效果
// i 值的判断其实是对递归调用的限制,由于递归时每次都除 10, // 可以预见最终这个整型参数将为 0,从而结束递归。 }
main() { f(12345); // 这里直接给最大的那个值。 }
// prob.2
f(i) { // 这里要注意 && 与逗号两个运算符的优先级,&&高,所以不必加括号 printf("%d\n",i), i>1&&f(i/10); // 同样是递归,这时是先输出数据再递归调用,所以得到长的数字在前面 // 与上面类似 i>1 用来做为递归调用的限制条件。 // 不同的是这里在i为 1 时就要结束递归,否则将输出0 // 这里其实有个问题,如果需要输出的是 23456 这个数,那么将得到一个多余的0 // 也就是与 1 比大小恰好是这个题的特例,正确的想法应该是 // i 这个数是否为 2 位数,也就是写成 i>9 }
main() { f(12345); }
// prob.3
f(char*s) { // 仍然是递归,所不同的是参数是一个字符串 printf(s), *s&&f(s+2); // 这里要特别小心,字符串是连续存储的一串字符,末尾有一个 '\0' 也就是数字 0。 // 由于 s 每次加 2 做 *s 这个判断有一定的危险, // 假如串的内容不是奇数个字符,那么在最后一次 s+2 时直接越过了 // 字符串的末尾 '\0',然后程序将继续递归直到偶然地遇到一个0。 // 安全的做法是在字符串末尾多加1个'\0' }
main() { f("* * * * * * *\n"); // 这里恰好是奇数个字符.不然得这么写"* * * *\n\0" // 除了天然的一个结束标志,还有你人为的一个字符。保证了 s+2 不可能一口气跳过这个'\0'区域 }