代码意识流——花朵数问题(五)
本文前一部分的链接
http://www.cnblogs.com/KBTiller/archive/2011/06/02/2068470.html
15.改写代码(续)
//待修改 he += i * sz ;
这句实际上是测试用的代码。问题在这里提出的要求是把某个数字的N次方加到he中,而某个数字的N次方可能是一个很大的数字,因此需要用DASHU类型来表示。也就是说对于问题,这里提出的要求是 DASHU += DASHU
为了能够测试且写出问题所实际需要的函数,这里把
he += i * sz ;
分为两步
{
DASHU temp ;
temp = i * sz ;
he += temp ;
}
这里要求两个运算“=”、“+=”,由于运算对象是自己创建的新的数据类型,C语言并没有定义这种新数据类型的“=”、“+=”运算,所以只能自己通过定义函数的办法自行定义。
将 temp = i * sz ; 改为 ds_fuzhi ( &temp , i * sz ) ;
(使用指针的缘故是因为temp被函数改变,这和scanf()里使用&运算的道理一样)
同时可给出函数原型
void ds_fuzhi ( DASHU * const , const int ) ;
修改(2_穷举.c xunhuan()函数 )
static void xunhuan( const int gssx /*个数上限*/,
const int sz /*关于哪个数字*/)
{
static DASHU he = { { 0 } } ;//static DASHU he ; // =0 待完成
DASHU he_ = he ; //记录累加前的值
if( sz > 0 ){
int i;
for( i = 0 ; i <= gssx ; i++ ){
printf("%d*%d +" , i , sz );
{
DASHU temp ;
ds_fuzhi ( &temp , i * sz ) ; //void ds_fuzhi ( DASHU * const , const int ) ;
//he += temp ; // 每次调用都从he开始累加
}
xunhuan( gssx - i , sz - 1 );
he = he_ ; //恢复原来的值
}
}
else{
//待修改 he += gssx * sz ;
//待修改 printf("%d*%d = %d" , gssx , sz , he );
putchar('\n');//<=>验算<=>记录结果
}
}
因为在前面已经 #include "3_大数.h"
所以直接把函数原型 ds_fuzhi ( DASHU * const , const int ) ; 移动到"3_大数.h"中,并修改为
/*3_大数.h*/
#ifndef DASHU_H
#define DASHU_H
#include "0_问题.h" //DASHU用到了WEISHU
/**************************类型定义**************************/
//gw_sz[0]为个位,gw_sz[WEISHU-1]为最高位
//gw_sz[WEISHU-1]的值大于等于JINZHI表示溢出
typedef struct {
int gw_sz[WEISHU] ;
}
DASHU ;
/**************************函数原型**************************/
extern void ds_fuzhi ( DASHU * const , const int ) ;
#endif // DASHU_H
在工程中添加"3_大数.c" 源文件,并写出ds_fuzhi()函数定义
/*3_大数.c*/
#include "3_大数.h"
//在*p_ds中写入n
extern void ds_fuzhi ( DASHU * const p_ds , const int n )
{
p_ds->gw_sz[0] = n ;
//可能有进位,同时把高位写为0
{
int *t = p_ds->gw_sz , //指向 p_ds->gw_sz[0]
*w = t + WEISHU - 1 ; //指向 p_ds->gw_sz[WEISHU-1]
while( t < w ){
*( t + 1 ) = * t / JINZHI ;
* t ++ %= JINZHI ;
}
}
}
编译,通过。之后首先考虑测试
由于在xunhuan()函数里面写测试语句可能把代码弄得很乱,所以这次在main()中写测试代码
修改main()为:
#ifdef CESHI //测试
int main( void )
{
#define TEST_ds_fuzhi
#ifdef TEST_ds_fuzhi
{
#include "3_大数.h"
DASHU t ;
ds_fuzhi(&t,12);
{
int i ;
for(i=WEISHU-1;i>=0;i--){
printf("%d",t.gw_sz[i]);
}
putchar('\n');
}
}
#endif
#ifdef TEST_qiongju
qiongju(); //保留,以后继续测试
#endif
system("PAUSE");
return 0;
}
#endif //CESHI
输出:012。测试通过
回到xunhuan()函数继续未完成的修改。(要点:先写出ds_jiaru() 、ds_shuchu()的函数调用及原型)
static void xunhuan( const int gssx /*个数上限*/,
const int sz /*关于哪个数字*/)
{
static DASHU he = { { 0 } } ;//static DASHU he ; // =0 待完成
DASHU he_ = he ; //记录累加前的值 //记录累加前的值
if( sz > 0 ){
int i;
for( i = 0 ; i <= gssx ; i++ ){
printf("%d*%d +" , i , sz );
{
DASHU temp ;
ds_fuzhi ( &temp , i * sz ) ;
ds_jiaru ( &he , &temp ) ;
//void ds_jiaru ( DASHU * const , const DASHU * const ) ; // 每次调用都从he开始累加
}
xunhuan( gssx - i , sz - 1 );
he = he_ ; //恢复原来的值
}
}
else{
{
DASHU temp ;
ds_fuzhi ( &temp , gssx * sz ) ;
ds_jiaru ( &he , &temp ) ; //待修改 he += gssx * sz ;
}
//待修改 printf("%d*%d = %d" , gssx , sz , he );
printf("%d*%d = " , gssx , sz );
ds_shuchu( &he ) ;//extern void ds_shuchu( const DASHU * const ) ;
//<=>验算<=>记录结果
}
}
把ds_jiaru() 、ds_shuchu()的函数原型移动到 “3_大数.h”
修改
/*3_大数.h*/
#ifndef DASHU_H
#define DASHU_H
#include "0_问题.h" //DASHU用到了WEISHU
/**************************类型定义**************************/
//gw_sz[0]为个位,gw_sz[WEISHU-1]为最高位
//gw_sz[WEISHU-1]的值大于等于JINZHI表示溢出
typedef struct {
int gw_sz[WEISHU] ;
}
DASHU ;
/**************************函数原型**************************/
extern void ds_fuzhi ( DASHU * const , const int ) ;
extern void ds_shuchu( const DASHU * const ) ;
extern void ds_jiaru ( DASHU * const , const DASHU * const ) ;
#endif //DASHU_H
修改
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*3_大数.c*/
#include "3_大数.h"
static void ds_jinwei ( DASHU * const );
//进位
static void ds_jinwei ( DASHU * const p_ds )
{
int * t = p_ds->gw_sz , * const w = t + WEISHU - 1 ;
while( t < w ){
*( t + 1 ) += * t / JINZHI ;
* t ++ %= JINZHI ;
}
}
// *p_he += *p_js
extern void ds_jiaru ( DASHU * const p_he , const DASHU * const p_js )
{
int *he_t = p_he->gw_sz , * const he_w = he_t + WEISHU - 1 ;
const int *js_t = p_js->gw_sz ;
while( he_t < he_w ){
*he_t++ += *js_t++ ;
}
ds_jinwei ( p_he ); // static void ds_jinwei ( DASHU * const );
}
extern void ds_shuchu( const DASHU * const p_ds )
{
int * const t = p_ds->gw_sz , *w = t + WEISHU - 1 ;
while( w > t && *w == 0 ){ //高位0不输出
w--;
}
while( w > t ){
printf( "%d" , * w -- );
}
printf( "%d\n" , * t ) ;
}
//在*p_ds中写入n
extern void ds_fuzhi ( DASHU * const p_ds , const int n )
{
p_ds->gw_sz[0] = n ;
//可能有进位,同时把高位写为0
{
int *t = p_ds->gw_sz , //指向 p_ds->gw_sz[0]
*w = t + WEISHU - 1 ; //指向 p_ds->gw_sz[WEISHU-1]
while( t < w ){
*( t + 1 ) = * t / JINZHI ;
* t ++ %= JINZHI ;
}
}
}
期间对ds_shuchu(), ds_jiaru()进行了测试,均通过。
最后,修改main(),重新测试qiongju()函数(求各位数字的一次方之和),通过。
至此完成了数字组合和大数运算有关的主要函数。