微学苑—编程语言学习第一站!
主页   C++   Visual C++游戏编程   “幸运52”游戏  

Visual C++环境下“求最大公约数”的程序设计


“求最大公约数”简介

求两个数的最大公约数是一个非常经典的小程序,由用户输入两个数字,然后由程序计算出这两个数字的最大公约数,将结果返回给用户。初学者开始学习程序都会通过这样的小例子来熟悉程序的基本架构。这里,我们也通过一个小程序向大家展示,在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++程序中都要用到,读者应当熟练掌握,在程序中能很快地完成这些转换。