广州地坪漆厂家:发个C程序,大家看看什么结果呵呵

来源:百度文库 编辑:查人人中国名人网 时间:2024/04/30 00:39:03
#include <stdio.h>
int main(int i,int j)
{i++<10&&main(i,printf("%*s\n",i<6?i+3:15-i,"*********"+(i<6?12-2*i:2*i-12)));}
知道上难道非要提一些基础问题才算知道吗?
碰到了有趣的题目,提出来给大家一起分享,思考和分析难道就是刁难了吗?
缺乏交流,补课式的问答难道就没人厌倦吗?
这么一个交流板块,难道就是一群人无聊的帮另一群人做作业赚分就是真心问答了?
-----------------------------------------------
提醒御剑晨风:不要用义正昂然的话来掩盖自己的懒惰,拿到难题就放弃不思考的人永远是学不好编程的!这个题目妙不在它的函数体,而是整个程序!!不自己运行,你根本不能体会.
-----------------------------------------------
补充分数,给喜欢思考的朋友,分析透彻我再加分,只是我偶尔在网上看到的有趣程序问题,不敢独享,放上来给大家一起交流.
-----------------------------------------------
原题目是下面的代码,下划线不是笔误,可以拷到编译器里面编译一下试试,为了分析我改成了上面的,如下面朋友所说,j纯粹是凑格式呵呵,这个下划线,我怎么也想不通是怎么回事情...希望高手能解释一下:
#include <stdio.h>
int main(_)
{_++<10&&main(_,printf("%*s\n",_<6?_+3:15-_,"*********"+(_<6?12-2*_:2*_-12)));}

噢,是件 C 艺术品。艺术品总是让我们看到平时忽略了的东西。
谢谢鬼火狼烟和我们分享。

那个下划线是跟任何单字母变量名一样合法的变量名,因为 C 视下划线为字母。

