发布网友 发布时间:2022-04-30 00:03
共1个回答
热心网友 时间:2022-06-26 17:59
方法有很多种:
一、直接循环,通过变量计数判断每个字符输出的内容。缺点:逻辑繁琐。
二、把图像看成固定长度的多行字符串(最大行宽用常量或动态数组)。
这样两个题目就都统一成一个思路,那就是循环重复打印一个字符串。而这个字符串在每次循环都改变自己的内容。
改变内容的方法:初始用两个指针指向这个字符串的中心位置,不断往两边移动,移动同时改变指向地址的值。
这里,如指针移动到两头,程序就结束,那么打印的就是题目二的三角形。如到两头再往回走,打印的就是菱形。
另外要注意:1、菱形是固定字符黑桃。而三角形是循环打印大写字母。
2、字符之间是有宽度的,不能直接用%s输出一行字符串,需要循环输出指定宽度字符。
因此,按照编程思想,输出打印一个字符串以及循环大写字母这两个功能是要重复调用的,要单独写函数。
下面是代码:
#include <stdio.h>
#define MLEN 50//图形最大行宽度
void show1();//对应题目1的菱形
void show2();//对应题目2的三角形
void showLine(char lnStr[],int n,int d);//打印输出一行图形,参数:行数组、数组长度、字符间隔大小
char getLetter();//每次调用,返回A~Z的一个字母,字母循环
int main()
{
show1();
show2();
return 0;
}
void showLine(char lnStr[],int n,int d)
{
int i;
for(i=0;i<n;i++) printf("%*c",d,lnStr[i]);
printf("\n");
}
char getLetter()
{
char b;
static char w='A';
b=w;
if(w<'Z') w++;
else w--;
return b;
}
void show1()
{
int i,flag=1,n=0;
char lnStr[MLEN]={0},*p0=NULL,*p1=NULL;
while(n<=1 || n%2==0 || n>=MLEN)
printf("请输入菱形最大宽度n(字符个数n必须是大于1且小于%d的奇数):",MLEN),scanf("%d",&n);
for(i=0;i<n;i++) lnStr[i]=' ';//初始化一行空格
p0=p1=&lnStr[n/2];//指针初始指向中间
while(p0<=p1)
{
if(flag) *p0=*p1=5,p0--,p1++;//标识为1,两指针指向地址值变黑桃,之后分别向两边移动
else *p0=*p1=' ',p0++,p1--;//标识为0,两指针指向地址值变空格,之后分别向中间移动
showLine(lnStr,n,2);
if(p0+1==&lnStr[0]) p0++,p1--,flag=0;//两指针移动到两头,开始反向移动
}
}
void show2()
{
int i,n=0;
char lnStr[MLEN]={0},*p0=NULL,*p1=NULL,*p=NULL;
while(n<=1 || n%2==0 || n>=MLEN)
printf("请输入三角形底边宽度n(字符个数n必须是大于1且小于%d的奇数):",MLEN),scanf("%d",&n);
for(i=0;i<n;i++) lnStr[i]=' ';//初始化一行空格
p0=p1=&lnStr[n/2];//指针初始指向中间
while(1)
{
showLine(lnStr,n,2);
if(p0+1==&lnStr[0]) break;
p=p0;
while(p<=p1) *p=getLetter(),p++;
//两指针之间的地址值循环取大写字母,之后分别向两边移动
p0--,p1++;
}
}