C语言 第六章 函数程序设计代码总结
Ⅰ基础部分
1.用户函数方法计算表达式a!+b!+c!的值。
有返回值,要先赋值,调用出现在表达式
#include<stdio.h>
int main()
{
long f(int n);
int a,b,c;
printf("input");
scanf("%d,%d,%d",&a,&b,&c);
printf("sum=%d\n",f(a)+f(b)+f(c));
return 0;
}
long f(int n)
{
long t;
int i;
for(t=1,i=1;i<=n;i++)
t*=i;
return t;
}
2.定义连续输出n个"*"字符的函数
void类型,直接调用函数,无返回值。
#include<stdio.h>
#define N 6
int main()
{
void p_star(int n);
int i;
for(i=1;i<=N;i++)
{
p_star(i);
printf("\n");
}
return 0;
}
void p_star(int n)
{
int i;
for(i=1;i<=n;i++)
printf("*");
}
3.定义求两个实数的最大数函数 max()
每个数据,要通过数据类型名称的格式再用逗号隔开
#include<stdio.h>
int main()
{
int max(int x,int y);
int x,y;
scanf("%d,%d",&x,&y);
printf("%d",max(x,y));
return 0;
}
int max(int x,int y)
{
int m;
m=(x>y)?(x):(y);
return m;
}
4.定义能对表达式 求值的函数sum()。
#include<stdio.h>
int main()
{
int sum(int x);
int x;
scanf("%d",&x);
printf("%d",sum(x));
return 0;
}
int sum(int x)
{
int s=0,i;
for(i=1;i<=x;i++)
s+=i;
return s;
}
函数调用
一般格式 :函数名(实参)例:f(a)
注意:在进行函数调用之前,必须对被调用函数进行函数声明
一般形式:函数类型 函数名(数据类型1 形参1,数据类型2 形参2,....数据类型n 形参n);
简化形式:函数类型 函数名(数据类型1 ,数据类型2 ,....数据类型n);
函数调用注意事项:
1函数调用的实参个数必须与形参个数相同。
2实参与形参按照在参数表中的位置一一对应传值,实参与形参的名称是否相同对调用传值无任何影响。
3实参与形参对应位置上的数据类型应该一致。
4对于无参数函数,即形参表为void的函数,函数调用时实参表必须为空,不能有任何内容。
函数调用的三种形式
1.当被调用的函数为void类型时,函数无返回值,函数调用是一个独立的语句。
2.当被调用的函数有返回值时,函数调用出现在的表达式中,是表达式中的一部分。
3.函数调用也可以做为一个函数的实参。
5.调用(3)求3个数的最大数
#include<stdio.h>
int main()
{
int max(int x,int y);
int x,y,z;
scanf("%d,%d,%d",&x,&y,&z);
printf("%d",max(max(x,y),z));//函数调用作为函数的实参
return 0;
}
int max(int x,int y)
{
int m;
m=(x>y)?(x):(y);
return m;
}
6.编写连续输出n个任意字符的函数p_string(),并调用该函数输出一个5行的"*"三角形图案
函数原型中的形参是可以省略掉的。
#include<stdio.h>
int main()
{
void p_string(int,char);
int i;
for(i=1;i<=5;i++)
{
p_string(i,'*');
printf("\n");//或者putchar('\n');
}
return 0;
}
void p_string(int n,char ch)
{
int i;
for(i=1;i<=n;i++)
putchar(ch);
}
Ⅱ 函数嵌套和递归函数
函数嵌套
函数嵌套是在一个用户函数的函数体中,出现另外用户函数的调用。如函数a调用函数b,函数b又调用函数c等
1.定义输出"*"三角形图案的函数,并在主函数中调用该函数输出一个5行的"*"三角形图案,其中每行"*"字符串的输出也要通过用户函数实现。(函数嵌套)
#include<stdio.h>
#define N 6
void p_star(int);
void p_all(int);
int main()
{
p_all(N);
return 0;
}
void p_star(int n)
{
int i;
for(i=1;i<=n;i++)
printf("*");
}
void p_all(int m)
{
int i;
for(i=1;i<=m;i++)
{
p_star(i);
putchar('\n');
}
}
递归函数
递归函数是由递归定义产生的,若在定义一个函数的过程中直接或间接地调用了被定义的函数本身,那么这种定义就是递归定义,所定义的函数称为递归函数。
分为两类:公式递归问题,非公式递归问题。
2. 用递归函数计算累加和(公式递归问题)
能够使用一个递归公式描述的问题归类为公式递归问题,公式递归问题实现起来比较容易,只要给出了递归公式就能直观地编写递归函数。
归结为以下两个步骤:(1)用递归公式描述问题。(2)将递归公式函数化。
#include<stdio.h>
int main()
{
long sum(int);
int n;
printf("n=");
scanf("%d",&n);
printf("sum=%ld\n",sum(n));
return 0;
}
long sum(int n)
{
if(n==1)
return(1);
else
return(sum(n-1)+n);
}
3.汉诺塔问题(非公式递归问题)
有的问题不能直接用一个递归公式进行描述,但可以用递归方法进行描述。
有3个柱子和n个大小各不相同的盘子,开始时所有的盘子以塔状叠放在柱A上,要求按一定规则将柱A上的所有盘子移动到柱B上,柱C为移动缓冲柱。移动规则如下:
1)一次只能移动一个盘子。
2)任何时候不能把盘子放在比它小的盘子上面。
步骤:
#include<stdio.h>
int main()
{
int disks;
void hanoi(int,char,char,char);//分隔符
printf("number of disks:");
scanf("%d",&disks);
printf("\n");
hanoi(disks,'A','B','C')//单引号
return 0;
}
void hanoi(int n,char A,char B,char C)//a柱移动到b柱,c为缓冲柱
{
if(n==1)
{
printf(" %c --> %c ",A,B);
return;
}
else
{
hanoi(n-1,A,C,B);
printf(" %c --> %c ",A,B);
hanoi(n-1,C,B,A);
}
}
Ⅲ 数组与函数
数组元素做函数参数(传值调用)
数组元素作为函数的参数时,只传送作为实参的数组元素,与其他简单变量作函数参数没有区别。
题目:设计一个判断素数的函数,在主函数中调用它,把一个整数数组的所有素数找出来。
if (1) printf("这部分会打印"); if (0) printf("这部分不打印");
#define N 10
#include<stdio.h>
#include<math.h>
int main()
{
int prime(int);
int i,natural[N];
printf("data:");
for(i=0;i<N;i++)
scanf("%d",&natural[i]);
printf("result:");
for(i=0;i<N;i++)
if(prime(natural[i]))
printf("%d",natural[i]);
printf("\n");
return 0;
}
int prime(int k)
{
int sk,i;
sk=(int)sqrt(k);
for(i=2;i<=sk;i++)
if(k%i==0)return 0;/*非素数返回0,素数返回1.*/
return 1;
}
一维数组名作函数参数(传址调用)
定义求一维数组最大元素值的函数v_max(),并在主函数中调用它求某个数组中的元素最大值
#include<stdio.h>
#define N 10
int main()
{
int v_max(int a[N]);/*省略形式[]*/
int i,data[N];
printf("data:");
for(i=0;i<N;i++)
scanf("%d",&data[i]);
printf("max= %d\n",v_max(data));//一维数组名作函数参数
return 0;
}
int v_max(int a[N])
{
int i,max=a[0];/*初始化*/
for(i=1;i<N;i++)
if(max<a[i])max=a[i];
return max;
}
改进
#include<stdio.h>
#define N 10
int main()
{
int v_max(int [],int);
int i,data[50];
printf("data:");
for(i=0;i<N;i++)
scanf("%d",&data[i]);
printf("max= %d\n",v_max(data,N));
return 0;
}
int v_max(int a[],int n)
{
int i,max=a[0];
for(i=1;i<n;i++)
if(max<a[i])max=a[i];
return max;
}
输入一个字符串,统计其中数字字符的个数,具体统计过程通过用户函数实现。
#include<stdio.h>
#define N 100
int main()
{
char string[N];
int count_s(char []);
gets(string);
printf("Total: %d\n",count_s(string));
return 0;
}
int count_s(char str[])
{
int i,count;
for(i=0,count=0;str[i]!='\0';i++)
if(str[i]>='0'&&str[i]<='9')
count++;
return count;
}
二维数组与函数
二维数组在内存中是按行逐列存储的,各个数组元素依次占用连续的存储单元,存储后的状态与一维数组没有区别。因此,按照存储情况,可使用一个一维数组对应表示二维数组。
1.二维数组example由两行组成,每行可视为一个元素,分别用example[0]和example[1]表示,因此example可视为由example[0]和example[1]两个元素构成的一维数组,而example[0],example[1]又可视为分别存储二维数组example各行元素的一维数组。数组example的首地址可用example[0]表示。example与example[0]一样。
2.若把一维数组p映射到m×n的二维数组example的存储空间,则二维数组元素和一维数组元素有如下对应关系:example[i][j]对应于p[i*n+j],例如example[1][0]对应于p[3]。n:一行有几个元素。
题目:求下列3×4矩阵的所有元素的和。
#include<stdio.h>
int main()
{
int sum_array(int [],int,int);
int arr[3][4]={{16,27,8,-6},{-17,21,5,19},{66,9,58,86}};
printf("sum = %d\n",sum_array(arr[0],3,4));
return 0;
}
int sum_array(int a[],int m,int n)
{
int i,s=0;
for(i=0;i<m*n;i++)
s+=a[i];
return s;
}