“求最大公约数”简介
求两个数的最大公约数是一个非常经典的小程序,由用户输入两个数字,然后由程序计算出这两个数字的最大公约数,将结果返回给用户。初学者开始学习程序都会通过这样的小例子来熟悉程序的基本架构。这里,我们也通过一个小程序向大家展示,在Visual C++开发环境下实现这样一个小程序也是十分轻松的事情,同时会涉及到控件编辑、消息映射、控件变量设置、基本数据类型转换和计算等知识点。要创建的程序界面如图2.1所示。图 2.1 “求最大公约数”程序界面
“求最大公约数”程序设计
下面开始一步一步地实现这个程序。首先,我们使用应用程序向导来创建这个程序框架。选择File|New命令,打开New对话框,在Projects标签中选择MFC AppWizard(exe),在Project Name文本框中输入MaxDivisor,然后单击“OK”按钮,如图2.2所示。然后,在随后出现的对话框中选择Dialog based,在下方选择“中文[中国]”,如图2.3所示。图 2.2 创建程序文件
图 2.3 选择基于对话框的程序
在下面的几步中把一些不必要的选项都去掉,因为我们这个程序非常简单,不需要复杂的界面,如图2.4所示。然后单击Finish按钮,应用程序向导就自动产生了一个基于对话框的程序。下面对这个程序进行改造。首先,在工作区窗口中选择ResourceView,单击Dialog中的对话框资源,然后删掉应用程序向导生成的按钮和文本框,编辑产生我们自己的窗口,使其布局如图2.1。对于静态文本和按钮控件,单击鼠标右键,选择Properties选项,就可以编辑控件上的显示文字。然后我们用ClassWizard来添加消息映射和文本框变量,如图2.5所示。选中要添加的控件ID,然后在右面选择Add Variable按钮,就会弹出一个如图2.6所示的对话框,从中可以输入变量名、变量属性、变量的数据类型。这里,我们添加的3个变量都是整型数。另外,还要给第3个文本框添加一个额外的控件变量,如图2.7所示。
图 2.4 撤选应用程序向导里面的选项
图 2.5 添加变量
图 2.6 添加值变量
图 2.7 添加控件变量
现在,我们的程序框架已经基本完成,我们把“计算最大公约数”按钮的ID改为ID_COMPUTE,然后添加处理函数,如图2.8所示。然后单击Edit Code按钮,添加如下代码:
图 2.8 添加处理函数
void CMaxDivisorDlg::OnCompute(){
UpdateData ();
n_Num1 = m_num1;
n_Num2 = m_num2;
if((n_Num1 <= 0) ||(n_Num2 <= 0))
::AfxMessageBox ("请输入大于0的整数");
else{
n_Result = Compute(n_Num1,n_Num2);
m_result = n_Result;
}
char sz[20];
sprintf(sz,"%d",m_result);
m_CResult.SetWindowText (sz);
}
前面一部分代码用于输入的合法性检查,后面的代码调用一个Compute()函数,然后输出结果。Compute()函数是计算最大公约数的主体,代码如下:
int CMaxDivisorDlg::Compute(int a, int b){
int max,min;
max = a > b ? a : b;
min = a + b - max;
int temp;
while( min ){
temp = min;
min = max % min;
max = temp;
}
return max;
}
While里面的循环就是主要的计算程序,利用的是公约数的特性,是一个辗转相除的过程,稍微具备一点数学常识的人就能明白。计算结果如图2.9所示。
图 2.9 计算结果显示
程序说明
现在程序已经能够运行了,但读者单独完成时可能会遇到一些问题。下面说明两点,一是UpdateData()函数的应用。在基于对话框的程序中,当对话框上面的控件,尤其是文本框里面的内容发生改变时,我们需要调用UpdateData()函数进行更新,否则不能反映这些内容的变化。该函数有一个布尔型参数,False表示对话框刚开始创建,True表示对话框中的数据被刷新。二是字符串和基本数据类型,即数据格式间的转换问题。这也是初学者经常会遇到的问题,一般有3种办法可以解决:◆ 1.用sprintf()函数来实现,即按照某种规定好的格式将数据写到字符串中。该函数原型如下:
int sprintf(char *buffer, const char *format [,argument] …);
使用方法如下:
#include <stdio.h>
void main( void ){
char buffer[200], s[] = "computer", c = 'l';
int i = 35, j;
float fp = 1.7320534f;
/* Format and print various data: */
j = sprintf( buffer, "\tString: %s\n", s );
j += sprintf( buffer + j, "\tCharacter: %c\n", c );
j += sprintf( buffer + j, "\tInteger: %d\n", i );
j += sprintf( buffer + j, "\tReal: %f\n", fp );
printf( "Output:\n%s\ncharacter count = %d\n", buffer, j );
}
Output:
String: computer
Character: l
Integer: 35
Real: 1.732053
character count = 71
◆ 2.使用CString类提供的Format()函数,也可以将数据按照某种规定格式写入字符串:
CString str;
str.Format("%d",n);
这样也可以很简单地实现基本数据类型到字符串的转换。
◆ 3.用_itoa(),*_i64toa()系列函数,这是在程序中经常用到的小函数,其原型如下:
char *_itoa(int value,char *string,int radix );
char *_i64toa(__int64 value, char *string, int radix );
char * _ui64toa( unsigned _int64 value, char *string,int radix );
wchar_t * _itow(int value, wchar_t *string, int radix );
wchar_t * _i64tow( __int64 value, wchar_t *string, int radix );
wchar_t * _ui64tow(unsigned __int64 value, wchar_t *string, int radix);
使用方法如下:
void main( void ){
char buffer[20];
int i = 3445;
long l = -344115L;
unsigned long ul = 1234567890UL;
_itoa( i, buffer, 10 );
printf( "String of integer %d (radix 10): %s\n", i, buffer );
_itoa( i, buffer, 16 );
printf( "String of integer %d (radix 16): 0x%s\n", i, buffer );
_itoa( i, buffer, 2 );
printf( "String of integer %d (radix 2): %s\n", i, buffer );
_ltoa( l, buffer, 16 );
printf( "String of long int %ld (radix 16): 0x%s\n", l, buffer );
_ultoa( ul, buffer, 16 );
printf( "String of unsigned long %lu (radix 16): 0x%s\n", ul,buffer );
}
输出结果如下:
String of integer 3445 (radix 10): 3445
String of integer 3445 (radix 16): 0xd75
String of integer 3445 (radix 2): 110101110101
String of long int -344115 (radix 16): 0xfffabfcd
String of unsigned long 1234567890 (radix 16): 0x499602d2
这几种转换方式是非常常用的编程方法,在许多Visual C++程序中都要用到,读者应当熟练掌握,在程序中能很快地完成这些转换。