c语言
本练习假设:整数int为4字节,运行环境为VC
一、整数位数有关的问题
1、输入一个整数,判断它是几位数?
#include <stdio.h>
void main()
{
int a,n=0;
scanf("%d",&a);
{
a/=10;
n++;
}
printf("%d\n",n);
}
扩展:编制一个函数,参数为整数,返回该整数的位数。
{
int n=0;
while(a>0)
{
a/=10;
n++;
}
return n;
}
2、编制一函数,得到一个整数的某一位的数字。
int digit(int a,int n) /*返回:整数a的倒数第n位数,n从1开始*/
{
答案在后面思路:如何将倒数第n位用一个表达式取出?不能!转变成怎样后就能? while(n>1)
{
a/=10;
n--;
}
return a%10;
}
测试函数的例子:
#include <stdio.h>
int digit(int a,int n);
void main()
{
int a,n,d;
scanf("%d%d",&a,&n);
d=digit(a,n);
printf("%d\n",d);
}
二、关于整数的几个题目
1、输入两个正整数m和n,求其最大公约数和最小公倍数。
算法分析:采用辗转相除法,先求出最大公约数d,然后求最小公倍数c=m*n/d。
辗转相除法:余数=大数%小数,然后将小数和余数再作辗转相除。
#include <stdio.h>
void main()
{
int m,n,a,b,d,c;
scanf("%d,%d",&m,&n);
if(m>n){a=m;b=n;} /*保证a>b*/
else {a=n;b=m;}
while((d=a%b)>0) /*每次循环都测试余数是否为0*/
{
a=b;b=d;
}
d=b; /*得到最大公约数*/
c=m*n/d; /*得到最小公倍数*/
printf("最大公约数是%d\n最小公倍数是%d\n",d,c);
}
拓展:编出求最大公约数的函数。
int mcd(int a,int b)
{
int d,t;
if(a<b){t=a;a=b;b=t;} /*保证a>b*/
while((d=a%b)>0) /*每次循环都测试余数是否为0*/
{
a=b;b=d;
}
return b; /*得到最大公约数*/
}
测试上述函数:
#include <stdio.h>
int mcd(int a,int b);
void main()
{
int m,n,d,c;
scanf("%d,%d",&m,&n);
d=mcd(m,n);
c=m*n/d;
printf("最大公约数是%d\n最小公倍数是%d\n",d,c);
}
2、求出所有的水仙花数。水仙花数是一个三位数,其各位数字的立方和等于该数。例如153=1^3+5^3+3^3。
#include <stdio.h>
void main()
{
int s,a,b,c;
for(s=100;s<=999;s++)
{
a=s%10; b=s/10%10;c=s/100; /*分解出每一位*/
if(a*a*a+b*b*b+c*c*c==s)
printf("%d\n",s);
}
}
按位循环:
#include <stdio.h>
void main()
{
int s,a,b,c;
for(a=0;a<=9;a++)
for(b=0;b<=9;b++)
for(c=1;c<=9;c++)
{
s=c*100+b*10+a;
if(a*a*a+b*b*b+c*c*c==s)
printf("%d\n",s);
}
}
类似地:可以求出100以内的勾股数,如3^2+4^2=5^2。
三、关于数组的几个题目
求2100的精确值。
参考:
#include <stdio.h>
void main()
{
double s=1.0;
int i;
for(i=1;i<=100;i++)
s*=2;
printf("%f\n",s);
}
运行结果:
1267650600228229400000000000000.000000
后面十多位全是0,因此是近似值。
如何求精确值呢?(关键是如何保存每一位)
#include <stdio.h>
void main()
{
int i,j,m=0; /*m指示最高位为s[m]*/
for(i=1;i<=100;i++)
{
for(j=0;j<=m;j++)
s[j]*=2;
for(j=0;j<=m;j++) /*检查进位*/
if(s[j]>9) /*第j位需要进位*/
{
s[j+1]+=s[j]/10;
s[j]%=10;
if(j+1>m) m=j+1; /*最高位进位*/
}
}
printf("2^100 = ");
for(j=m;j>=0;j--)
printf("%d",s[j]);
printf("\n");
}
运行结果:
2^100 = 1267650600228229401496703205376
扩展问题:如何求出100!的精确值?
缺陷:如果乘以一个很大的数如20亿,会使高一位与进位相加后溢出。
四、大数运算
用整数数组存放每一位,最高位用-1存储,如12存为:a[0]=2,a[1]=1,a[2]=-1。
1、输入和存储大数。
编制一函数,将合法数字组成的字符串表示的大数按位拆分存储到整数数组中,最高位前存储-1。
/*转换大数:将字符串c中的数字保存到整数数组a中,a最高位添加-1标志*/
void LargeSet(char *c, int *a)
{
char *p;
for(p=c;*p!='\0';p++); /*找到末尾作为最低位*/
p--;
for(;p>=c;p--,a++)
*a=*p-'0';
*a=-1;
}
2、输出和获得数字串。
编制一函数,将大数转换成字符串。
/*转换大数:将大数a转换成字符串存入字符数组c中*/
void LargeGet(char *c, int *a)
{
int *p;
for(p=a;*p>=0;p++);
p--;
for(;p>=a;c++,p--)
*c=*p+'0';
*c='\0';
}
3、大数相加。
编制一函数,实现两个大数相加。
void LargeAdd(int *a, int *b, int *s) /*大数相加:s=a+b*/
{
int ka=0,kb=0;
for(*s=0;ka==0||kb==0;s++)
{
if(*a<0) ka=1;
if(*b<0) kb=1;
if(ka==0) {*s+=*a; a++;}
if(kb==0) {*s+=*b; b++;}
if(*s>9) {*(s+1)=1;*s%=10;}
else *(s+1)=0;
}
if(*s>0) *(s+1)=-1;
else if(*(s-1)>0) *s=-1;
else *(s-1)=-1;
}
验证上面的函数:
#include <stdio.h>
void LargeSet(char *a, int *s);
void LargeGet(char *a, int *s);
void LargeAdd(int *a, int *b, int *s);
void main()
{
int a[100],b[100],s[100];
char c[100];
scanf("%s",c);
LargeSet(c,a);
scanf("%s",c);
LargeSet(c,b);
LargeAdd(a,b,s);
LargeGet(c,s);
printf("sum is %s\n",c);
}
运行结果:
12345678901234567890
12345678901234567890
sum is 24691357802469135780
扩展:可以编制大数相减、相乘、相除、乘方、开方等运算。有了这些运算,计算100!或2的100次方的精确值将变得很简单。
资源链接
标签
发布日期
2016-08-01
擦亮日期
2016-08-01