c语言编写,两种思路:
方法一:循环输出n行,每行分5个部分。
分别是:左边的空格,字符1,中间的空格,字符2,右边的空格。
循环控制空格输出个数,实现打印效果。
方法二:根据行数,定义一个字符串表示一行最大宽度(动态申请)。
定义2指针,初始指向字符串中间位置。
循环,两指针先往两边移动,到头就往回移动。
每次循环,指针指向的位置为符号,其余都是空格。并打印输出字符串。
下面是代码(两方法对应两函数):
#include
#include
#include
#define CR '*'//用于填充的字符
int show1(int row);//方法1
int show2(int row);//正常打印菱形,异常返回-1
int main()
{
int row;
printf("请输入行数(奇数):"),scanf("%d",&row);
printf("方法一:通过字符遍历打印图形\n");
show1(row);
printf("\n方法二:通过指针移动打印图形\n");
show2(row);
return 1;
}
int show1(int row)//方法1
{
int i,j,len,lk=0,mk=0,rk=0,flag=1;//lk,mk,rk每行左边中间右边的空格数量
if(row%2==0)
{
printf("错误!行数必须为奇数!");
return -1;
}
len=1+(row/2)*2;
lk=rk=len/2,mk=0;
for(i=0;i { for(j=0;j printf("%c",CR); for(j=0;j if(mk>0)printf("%c",CR); for(j=0;j printf("\n"); if(lk==0)flag=0; if(flag) { lk--,rk--; if(mk>=1)mk+=2; else mk++; } if(!flag) { lk++,rk++; if(mk>2)mk-=2; else mk--; } } return 1; } int show2(int row)//方法2 { int len,flag=1;//标识,flag=1两指针往两边移动。flag=0向中间汇合 char *rStr=NULL,*p1=NULL,*p2=NULL; if(row%2==0) { printf("错误!行数必须为奇数!"); return -1; } len=1+(row/2)*2; rStr=(char *)malloc(sizeof(char)*(len+1));//根据行数申请最大行字符串地址 if(!rStr)return -1; p1=p2=&rStr[len/2]; while(p1<=p2) { memset(rStr,' ',len);//填充空格 rStr[len]=0; *p1=*p2=CR; printf("%s\n",rStr); if(p1==rStr) flag=0;//指针移动到两头,反向移动 if(flag)p1--,p2++; if(!flag)p1++,p2--; } free(rStr); return 1; }
C++
#include
#include
using std::cin;
using std::cout;
int main(void) {
int n;
cout << "请输入行数: ";
cin >> n;
for (int y = n / 2; y >= -n / 2; y--) {
for (int x = -n / 2; x <= n / 2; x++) {
cout << (abs(y) + abs(x) == n / 2 ? '*' : ' ');
}
cout << '\n';
}
return 0;
}
定义字符型二维数组,有些存放空格(空格的ASCII码值为32),有些存放*(ASCII码值为42),再用循环语句输出数组即可。