用printf()的格式说明符“%*.*s”绘制菱形
Draw rhombus with the format specifier "%*.*s" of printf()
我正在尝试对一个小程序进行编码,以便使用标准 printf 在屏幕上打印一个菱形,直到现在我有这段代码,正如您在编译时看到的那样,它没有打印出所需的输出:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n = 5;
for(i = -n/2; i < n; i++)
printf("%*.*s\n", n / 2 + 1, i, "*****");
return 0;
}
谁能告诉我应该怎么做?
期望的输出:
一种方式:
#include <stdio.h>
#include <stdlib.h>
int main() {
for(int i=1;i<10;i++)
printf("%.*s%.*s\n",abs(5-i)," ",9-abs(10-(i<<1)),"**********");
return 0;
}
另一个选项:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
for (int n = 11, i = -n / 2; i < n / 2 + 1; i++)
printf("%*.*s\n", n - abs(i), 1 + (n / 2 - abs(i)) * 2, "***********");
return 0;
}
其他答案演示了如何用时髦的数学来解决问题。另一种方法是使用软件状态机解决问题。状态机有3个状态变量
- skip -- 行首空格数
- show -- 行中显示的星号(星星)数
- delta -- 用于调整每次循环时的跳过和显示
这种状态变量的安排使 printf 更容易理解。 skip+show
是一行中的字符总数,show
是要从 stars
字符串中取出的星号数,而 stars
字符串必须长于show
.
的最大值
char *stars = "*********************";
printf( "%*.*s\n", skip + show, show, stars );
所以问题是如何在每次循环时更新状态变量,以及循环终止条件是什么。
以 n=5
为例,skip
的值序列是
4 3 2 1 0 1 2 3 4
我们通过初始设置 skip = n-1
和 delta = -1
来完成此操作。将 delta
添加到 skip
会导致 skip
递减直到达到 0
。我们不允许 skip
变为负数,而是强制 skip = 1
和 delta = 1
改变方向。然后 skip
递增,直到达到 n
,从而终止循环。
show
的值序列是
1 3 5 7 9 7 5 3 1
这个序列是从show=1
开始,通过-2*delta
调整生成的。
char *stars = "*********************";
int n = 5;
int skip = n - 1;
int delta = -1;
int show = 1;
while ( skip < n )
{
printf( "%*.*s\n", skip + show, show, stars );
skip += delta;
if ( skip < 0 )
{
skip = 1;
delta = 1;
}
show -= delta * 2;
}
我正在尝试对一个小程序进行编码,以便使用标准 printf 在屏幕上打印一个菱形,直到现在我有这段代码,正如您在编译时看到的那样,它没有打印出所需的输出:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n = 5;
for(i = -n/2; i < n; i++)
printf("%*.*s\n", n / 2 + 1, i, "*****");
return 0;
}
谁能告诉我应该怎么做?
期望的输出:
一种方式:
#include <stdio.h>
#include <stdlib.h>
int main() {
for(int i=1;i<10;i++)
printf("%.*s%.*s\n",abs(5-i)," ",9-abs(10-(i<<1)),"**********");
return 0;
}
另一个选项:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
for (int n = 11, i = -n / 2; i < n / 2 + 1; i++)
printf("%*.*s\n", n - abs(i), 1 + (n / 2 - abs(i)) * 2, "***********");
return 0;
}
其他答案演示了如何用时髦的数学来解决问题。另一种方法是使用软件状态机解决问题。状态机有3个状态变量
- skip -- 行首空格数
- show -- 行中显示的星号(星星)数
- delta -- 用于调整每次循环时的跳过和显示
这种状态变量的安排使 printf 更容易理解。 skip+show
是一行中的字符总数,show
是要从 stars
字符串中取出的星号数,而 stars
字符串必须长于show
.
char *stars = "*********************";
printf( "%*.*s\n", skip + show, show, stars );
所以问题是如何在每次循环时更新状态变量,以及循环终止条件是什么。
以 n=5
为例,skip
的值序列是
4 3 2 1 0 1 2 3 4
我们通过初始设置 skip = n-1
和 delta = -1
来完成此操作。将 delta
添加到 skip
会导致 skip
递减直到达到 0
。我们不允许 skip
变为负数,而是强制 skip = 1
和 delta = 1
改变方向。然后 skip
递增,直到达到 n
,从而终止循环。
show
的值序列是
1 3 5 7 9 7 5 3 1
这个序列是从show=1
开始,通过-2*delta
调整生成的。
char *stars = "*********************";
int n = 5;
int skip = n - 1;
int delta = -1;
int show = 1;
while ( skip < n )
{
printf( "%*.*s\n", skip + show, show, stars );
skip += delta;
if ( skip < 0 )
{
skip = 1;
delta = 1;
}
show -= delta * 2;
}