分析前我把程序里那个唯一的变量(脚注#1)改名为 sole,
然后做代码编排,让程序的结构变得清晰:
 
 
#include <stdio.h>

int main( sole ) {

    sole++ < 10

        &&

    main(
 
          sole
          ,

          printf(
 
                  "%*s\n"
                  ,

                  sole < 6 ?
                             sole + 3 :
                             15 - sole
                  ,

                  "*********" + (
 
                                  sole < 6 ?
                                             12 - 2 * sole :
                                             2 * sole - 12
                                )
          )
    );
}
 
 
其实这个程序是以 main 的尾递归(脚注#2)重复调用 printf 打印出菱形。

程序里 && 这个二目短路运算符把 sole++ < 10 化作 main 的递归条件。
执行这程序时若没有命令行参数,sole 的始值是 1(脚注#3),终值是 11,
但 printf 看到的 sole 的始值是 2,终值是 10。

任何尾递归都可以在不改变程序语义的情况下被直接转换成迭代。
该程序(不带命令行参数执行时)的 for 迭代版本如下:
 
 
#include <stdio.h>

int main( ) {

    int sole;

    for( sole = 2; sole <= 10; sole++ )
        printf(
 
                "%*s\n"
                ,

                sole < 6 ?
                           sole + 3 :
                           15 - sole
                ,

                "*********" + (
 
                                sole < 6 ?
                                           12 - 2 * sole :
                                           2 * sole - 12
                              )
        );
}
 
 
printf 的格式控制字符串里的星号是特别的最小宽度指定符。
星号将被 printf 的第二个参数代替,所以第一个三目运算的结果指定最小宽度。

C 里的字符串皆为字符指针。指针与整数相加产生新的指针,
所以 printf 的第三个参数是妥当的。

printf 打印那 9 颗星的时候必须跳过前面多少颗?
第二个三目的运算结果是直接的答案。
 
 
运行。。。

sole 等于 2。 最小宽度是 5。 跳过前面 8 颗星,即打印 1 颗星,
但最小宽度是 5,所以打印时左补 4 个空格。

sole 等于 3。 最小宽度是 6。 跳过前面 6 颗星,即打印 3 颗星,
但最小宽度是 6,所以打印时左补 3 个空格。

sole 等于 4。 最小宽度是 7。 跳过前面 4 颗星,即打印 5 颗星,
但最小宽度是 7,所以打印时左补 2 个空格。




 
 
 
 
 
脚注:

#1)
   声明函数时若没有声明参数的类型,则参数将被默认为 int 类,
   而且该函数被调用时所接收到的参数的个数和类型都不会被检察
   (所以 main 被递归的时候多一个 int 参数也无所谓)。

#2)
   把递归调用作为函数体里的最后一件事即造就了尾递归。

#3)
   main 这个应该只被操作系统调用的特殊函数的第一个参数如果有声明的话,
   不管声明时类型和名字为何,程序执行时该参数的始值都将会是命令行参数的个数。

   由于 C 把程序的全路径当作第一个“命令行参数”,所以程序执行时若没有命令行参数,
   main 的第一个参数的始值便是 1。

呵呵,下划线_就是main函数的参数个数啊。
这样看,应该会好看一些:
#include <stdio.h>
int main(_)
{
int i, j, k, l;
i = _;
j = i<6 ? i+3 : 15-i;
k = i<6 ? 12-2*i : 2*i-12;
l = printf("%*s\n", j, "*********" + k);

//printf("%d, %d, %d, %d\n", i, j, k, l);

if( i++<10 )
main(i, l);
}

首先认错,我确实是懒人。不过这个程序也并没有太多价值,因为现在工业上没有这样写程序的,当然,想了解汇编的人应该看看。在此,我先正式向楼主道歉。

其次,我分析一下,大家看看说不说得通:
main函数的特殊定义使它看起来玄了点。
#include <stdio.h>
int main(int i,int j)
{
i++<10&&main(i,printf("%*s\n",i<6?i+3:15-i,"*********"+(i<6?12-2*i:2*i-12)));
}

一些说明:
第一、j参数,凑形式而已,其实在函数体中无用;因为printf的返回值是int类型。
第二、i++<10&&(...)。程序执行该语句时判断第一条件,其为真后判断第二条件,此处其实相当于if(i++<10)...。
第三、"%*s"的作用是打印后继参数一的个数个空格后接参数二字符指针指向位置。
第四、"*********"+n指从第n+1位置上开始的字符串"***..."(n为整数),因为字符串常量在编译器中实际上在编译后是一个指向该字符串的指针。

让我们来看这个程序:
启动后,参数均为零(可以带参启动,不带参则默认为0参),i=0,j=0,main(0,0);
i++<10为真,执行后继语句,同时i=1;
调用printf,打印4个空格+"*\n";
接受printf返回值2,递归调用main(1,2);

i++<10仍然为真,仍须执行后继语句,同时i=2;
调用printf,打印3个空格+"***\n";
接受printf返回值2,递归调用main(2,2);

i++<10仍然为真,执行后继语句,同时i=3;
调用printf,打印2个空格+"*****\n";

……

i=10
i++<10为假,不再执行后继语句,所有递归返回,程序结束。

因为程序最后一个表达式值为0,(假=0),程序返回0,正常结束。

基本上看懂了.只有一点不太清楚
printf("%*s",a,*p);
输出时在*p指向的字符串前有几个空格呀,和a是什么关系
我刚学C++,很少用printf();函数输出的 ^_^

我看是不是改为这面的,改为有返回值的,要不编译就出警告的
#include <stdio.h>
int main(int i,int j)
{return (i++<10&&main(i,printf("%*s\n",i<6?i+3:15-i,"*********"+(i<6?12-2*i:2*i-12))));}

这个问题好,有意思,可以说是享受C语言
一个语句包含以下几点:
1>函数递归调用.
2>三目运算 ?;
3>printf();
4>逻辑运算&&.(如果左值为0,右表达式不计算就返回)
5>字符串做指针处理

enjoy it~~

这样写也许比较容易理解一点:

#include <stdio.h>

int main(int x)
{
int width; //* 打印字符串的宽度
int pos; //* 开始显示的位置

//x如果x小于10自增1并继续,否则返回
if (x++ < 10) {
//x有没有过半,分别用两个公式算字符串总宽度
if (x < 6) {
width = x + 3;
} else {
width = 15 - x;
}

//x有没有过半,分别用两个公式算字符串的起始位置
if (x < 6) {
pos = 12 - 2 * x;
} else {
pos = 2 * x - 12;
}

//根据计算得出的宽度和位置打印出字符串
printf("%*s\n", width, "*********"+pos);

//递归调用
main(x);
}
return 0;
}

哈哈,有意思,不过在上网时做浪费时间和金钱