99乘法表到底可以怎么玩? [1] \t排版

我记得老师说过,科技的研究大概往2个方向,不是最复杂化,就是最精简化。
大家第一个学会的程序就是 hello world,而其次应该就是九九乘法表了
但大家有没有想过九九乘法表,到底可以被我们搞得多复杂呢?

  int main(){
    for(int y=1;y<=9;y++){
      for(int x=1;x<=9;x++){
         printf("%d * %d=%d    ",y,x,y*x);
         }  }
return 0;
}

执行结果如下图
https://ithelp.ithome.com.tw/upload/images/20171219/20107818gVuW0UKEaZ.png

======================分格======================

这应该是入门必学的程序了,但用这个去交作业,通常都会被老师打枪,要你去排版
这个时间就应该加一点\n (换行)、\t(TAB)
所以又产生了以下程序

int main(){
    for(int y=1;y<=9;y++){
      for(int x=1;x<=9;x++){
         printf("%d * %d=%d \n",y,x,y*x );
         }  }
return 0;
}

执行结果如下图
https://ithelp.ithome.com.tw/upload/images/20171219/20107818rxd6JxTwuv.png

======================分格======================

每完整输出一句,均下一行。
这样可不行,太长,所以要每9个才执行下一行
一般新人很直接的想:加一个if的判断码,判断每9个,才下一行。
但其实我们可以在第二个loop结束后,执行下一行的动作。

int main(){
    for(int y=1;y<=9;y++){
      for(int x=1;x<=9;x++){
         printf("%d * %d=%d",y,x,y*x );
         }
      printf("\n");
      }
return 0;
}

第二个loop执行结束时,便回到第一个loop作判断,合乎条件再执行一次第二个loop
结果如下
https://ithelp.ithome.com.tw/upload/images/20171219/20107818H4l1VWSKsw.png

======================分格======================

问题又出现了,下一句的输出结果黏着上一句的输出结果
这个时候\t(TAB) 用途要出现了

int main(){
    for(int y=1;y<=9;y++){
      for(int x=1;x<=9;x++){
         printf("%d * %d=%d\t",y,x,y*x );

         }
      printf("\n");
      }
return 0;
}

结果如下
https://ithelp.ithome.com.tw/upload/images/20171219/20107818XwzW7Nwz6S.png

======================分格======================

噢不...句与句之间是有分格开,但怎么变那么丑?
老师说过:程序不会有错,有错的一定是人
我们仔细看一下,乘1的时候,排版都没有偏差
但从乘2开始,程序所使用的\t,出现长短不一的距离
而且长TAB出现的位置都是前面是双位数的结果;而短TAB出现的位置前面则是单位数的结果
首先,我会怀疑是不是\t前面输出字元的长度,会影响\t所产生长短不一的间隔?
所以我把空白(Space)先删去

#include 
#include 
int main(){
    for(int y=1;y<=9;y++){
      for(int x=1;x<=9;x++){
         printf("%d*%d=%d\t",y,x,y*x );

         }
      printf("\n");
      }
return 0;
}

结果如下
https://ithelp.ithome.com.tw/upload/images/20171219/20107818uvC3oydSo3.png

======================分格======================
根据结果与理论,初步相信我的结论是对的
所以,我们来证明一下理论

int main(){
   printf("123456\t");
   printf("123456");
      printf("\n");
   printf("1234567\t");
   printf("1234567");
      printf("\n");
   printf("12345678\t");
   printf("12345678");
      printf("\n");
   printf("123456789\t");
   printf("12345678");
      printf("\n");
return 0;
}

结果如下
https://ithelp.ithome.com.tw/upload/images/20171219/20107818TqznKDdyEk.png

======================分格======================

在结果中,我们可以得知:当前一输出字元长度超过7时,\t(TAB)会突然变超长
那我们知道\t前的输出会影响\t(TAB)的长度,那\t后的输出也会同样影响到吗?

int main(){
   printf("123456\t");
   printf("1234567891234");
      printf("\n");
   printf("1234567\t");
   printf("1");
      printf("\n");
   printf("12345678\t");
   printf("1");
      printf("\n");
   printf("123456789123456789\t");
   printf("1");
      printf("\n");
return 0;
}

结果如下
https://ithelp.ithome.com.tw/upload/images/20171219/20107818wblL8Zc2fG.png

======================分格======================

结论:
根据输出结果,我们看到\t的长度,只受前一输出字元的长度而影响
\t是以每8个作一个区分,因为要留一空白作区隔,因此最高为7个字元
当超过7个字元时,电脑会自动帮你区分至下一个区段,因此会出现「突然变超长的情况」

解决办法:
尽量统一输出长度,方便\t排版
输出长度尽可能为7+Nx8 (N为区隔数量)
为什么是乘8,而不是乘7?
因为除了第一区隔不需要计算空白外,接下来的区隔,均要计算上一区隔所没有占用的空白。

======================分格======================

心得:
可能大家觉得只是\t排版遇到问题而且,修改一下,程序有美观就可以了。
其实我当初写九九乘法表,也是为了交作业,因此出现「结果出来就好了」的概念。
如果被老师问到「你根据什么理论而写这一行程序?」通常学生哑口无言,因为也不知道为什么会出现这个结果。
因此希望从很简单的程序入手,再参入一些研究方法,把大家常常忽略的东西,提出再加以验证。

最后,其实我有点怕没有主题可以写,所以目前是分享撰写程序的考虑及分析(当然,跟业界的工程师无法相比),同时也为踏入研究所提早准备,一定要坚持30天。希望大家能给我鼓励及评论(好坏也可以)
(其实我也没有想到做九九乘法表,最后会思考\t排版问题...)