使用格式说明符"%*。* s"绘制菱形。 of printf()

时间:2015-02-05 19:36:00

标签: c 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;
}

有人能告诉我这应该是怎么回事吗?

期望的输出:

enter image description here

3 个答案:

答案 0 :(得分:4)

另一种选择:

#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;
}

答案 1 :(得分:2)

一种方式:

#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;
}

答案 2 :(得分:1)

其他答案演示如何用时髦的数学解决问题。另一种方法是用软件状态机解决问题。状态机有三个状态变量

  • 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-1delta = -1来实现此目的。将delta添加到skip会导致skip递减,直到达到0。我们强制skipskip = 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;
}