第六章、循环控制结构
6.1 常用的循环语句
从键盘输入n,然后输出1+2+3+···+n。
#include<stdio.h>
int main()
{
int i,n,sum;
scanf("%d",&n);
sum=0;
/*
for(i=0;i<=n;i++)
{
sum+=i;
}
*/
/*
i=0;
while(i<=n)
{
sum+=i;
}
*/
//do~while方法
i=1;
do
{
sum+=i;
}while(i<=n); //注意:这个循环它至少执行一次
printf("%d\n",sum);
}
空语句,常用于编写延时程序。
for(i-0;i<n;i++)
{
; //就一个分号
}
6.2 嵌套循环
输出1!+2!+3!·····。
#include<stdio.h>
int main()
{
int i,j,k,sum,n;
sum=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
k=1;
for(j=1;j<=i;j++)
{
k*=j
}
sum+=k;
}
/*
for(i=1;i<=n;i++)
{
k=k*i;
sum+=k;//不用嵌套循环
}
*/
printf("%d\n",sum);
}
6.3?条件控制循环
猜数游戏。
#include<time.h>
#include<stdio.h>
int main()
{
int magic,guess,counter=0;
//srand(time(NULL));设置随机数种子,包含头文件time
unsigned int seed;
scanf("%u",&seed);
srand(seed); //输入一个随机种子,包含头文件stdlib
magic=rand()%100+1;//猜1~100的数
do
{
scanf("%d",&guess);
/*
ret=scanf("%d",&guess);
while(ret!=1) //输入有误,重新输入
{
while(getchar()!='\n'); //清除缓冲区非法字符
ret=scanf("%d",&guess); //再一次输入
}
*/
counter++;
if(guess>magic)
printf("big!\n");
else if(guess<magic)
printf("small!\n");
else
printf("Yes!\n");
}while(guess!=magic);
//while(guess!=magic&&couter<10);//猜不对且未超过10次继续猜
printf("counter=%d\n",counter);
}
6.4?流程的转移控制
读入5个正整数并显示他们,输入负数时,程序终止。
#include<stdio.h>
int main()
{
int i,n;
for(i=0;i<5;i++)
{
scanf("%d",&n);
if(n<0)
goto END;//goto语句要少用,除非要跳出多重循环。
//break; //直接跳出for循环。
//continue;//跳过下面的语句,不跳出循环
printf("%d\n",n);
}
END:printf("program is end!");
}
6.5 课后习题
穷举法编程实例。
士兵排队报数,从1到5,多1个;从1到6,多5个;从1到7,多4个;从1到11,多10个;有多少个兵?
#include<stdlib.h>
#include<stdio.h>
int main()
{
int i,flag;
flag=0;
for(i=1;!flag;i++)
{
if(i%5==1&&i%==5&&i%7==4&&i%11==10)
{
printf("%d\n",i);
flag=1;
}
}
}
类型溢出问题。
#include<stdio.h>
int main()
{
short i,sum=0;
for(i=1;;i++)
{
sum+=i*i*i;
if(sum>=1000000)
break;
}
printf("%d\n",i);//short只有两个字节,最大32767,发生了溢出
}
一般可以用long int。但是巨大无比的大数,超过了long long int,可考虑用数组来存储大数,每个数组元素对应大数的一位。
计算e=1+1/1!+1/2!+1/3!+···+1/n!,直到最后一项小于10^-5。
#include<stdio.h>
#include<math.h>
int main()
{
int i,n;
double j,e;
j=1;e=1;i=1
scanf("%d",&n);
while(fabs(j)<1e-5)
{
j*=(double)(1/(i));
e+=j;
i++;
}
printf("%lf\n",e);
}
第七章、函数
7.1函数的相关问题
求一个数的阶乘
#include<stdio.h>
int fun(int n);//函数的声明,函数的定义放在main()后要加声明,
//否则不用。注意函数的声明要加一个分号;
int main()
{
int n,m;
scanf("%d",&n);
m=fun(n);
if(m==-1)
{
printf("error!\n");
}
else
{
printf("%d\n",m);
}
}
int fun(int n)
{
int i;
int result=1;
if(n<0)
{
return -1;//对非法值进行检验
}
else
{
for(i=2;i<=n;i++)
{
result*=i;
}
}
return result;
}
利用递归的方法求n!
#include<stdio.h>
int fun(int n);
int main()
{
int n;
long result;
scanf("%d",&n);
result=fun(n);
if(result==-1)
{
printf("error!\n");
}
else
{
printf("%d\n",result);
}
}
int fun(int n)
{
int i;
if(n<0)
return -1;
else if(n==0||n==1)
return 1;
else
return n*fun(n-1);
}
7.2变量的作用域和存储类型
用递归的方法输出Fibonacci数列,同时计算每一项递归的次数。
#include<stdio.h>
int count;//定义了一个全局变量,用来记录递归的次数,初始化为0;
//全局变量的作用域为整个程序;
long Fib(int n)
{
count++; //记录每次递归的次数
if(n==0)
return 0;
else if(n==1)
return 1;
else
return (Fib(n-1)+Fib(n-2));
}
int main()
{
int n,i,x;
scanf("%d",&n);
for(i=0;i<=n;i++)
{
count=0; //自动清零
x=Fib(n);
printf("Fib(%d):%d,count=%d",i,x,count);
}
}
变量的存储类型:自动变量;静态变量;外部变量;寄存器变量。
自动变量:auto int tmp; auto可以省略不写 函数内部定义都是局部变量(包括main函数),局部变量(包括形参)都是自动变量,进入语块时自动申请内存,退出语块时自动释放内存。正因如此,在不同的并列语句块内可以定义同名变量,不会相互干扰 因为他们占据不同的内存单元,并且有着不同的作用域。 ?
#include<stdio.h>
void swap(int a,int b) //这里的a,b与main函数里面的a,b不同。
{ //如果希望形参不被修改,可以在形参前面加一个const,声明为常量。
int tmp;
tmp=a;a=b;b=tmp;
printf("a=%d,b=%d\n",a,b);
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
swap(a,b); //将实参的一个副本传给了被调函数,实参并不能被修改。
printf("a=%d,b=%d\n",a,b);
}
输出: 15 8 a=8,b=15 a=15,b=8
静态变量:static 类型名 变量名;
- 自动变量在定义时不会自动初始化,而静态变量定义同时初始化为0
- 自动变量在退出函数后,其分配的内存会立即释放,静态变量退出函数后内存不会释放,静态的局部变量的值可以保持到下一次进入函数时
- 静态局部变量只能在它的函数内访问,静态全局变量可以在它文件的任何地方进行访问。
#include<stdio.h>
long fun(int n)
{
static int p=1;//定义静态局部变量
p*=n; //若不加static,每次p都会重置为1
return p;
}
int main()
{
int i,n;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("%d!=%d\n",i,fun(i));
}
}
输出: 3 1!=1 2!=2 3!=6
外部变量:所有函数之外的变量,外部变量也是全局变量,作用域从定义处到本文件的末尾。要在定义之前或者其他文件中使用,需要:(extern 类型名 变量名) 进行声明,才可以使用。 寄存器变量:register 类型名 变量名 对频繁访问的数据放在CPU中,使程序执行地更快
7.3课后习题
求两个正整数的最大公约数。
欧几里得算法:对于正整数a和b,连续进行求余运算,直到余数为零,此时非零的除数就是最大公约数。 递归的方法:
- a>b,a-b和b最大公约数相同,fun(a,b)=fun(a-b,b)
- a<b,b-a和a最大公约数相同,fun(a,b)=fun(a,b-a)
- a=b,a和b最大公约数相同,fun(a,b)=a=b
#include<stdio.h>
/*
int fun(int a,int b)
{
int c,d;
c=0;d=1;
if(a<b)
{
c=a;a=b;b=c;
}
while(d!=0)
{
d=a%b;
if(d!=0)
{
a=b;b=d;
}
}
return b;
}
*/
int fun(int a,int b)
{
if(a==b)
{
return a;
}
else if(a>b)
{
return (fun(a-b,b));
}
else
{
return (fun(a,b-a));
}
}
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c=fun(a,b);
printf("%d\n",c);
return 0;
}
5个人分椰子,第一个把椰子分为5等份,还剩下一个给猴子,自己拿了一份;第二个把剩下的椰子分为5等份,还剩下一个给猴子,自己拿了一份;以此类推,直到五个水手都分完。计算并输出这堆椰子至少有多少个?
#include<stdio.h>
int main()
{
int i,n;
double j,k;
i=0;
while(1)
{
n=0;
k=i*5+1;
while(n<4)
{
k=(k/4)*5+1;
if(k!=(int)k)
{
break;
}
n++;
}
if(n==4)
{
break;
}
else
{
i++;
}
}
printf("k=%d\n",k);
return 0;
}
|