苏小红C语言(函数、数组、指针)
7.1 n!直接用累乘的方法来求
long fact(int n)
{
int i;
long result=1;
if(n<1)return 0;
for(i=1;i<n+1;i++)
{
result=result*i;
}
return result;
}
int main()
{
int n;
long result;
printf("input a number:");
scanf("%d",&n);
result=fact(n);
if(result==0)
printf("error");
else
printf("%ld",result);
return 0;
}
7.2求组合数
int main()
{
int m,k;
long result;
do
{
printf("input two numbers:");
scanf("%d %d",&m,&k);
}while(m<k||m<=0||k<0);//while 后面必须加;
result=fact(m)/(fact(k)*fact(m-k));
printf("%ld",result);
return 0;
}
7.3 利用递归来写阶乘函数
long fact(int n)
{
if(n==1)
return 1;
else
return n*fact(n-1);
}
7.4计算fib数列以及递归次数
#include <stdio.h>
#include <stdlib.h>
int count;
//求递归的次数
long fib(int n)
{ count++;
if(n==1)return 1;
if(n==0)return 0;
else if(n>1)return (fib(n-1)+fib(n-2));
}
int main()
{
int n;
long result;
printf("input a number:\n");
scanf("%d",&n);
result=fib(n);
printf("fib(%d)=%ld,count=%d",n,result,count);
return 0;
}
7.5形参与实参之间的区别
int Swap(int m,int n)
{
int temp;
temp=m;
m=n;
n=temp;
printf("a=%d b=%d\n",m,n);
return 0;
}
int main()
{
int a,b;
printf("input a and b:\n");
scanf("%d %d",&a,&b);
Swap(a,b);//只是把ab的值传递给了形参mn
printf("a and b is %d %d",a,b);
return 0;
}
7.6利用局部变量来写递归
//静态局部变量的使用方法,
//在再一次调用这个变量时,并不会因为圆的函数被释放而被释放,
//静态局部变量存储在存储器中
long fact(int n)
{
static long p=1;//这个仅仅是定义,而不会再一次进行赋值
p=p*n;
return p;
}
int main ()
{
int n,i;
printf("input n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("%d!=%ld\n",i,fact(i));
}
return 0;
}
7.7静态变量
//程序中竟然同时出现了i,一个在内存,一个是寄存器
#include <stdio.h>
#include <stdlib.h>
//外面的i通过寄存器存储器存储而静态局部变量存储在内存中
int square(int i)
{
return i*i;
}
int main()
{
int i=0;
i=square(i);
for(;i<3;i++)
{
static int i=1;
i+=square(i);
printf("%d,",i);
}
printf("%d\n",i);
return 0;
}
7.8时钟模拟
int hour,minute,second;
void Update()
{
second++;
if(second==60)
{
second=0;
minute++;
}
if(minute==60)
{
minute=0;
hour++;
}
if(hour==24)
{
hour=0;
}
}
void Delay()
{
int t;
for(t=0;t<1000;t++);//什么都不做的时候这儿要加;
}
void display()
{
printf("time=%d:%d:%d\n",hour,minute,second);
}
int main()
{
int i;
int second=0,minute=0,hour=0;
for(i=0;i<1000000;i++)
{
Update();
display();
Delay();
}
return 0;
}
7.9练习题7.4求最小公倍数
#include <stdio.h>
#include <stdlib.h>
//最小公倍数函数
int mingb(int m ,int n)
{
int temp=1;
int x=m>n?m:n;
while(temp)
{
if((x%m==0)&&(x%n==0))
temp=0;
else
x++;
}
return x;
}
int main()
{
int a,b;
int result;
printf("input two numbers:\n");
scanf("%d %d",&a,&b);
result=mingb(a,b);
printf("min GBS is%d\n",result);
return 0;
}
7.10 利用三种方法来求最小公约数
穷举法:从最小的那个数开始逐个减去1;
欧几里得算法
int maxgys(int a,int b)
{
int r;
do
{
r=a%b;
a=b;
b=r;
}while(r!=0);
return a;
}
递归方法
int maxgys(int a,int b)
{
if(a==b)return a;
else if(a>b)return maxgys(a-b,b);
else return maxgys(a,b-a);
}
7.11 小岛分桃子
//递归用for的方法来进行迭代
int yz(int n)
{
int i;
float x=0;
float y;
do{
x++;
y=n*x+1;
for(i=1;i<5;i++)
{
y=y*n/(n-1)+1;
if(y!=(int)y)break;
}
}while(i<5);
return y;//应该是默认的成为了int
}
int main()
{
int n=5;
int result;
result=yz(n);
printf("people numbers are:%d\n",result);
return 0;
}
7.12递归求年龄
所谓的递归,不过是问题中包含着同样的问题
int age(int n)
{
if(n==1)return 10;
else return(2+age(n-1));
}
int main()
{
int n=5;
printf("5 person age is =%d",age(n));
}
7.13 魔术猜数字
int moshu(int sum)
{ int a,b,c;
int x;
int y;
for(a=1;a<=9;a++)
{
for(b=0;b<=9;b++)
{
for(c=0;c<=9;c++)
{ x=a+b+c;//放到上面不行啊
y=100*a+10*b+c;
if((111*2*x-y)==sum)
return y;
}
}
}
return -1;
}
int main(){
int sum,result;
printf("the sum is :");
scanf("%d",&sum);
result=moshu(sum);
if(result==-1)printf("error");
else printf("the number=%d\n",result);
return 0;
}
7.14数30的游戏
int i=0;//用了全局变量是不是说明这些全部都是i了?
int shaizi()
{
int a;
a=rand()%2+1;
return a;
}
void diannao()
{
int n;
int m;
m=(30-i)%3;
if(m==1)
{
n=1;
}
else if(m==2)
{
n=2;
}
else
n=shaizi();
i=i+n;
printf("computer input n=%d, i=%d\n",n,i);
}
void mychoice()
{
printf("input your number:");
int n;
scanf("%d",&n);
i=i+n;
}
int main()
{
while(i<30)
{
mychoice();
if(i==30)
{printf("you win");
return 0;}
diannao();
if(i==30)
{printf("you lose");
return 0;}
}
}
7.15拒绝使用全局变量
//拒绝使用全局变量
int shaizi()
{
srand(time(NULL));
return rand()%2+1;;
}
int diannao(int i)
{
int n;
int m;
m=(30-i)%3;
if(m==1)
{
n=1;
}
else if(m==2)
{
n=2;
}
else
n=shaizi();
i=i+n;
printf("computer input n=%d, i=%d\n",n,i);
return i;
}
int mychoice(int i)
{ int n;//一定要拿在最上面,放到循环里面肯定不行的
do
{
printf("input your number:");
scanf("%d",&n);
if(n>2||n<1)
{printf("error,try again\n");}
}while(n>2||n<1);
i=i+n;
return i;
}
int main()
{ int i=0;
if(shaizi()==1)
{
i=diannao(i);
}
while(i<30)
{
i=mychoice(i);
if(i==30)
{printf("you win");
return 0;}
i=diannao(i);
if(i==30)
{printf("you lose");
return 0;}
}
}
7.16汉诺塔递归
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void move(char a,char b)
{
printf("from %c to %c\n",a,b);
}
void hanoi(int n,char a,char b,char c)
{
if(n==1)
move(a,b);
else
{
hanoi(n-1,a,c,b);
move(a,b);
hanoi(n-1,c,b,a);
}
}
int main()
{
int n;
char a='A',b='B',c='C';
printf("input the number on %c",a);
scanf("%d",&n);
hanoi(n,a,b,c);
}
8.1闰年月份
注意好,定义数组时不能使用变量,数组一旦被定义,便无法再去更改大小。
输出月份,注意好数组本身是从0开始的,不要忘记o
#include <stdio.h>
#include <stdlib.h>
#define MONTHS 12
int main()
{
int month;
int year;
int a[2][MONTHS]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
do{
printf("input year and months:\n");
scanf("%d%d",&year,&month);
if(year%4==0)
{
printf("the number is %d\n",a[1][month-1]);
}
else
printf("the number is %d\n",a[0][month-1]);
}while(month>0&&month<=12);
}
8.2 尝试输出首地址
int main()
{
int a=1,c=2,b[5]={0},i;
printf("%d,%d,%d\n",b,&c,&a);
for(i=0;i<=8;i++)
{
b[i]=i+1;
printf("%d\t",b[i]);
}
printf("\n&b=%d and b=%d and *b=%d and b[0]=%d\n",&b,b,*b,b[0]);
}
8.3
数组二维长度永远都不可以进行省略,将数组作为实参传递给函数
#include <stdio.h>
#include <stdlib.h>
#define N 40
int read(long num[],float score[],int n)
{
int i;
printf("input number and score:\n");
for(i=0;i<n;i++)
{
scanf("%ld%f",&num[i],&score[i]);
}
return 0;
}
float aver(float score[],int n)
{
float result=0;
int i;
for(i=0;i<n;i++)
{
result+=score[i];
}
return result/n;
}
int main()
{
long num[N];
float score[N];
int n;
float result;
printf("input student n :");
scanf("%d",&n);
read(num,score,n);
result=aver(score,n);
printf("the average=%.2f\n",result);
return 0;
}
8.4 未知人数的数组设置
上述的例子中,人数n是已知的,如果n并不知道如何求呢?直接做一个标记位如何呢?
int read(float score[])
{
int i=-1;
printf("input the score:\n");
do
{
i++;
scanf("%f",&score[i]);
}while(score[i]!=-1);
return i`;
}
float aver(float score[],int n)
{
float result=0;
int i;
for(i=0;i<n;i++)
{
result+=score[i];
}
return result/n;
}
int main()
{
float score[N];
int n;
float result;
do
{
printf("input score :");
n=read(score);
if(n>N)
printf("error");
}while(n>N);
result=aver(score,n);
printf("the average=%.2f\n",result);
return 0;
}
8.5 选择冒泡交换
#define N 40
int read(int a[])
{
int i=-1;
printf("input the score:\n");
do
{
i++;
scanf("%d",&a[i]);
}while(a[i]!=-1);
return i;
}
int aprintf(int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
return 0;
}
//交换法升序排序
int jhsort(int a[],int n)
{
int i,j;
float temp;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
return 0;
}
//选择法排序
int xzsort(int a[],int n)
{
int i,j;
int k=0;
int temp;
for(i=0;i<n-1;i++)
{
for(j=i;j<n;j++)
{
if(a[j]<a[k])
{
k=j;
}
}
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
return 0;
}
//冒泡法
int mpsort(int a[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
return 0;
}
int
int main()
{
int score[N];
int n;
n=read(score);
mpsort(score,n);
aprintf(score,n);
return 0;
}
8.6根据学号来查询成绩(线性查询)
#include <stdio.h>
#include <stdlib.h>
#define N 40
int read(int a[],long b[])
{
int i=-1;
printf("input number and score:\n");
do
{
i++;
scanf("%ld%d",&b[i],&a[i]);
}while(a[i]!=-1);
return i;
}
int aprintf(int a[],long b[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("the number is %ld and the score is %d\n",b[i],a[i]);
}
return 0;
}
//交换法升序排序
int jhsort(int a[],long b[],int n)
{
int i,j;
int temp_1;
long temp_2;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
temp_1=a[i];
a[i]=a[j];
a[j]=temp_1;
temp_2=b[i];
b[i]=b[j];
b[j]=temp_2;
}
}
}
return 0;
}
int searchnum(int a[],long b[],int n,long m)
{
int i;
for(i=0;i<n;i++)
{
if(b[i]==m)
return a[i];
}
return -1;
}
int main()
{
int score[N];
long num[N];
int n;
long m;
int result;
n=read(score,num);
printf("input your number:\n");
scanf("%ld",&m);
result=searchnum(score,num,n,m);
if(result>0)
{
printf("your score is %d",result);
}
else
printf("no the number!");
return 0;
}
8.7 折半查询方法
//这办法查询中,high、low变的时候,注意好+1-1
int zbsearchnum(int a[],long b[],int n,long m)
{
int low=0,high=n;
int middle;
while(low<=high)
{ middle=(high+low)/2;
if(b[middle]>m)
{
high=middle-1;
}
else if(b[middle]<m)//注意好是else if而不是if else
{
low=middle+1;
}
else return a[middle];
}
return -1;
}
8.8 二维数组存储多个学科
#include <stdio.h>
#include <stdlib.h>
#define STU_N 40
#define COU_N 3
int read(long a[],int b[][COU_N])
{
int i=-1;
int j;
printf("input your number and course as MT EN PH:\n");
do
{
i++;
scanf("%ld",&a[i]);
for(j=0;j<COU_N;j++)
{
scanf("%d",&b[i][j]);
}
}while(a[i]!=-1);
return i;
}
int stu_score(long a[],int b[][COU_N],int sum[],int aver[],int n )
{
int i,j;//无法使用变量来定义数组哦
for(i=0;i<n;i++)
{
for(j=0;j<COU_N;j++)
{
sum[i]+=b[i][j];
}
aver[i]=sum[i]/COU_N;
}
return 0;
}
int cou_score(long a[],int b[][COU_N],int sum[],int aver[],int n)
{
int i,j;
for(i=0;i<COU_N;i++)
{
for(j=0;j<n;j++)
{
sum[i]+=b[j][i];
}
aver[i]=sum[i]/COU_N;
}
return 0;
}
int print(int score[][COU_N],long num[],int n,int sumS[],int averS[],int sumC[],int averC[])
{
int i,j;
printf("Student's ID\tMT\tEN\tPH\tSUM\tAVER\n");
for(i=0;i<n;i++)
{ printf("%ld\t",num[i]);
for(j=0;j<COU_N;j++)
{
printf("%d\t",score[i][j]);
}
printf("%d\t%d\n",sumS[i],averS[i]);
}
printf("\nSumofcourse\t");
for(i=0;i<COU_N;i++)
{
printf("%d\t",sumC[i]);
}
printf("\naverofcourse\t");
for(i=0;i<COU_N;i++)
{
printf("%d\t",averC[i]);
}
return 0;
}
int main()
{
int score[STU_N][COU_N];
long num[STU_N];
int n;
int sumS[STU_N]={0};//注意好定义要用大括号哦
int averS[STU_N];
int sumC[COU_N]={0};
int averC[COU_N];
n=read(num,score);
stu_score(num,score,sumS,averS,n);
cou_score(num,score,sumC,averC,n);
print(score,num,n,sumS,averS,sumC,averC);
return 0;
}
8.8 矩阵乘积
#include <stdio.h>
#include <stdlib.h>
#define M 2
#define L 2
#define N 2
//计算C[M][N]=A[M][L]*B[L][N];
int read(int a[M][L],int b[L][N],int c[M][N])
{
int i,j;
printf("input a[][]:\n");
for(i=0;i<M;i++)
{
for(j=0;j<L;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("\ninput b[][]:\n");
for(i=0;i<L;i++)
{
for(j=0;j<N;j++)
{
scanf("%d",&b[i][j]);
}
}
return 0;
}
int jzcj(int a[M][L],int b[L][N],int c[M][N])
{
int i,j,k;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)//for 循环一直都是;别再写成,
{ c[i][j]=0;
for(k=0;k<L;k++)//一个分号引发的惨案
{
c[i][j]+=+a[i][k]*b[k][j];
}
}
}
return 0;
}
int print(int a[M][L],int b[L][N],int c[M][N])
{
int i,j;
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
printf("%3d\t",c[i][j]);
}
printf("\n");
}
return 0;
}
int main()
{
int a[M][L]={3,1,1,1};//只能赋值的时候定义?wr!
int b[M][L]={1,1,1,1};
int c[M][N]={0};
jzcj(a,b,c);
print(a,b,c);
return 0;
}
9.1 指针定义与初始化
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=0,b=1;
char c='A';
int *pa=&a;
int *pb;//不要上来使用未初始化的变量
pb=&b;
char *pc=&c;
*pa=100;
printf("a is %d &a is %p,pa is %p,&pa is %p\n",a,&a,pa,&pa);
//修改指针直接改变a的值
‘*9’printf("b is %d &b is %p,pb is %p,*pb=%d\n",b,&b,pb,*pb);
printf("c is %c &c is %p,pc is %p,*pc=%d\n",c,&c,pc,*pc);
return 0;
}
9.2 按值调用与模拟引用调用
按值调用是程序将函数的实参的一个副本传递给形参——实质为参数通过两个寄存器之间完成了传递
void FUN(int par)
{
printf("par=%d\n",par);
par=2;
}
int main()
{
int arg=1;
printf("arg=%d\n",arg);
FUN(arg);
printf("arg=%d\n",arg);
return 0;
}
void FUN(int *par)
{
printf("par=%d\n",*par);
*par=2;
}
int main()
{
int arg=1;
printf("arg=%d\n",arg);
FUN(&arg);//传递的参数实际上是地址,这就能将其进行改变了。
printf("arg=%d\n",arg);
return 0;
}
//当只传递一个参数的时候也可以通过return来传递
9.2swap交换函数
按值调用
int Swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
return 0;
}
int main()
{
int a,b;
printf("input a and b:\n");
scanf("%d%d",&a,&b);
Swap(a,b);
printf("%d,%d",a,b);
return 0;
}
模拟引用调用
int Swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
return 0;
}
int main()
{
int a,b;
printf("input a and b:\n");
scanf("%d%d",&a,&b);
Swap(&a,&b);
printf("%d,%d",a,b);
return 0;
}
9.3利用指针来做参数
#include <stdio.h>
#include <stdlib.h>
#define N 40
int read(long a[],int b[],int n)
{
int i;
printf("input number and score:\n");
for(i=0;i<n;i++)
{
scanf("%ld",&a[i]);
scanf("%d",&b[i]);
}
return 0;
}
int Max(long a[],int b[],int n,long *maxnum,int *maxscore)
{
int i;
int k=0;
for(i=0;i<n;i++)
{
if(b[i]>b[k])k=i;
}
*maxscore=b[k];
*maxnum=a[k];
return 0;
}
int main()
{
int n;
long num[N];
int score[N];
int maxscore;
long maxnum;
printf("input your number n:");
scanf("%d",&n);
read(num,score,n);
Max(num,score,n,&maxnum,&maxscore);
printf("%ld,%d",maxnum,maxscore);
return 0;
}
9.4 三种数组交换的方式
int read(int a[],int b[],int n)
{
int i;
printf("input number and score:\n");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
scanf("%d",&b[i]);
}
return 0;
}
int print(int a[],int b[],int n)
{
int i,j;
printf("a[]=");
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
printf("\nb[]=");
for(j=0;j<n;j++)
{
printf("%d\t",b[j]);
}
printf("\n");
return 0;
}
int swap1(int x,int y)
{
int temp;
temp=x;
x=y;
y=temp;
return 0;
}
int swap2(int *x,int *y)//用来传递了元素的地址咯
{
int temp;
temp=*x;
*x=*y;
*y=temp;
return 0;
}
int swap3(int a[],int b[],int n)//数组第一个元素本身就是指针
{
int i;
int temp;
for(i=0;i<n;i++)
{
temp=a[i];
a[i]=b[i];
b[i]=temp;
}
return 0;
}
int main()
{
int n,i;
int a[N];
int b[N];
printf("input your number n:");
scanf("%d",&n);
read(a,b,n);
print(a,b,n);
for(i=0;i<n;i++)
{
swap1(a[i],b[i]);
}
print(a,b,n);
return 0;
}
9.5 记录天数
int read(int *a,int *b,int *c)
{
printf("input year:\n");
scanf("%d",a);
printf("input month:\n");
scanf("%d",b);
printf("input day:\n");
scanf("%d",c);
return 0;
}
int howday(int a,int b,int c)
{
int twmonth[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
int i,flag;
int allday=0;
if(a%4!=0)flag=0;
else flag=1;
for(i=0;i<b-1;i++)
{
allday+=twmonth[flag][i];
}
allday=allday+c;
return allday;
}
int main()
{
int year=0,month=0,day=0;
int result;
read(&year,&month,&day);
result=howday(year,month,day);
printf("the day is %d",result);
}
9.6 年月日之间的换算
当需要返回两个值的时候,想到需要使用指针
#include <stdio.h>
#include <stdlib.h>
#define N 40
int twmonth[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
void menu(void)
{
printf("1.year/month/day/->day of year:\n");
printf("2.year/day->month/day:\n");
printf("3.exit\n");
printf("input your choice:\n");
}
int howday1(int year,int month,int day)
{
int i,flag;
int allday=0;
flag=(year%4==0);
for(i=0;i<month-1;i++)
{
allday+=twmonth[flag][i];
}
allday=allday+day;
return allday;
}
int howday2(int allday,int year,int *month,int *day)
{
int i,flag;
flag=(year%4==0);
for(i=0;allday>twmonth[flag][i];i++)
{
allday-=twmonth[flag][i];
}
*month=i+1;
*day=allday;
return 0;
}
int main()
{
int year,month,day,allday;
char c;
menu();
c=getchar();
switch(c)//这儿没有;
{
case '1':printf("please enter year month day:");
scanf("%d%d%d",&year,&month,&day);
allday=howday1(year,month,day);
printf("%d",allday);
break;
case '2':printf("please enter allday and year:");
scanf("%d%d",&allday,&year);
howday2(allday,year,&month,&day);
printf("month is %d and day is %d",month,day);
break;
case '3':exit(0);
default:printf("input error!");
}
}
9.6求解定积分
//注意好指针变量与指针函数的区别:
//int(*compare)(int a ,int b);的意思是定义了一个指针变量compare,其能够指向含有两个形参变量,返回类型为int的函数
//int *comare(int a,int b)本身是一个函数,其指向的类型为int *类型即,返回值是一个指向int类型的指针。
//整数类型之间如何强制转换的????
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float hanshu1(float x)
{
return(1+x*x);
}
float hanshu2(float x)
{
return(x/(1+x*x));
}
float selction(float(*f)(float), float a,float b)//因为allhansh里面的x用了a,b,因此不去表示
{
int i,n=100;
float h=(b-a)/n;
float s=0;
for(i=0;i<n;i++)
{
s=s+h*(*f)(a+i*h+h/2);
}
return s;
}
int main()
{
float a,b,c;
float y1,y2;
printf("input a and b and c:\n");
scanf("%f%f%f",&a,&b,&c);
y1=selction(hanshu1,a,b);
y2=selction(hanshu2,a,c);
printf("y1=%f",y1);
printf("y2=%f",y2);
return 0;
}