目录
项目场景:九九乘法表
编写程序,输出n行n列的下列形式的左下三角九九乘法表,n由用户输入。下表是n=4的输出。 4 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 输入:1-9的正整数; 输出:n行n列左下三角九九乘法表,一行中各列数据间有一个空格,末尾无空格。
实现方案
我们先给出任务实现部分,下面的程序可以实现输出九九乘法表,但并不满足题目所给出的格式要求
实现打印普通乘法表
|
实现按格式输出
方案一:使用\b
使用\b保证光标位置处于空格前,具体代码即下图所示
for
(i = 1; i <c+1; i++)
{
for
(j = 1; j <= i; j++)
{
printf
(
"%d*%d=%d "
, i,j, i * j);
}
printf
(
"\b\n"
);
}
printf("\b");
运行后输出结果如下:
6
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36|^space^^space^^space^^space^^space^
可以看出此时光标位置在红色“|”位置,但事实上行末的空格没有被消除,并且一直被堆积在光标后。也就是说实际上我们并没有实现输出末尾无空格,仅仅改变了光标位置
“\b”名称为退格符,但本身不同于“backspace”,只是将光标向前移动1格
方案二:通过if语句
通过if语句筛选实现行末无空格,引入一个局部变量来实现,通过区分第一项和后来项的格式实现,而本质上这也是实现功能的核心。
for(i = 1; i <c+1; i++)
{
for (j = 1; j <= i; j++)
{
if(j==1)
printf("%d*%d=%d", i,j, i * j);\\第一项无空格
else
printf(" %d*%d=%d", i,j, i * j);\\空格在前补上
}
printf ("\n");
}
方案三:使用字符串形式输出
与方案二的实现原理并没有太大差别,但是通过for语句特性来实现整个过程
for (i = 1; i < c + 1; i++)
{
for (j=1,(printf("%d*%d=%d",i,j,i*j)); j <= i;j++,(printf(" %d*%d=%d",i,j, i * j)))
{
;
}
printf("\n");
}
上面这个代码与下面这个没有太大差别
for (i = 1; i < c + 1; i++)
{
j = 1;
for ((printf("%d*%d=%d",i,j,i*j)); j <= i;(printf(" %d*%d=%d",i,j, i * j)))
{
j++;
}
printf("\n");
}
return 0;
下方的代码相比上方少了一丝“装逼”的精简,但是可读性更强,对本身程序运行复杂度没有影响
那么我们将原来的for语句变成这样丑陋的样子有什么作用呢 ?
针对这道题目,二者的区别不大,但下面这种写法减少了计算机内部的一步判断,当我们需要输出的数据为99*99乘法表时,计算机将多进行9801次的if判断,以此类推程序效率减慢。而for语句第一个括号前的语句只进行一次,相当于恰好适配了我们的希望,大大减少了判断时间。
拓展应用:
下面给出for语句的这种特性在其他情况下的应用(在所有的首元素需要不同操作的情况下,均可以通过类似的方法调用for语句)
//本题中的行末无空格
//恶臭数字生成器节选
for(int i=0;string arr="begin:";i<10;i++,(arr+="m[%d]",n))//这里的m[n]是题目中给的字符串
//字符串切片
char arr[]="192.111.112.35"
char* ret=NULL;
char*p="."
for (ret=stroke(arr,p);ret!=NULL;ret=stroke(NULL,p))
{ printf("%s\n",ret); }
//每行第一个名字标红
//.....
总而言之,当程序需要在第一次循环时做出一定程度的变化或是不同的操作时,for语句更加方便,但在未知循环次数的条件判断时,while语句的效率将比for更加优秀,明天更新相关内容。