近期在教学中讲了二维数组,给学生布置了一大堆的练习题。不愿意为这一批能够投身学习的学生再多加硬性的任务了,练习题目中有的是他们要体会的。但前一段时间还准备了一个好玩的程序,当作额外的阅读参考公布出来吧,不作为教学要求了。
临近期末,玩编程,但也要为着考试让让路了。
书归正题,二维数组可以用在很多很多的地方。一个典型应用,存储“字模”,即显示信息要用到的点阵数据。
例如,下面的二维数组定义了10个数字的字模(要是采用别的字体,这个数组中的数字变一下即可):
char a[10][8]= { {0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x18}, //0 {0x00,0x18,0x1c,0x18,0x18,0x18,0x18,0x18}, //1 {0x00,0x1e,0x30,0x30,0x1c,0x06,0x06,0x3e}, //2 {0x00,0x1e,0x30,0x30,0x1c,0x30,0x30,0x1e}, //3 {0x00,0x30,0x38,0x34,0x32,0x3e,0x30,0x30}, //4 {0x00,0x1e,0x02,0x1e,0x30,0x30,0x30,0x1e}, //5 {0x00,0x1c,0x06,0x1e,0x36,0x36,0x36,0x1c}, //6 {0x00,0x3f,0x30,0x18,0x18,0x0c,0x0c,0x0c}, //7 {0x00,0x1c,0x36,0x36,0x1c,0x36,0x36,0x1c}, //8 {0x00,0x1c,0x36,0x36,0x36,0x3c,0x30,0x1c}, //9 };这个数组,表示的是数字的字模?这,这,从何说起?
以数字3对应的数据a[3]({0x00,0x1e,0x30,0x30,0x1c,0x30,0x30,0x1e}, //3)为例,包括有8个十六进制的数,每行一个十六进制数,并且换成二进制的表示,会是什么样的呢?
是这样的:
00000000 //0x00
00011110 //0x1e
00110000 //0x30
00110000 //0x30
00011100 //0x1c
00110000 //0x30
00110000 //0x30
00011110 //0x1e
请看1出现的地方,可以借着鼠标按1出现的轨迹跟着划一划,不就是
数字3字型的轮廓吗?只不过,耳朵状的3是反着的(这自有道理,看完程序1自会明白)。
是的,我们就是要借着这个二维数组,玩点阵数字的显示。
【程序1】输入一个0-9之间的数字,用点阵的形式输出
#include <iostream> using namespace std; char a[10][8]= { {0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x18}, //0 {0x00,0x18,0x1c,0x18,0x18,0x18,0x18,0x18}, //1 {0x00,0x1e,0x30,0x30,0x1c,0x06,0x06,0x3e}, //2 {0x00,0x1e,0x30,0x30,0x1c,0x30,0x30,0x1e}, //3 {0x00,0x30,0x38,0x34,0x32,0x3e,0x30,0x30}, //4 {0x00,0x1e,0x02,0x1e,0x30,0x30,0x30,0x1e}, //5 {0x00,0x1c,0x06,0x1e,0x36,0x36,0x36,0x1c}, //6 {0x00,0x3f,0x30,0x18,0x18,0x0c,0x0c,0x0c}, //7 {0x00,0x1c,0x36,0x36,0x1c,0x36,0x36,0x1c}, //8 {0x00,0x1c,0x36,0x36,0x36,0x3c,0x30,0x1c}, //9 }; int main() { int n=0,i,j,x; int b[8]; //用于将字模中需要的某一行数据以二进制形式保存下来 cin>>n; for(i=0; i<8; i++) { x=a[n][i]; //a[n][i],取要显示的数字n对应字模中的第i个数据x,这是要在每i行显示 for(j=0; j<8; j++) //这个循环找出x以二进制的形式,保存在b数组中 { b[j]=x%2; x=x/2; } //注意b中放的数据是x的倒序,例0x30对应的二进制是00110000,b中存入的却是00001100 for(j=0; j<8; j++) //输出b,为1输出*(你可以设置别的符号),为0是空格,当然字型不会是反的了 { if(b[j]%2) cout<<'*'; else cout<<' '; } cout<<endl; } return 0; }运行结果示例:
上面程序中的数组b并不是必须的,可以一边算一边输出。于是main函数可以如下:
int main() { int n=0,i,j,x; cin>>n; for(i=0; i<8; i++) { x=a[n][i]; for(j=0; j<8; j++) { if(x%2) cout<<'*'; else cout<<' '; x=x/2; } cout<<endl; } return 0; }
【程序2】输入任意整数,用点阵形式输出
#include <iostream> using namespace std; char a[10][8]= { {0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x18}, //0 {0x00,0x18,0x1c,0x18,0x18,0x18,0x18,0x18}, //1 {0x00,0x1e,0x30,0x30,0x1c,0x06,0x06,0x3e}, //2 {0x00,0x1e,0x30,0x30,0x1c,0x30,0x30,0x1e}, //3 {0x00,0x30,0x38,0x34,0x32,0x3e,0x30,0x30}, //4 {0x00,0x1e,0x02,0x1e,0x30,0x30,0x30,0x1e}, //5 {0x00,0x1c,0x06,0x1e,0x36,0x36,0x36,0x1c}, //6 {0x00,0x3f,0x30,0x18,0x18,0x0c,0x0c,0x0c}, //7 {0x00,0x1c,0x36,0x36,0x1c,0x36,0x36,0x1c}, //8 {0x00,0x1c,0x36,0x36,0x36,0x3c,0x30,0x1c}, //9 }; int main() { int n=0,i,j,k,m,x; int c[8]; cin>>n; for(k=0; n&&k<8; k++) //c数组将分离出n中的各位数,不过是倒着的,例n=123,c中保存3 2 1 { c[k]=n%10; n/=10; } //循环结束,将由k记住n是几位数,此处限最多8位数 for(i=0; i<8; i++) //一共要显示8行,不是依次显示k个数字,而是依次显示k个数字中对应的每一行 { for(m=k-1; m>=0; m--) //要显示n=123, c中是倒着保存各位数的,所以m由大到小 { x=a[c[m]][i]; //现在要显示的数字是c[m],所以取a数组中的第c[m]行,第i列数据 for(j=0; j<8; j++) { if(x%2) cout<<'*'; else cout<<' '; x=x/2; } } cout<<endl; } return 0; }程序运行结果: