哈佛 CS50x 课程中的一个问题需要输入 1 到 8 之间的高度。有了这个高度,输出应该打印一个由空格和 # 组成的金字塔。
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height = 0;
do
{
// prompt for pos int between 1-8
height = get_int("Height? ");
}
while (height < 1 || height > 8);
for (int row = 0; row < height; row++)
{
// print left spaces
for (int j = height - row; j > 1; j--)
{
printf(" ");
}
// print left #
for (int i = row; i >= 0; i--)
{
printf("#");
}
// print gap
printf(" ");
// print right #
for (int z = row; z >= 0; z--)
{
printf("#");
}
// print new line
printf("\n");
}
}
我通过了所有测试用例,但我想知道是否有办法使用更少的代码行来解决这个问题。
以下代码打印一堆字符:
for (int z = row; z >= 0; z--)
{
printf("#");
}
您可以通过巧妙地索引字符串来使用单个
printf
调用来完成此操作:
printf("##########" + 10 - (row + 1));
这里
"##########" + 10
是一个超过字符串末尾的指针;从中减去一个数字将得到一个包含该数量字符的字符串。
您可以使用
puts
来执行此操作,而不是显式打印行尾字符。但不确定这算不算简化,因为你不能在任何地方都这样做——这只是一个有趣的事实。
您可以通过滥用
printf
的“字段宽度”功能来输出任意数量的空格(但不能输出其他字符 - 这个想法仅适用于空格)。例如,以下命令将在 10 个字符的字段中打印一个 4 个字符的字符串,并有效地在其前面添加 6 个空格:
printf("%*s", 10, "####");
这会让你的代码变得更复杂一些,但是更短。不确定综合效果是否有所改善。无论如何,如果你使用了这样的技巧,你必须在评论中解释它们。
为了极度简化,请考虑对输出字符串进行硬编码。由于有效输入的可能性很小,因此您可以在代码中将所有可能的输出准备为字符串并立即输出它们,而无需任何计算:
switch (height)
{
case 1: puts("..."); break;
case 2: puts("....."); break;
case 3: puts("......."); break;
...
}
不过没那么有趣。
@chqrlie:使用带有变量
width和
precision字段的
printf
%s
格式,这是修改后的版本:
#include <cs50.h>
#include <stdio.h>
int main(void) {
static char hashes[] = "########";
int height = 0;
// prompt for pos int between 1-8
do {
height = get_int("Height? ");
} while (height < 1 || height > 8);
for (int row = 1; row <= height; row++) {
printf("%*.*s %.*s\n", height, row, hashes, row, hashes);
}
return 0;
}