C6_函数

主要内容:函数分类、函数声明和定义、函数调用,形参实参、函数嵌套调用

函数是具有特定功能的代码段。
通俗来说:一连串语句组合在一起,实现了某一功能,我们为它们起了一个名字。之后就可以使⽤这个名字来替代这些语句。
函数的使用可以省去重复代码的编写,⼤大简化程序,提高开发效率。

一、函数的定义。

          返回值类型 函数名(形式参数列表) {


                            语句
                   return 返回值;
                         }

无参函数举例:

void hello(void)//⽆参数 无返回值
 {

printf(“Hello,Lanou”):
 

            }

int peopleCount(void)//无参数 有返回值
 {

          return 33;
 

              }

有参函数:

int max(int a,int b)//有参数 有返回值
 {

              return a>b?a:b;
 

          }
void printNumber(int x)//有参数 无返回值
 {

         printf(“number is %d”,x);
 

         }

返回值:

函数的返回值称为函数的值,只能通过return语句返回给主调函数。一个函数只能有一个返回值。
函数即使没有返回值也可以使用return来结束函数的执行, 回到主调函数。
 return后面的语句不再执⾏。

int main(int arc, char * arg[])!{


//函数上面的语句

sayHi();

//函数下面的语句

return 0;

}

形参(形式参数)
出现在函数定义中,以假名字来表示函数调用时需要提供的值。

实参(实际参数)

出现在函数调用中的表达式。

******************************************
注意:函数调用中,形参会拷贝实参内容,传递参数是给函数传送信息的一种方法。

函数声明:

严格的函数通常包括三部分:

函数声明、函数定义、以及函数调⽤用。
函数声明:指的就是函数的描述,也叫函数原型。
函数声明:
 1、函数定义出现在主调函数之前,可以省略函数声明。
 2、函数定义出现在主调函数之后,需要提前声明函数。
函数声明尽管可以省略,从规范来讲,不要省略。

头⽂文件 (xxxx.h)
函数声明一般写在头文件里。
实现⽂文件(xxxx.m)
函数定义一般写在实现文件里。
数组作为函数参数:
数组元素作为参数,与普通变量一样。
数组作为参数,把数组名传入,即数组的首地址。 
注意:此时,形参和实参实际上是同一段内存空间。

C语言不允许函数嵌套定义,但是允许函数嵌套调用。

C语⾔允许函数实现体内再次调用函数本身。这种调用方式称为递归调用,这个函数称为递归函数。
在计算机中阶乘就可以使用递归调用。
注意:递归一定要有出口。
变量的作用域。
注意:外部变量和局部变量可重名,但是在局部变量作用域内只能访问局部变量。
***总结
函数是具有特定功能的代码块。
函数能⼤大简化程序。
完整的函数包含3部分:声明、定义、调用。 函数调用时,会将实参拷贝给形参。
函数体内定义的变量是局部变量,函数体外定义的变量是全局变量。
作业:
//第一题(**)一维浮点型数组的冒泡排序函数

//浮点型冒泡排序函数
//void sort(float a[], int n)
//{
// for (int i = 0; i<n; i++) {
// scanf("%f",&a[i]);
// }
// for (int i =0;i<n-1; i++) {
// for (int j = 0;j<n-1-i ; j++) {
// if (a[j]>a[j+1]) { //判断大小
// int temp = a[j]; //换位
// a[j]=a[j+1];
// a[j+1]=temp;
// }
// }
// }
// for (int i=0; i<n; i++) {
// printf("%.2f ",a[i]); //打印排序过后的数组
// }
//}
//int main(int argc, const char * argv[])
//{
// float b[4];
// sort(b, 4);
// return 0;
//}


//第二题(***)编写实现 strlen 同功能的函数 stringLength。

//与strlen同功能,实现求数组长度功能
//int stringLength(char a[],int n)
//{
// n = 0;
// for (int i = 0; i < n+1; i++) {
// if (a[i] != '\0') {
// n++;
// }
// }
// printf("%d",n);
// return 0;
//}
//
//int main(int argc, const char * argv[])
//{
// int n = 0;
// char b[] ={"ksfhslkf"};
// stringLength(b, n);
// return 0;
//}


//第3题(***)编写实现 strcpy 同功能的函数 stringCopy。

//与strcpy同功能函数,实现数组复制功能
//char stringCopy(char a[],char b[],int n )
//{
// for (int i = 0; i<n; i++) {
// if (b[i]=='\0') {
// break;
// }
//
// a[i] = b[i];
// }
// printf("%s",a);
// return 0;
//}
//
//
//int main(int argc, const char * argv[])
//{
// char a[100]={"zhangkai"},b[20]={"zhangkaijie"};
// stringCopy(a, b,100);
// return 0;
//}


//第4题(***)编写实现 strcat 同功能的函数 stringCatch。

//与strcat 同功能的函数,实现数组拼接
//char stringCatch(char a[],char b[],int n )
//{
// for (int i = 0; i<n; i++) {
// if (a[i] == '\0') {
// a[i]=b[n];
// n++;
// }
// }
// printf("%s",a);
return 0;
}
//
//int main(int argc, const char * argv[])
{
// char a[100]={"zhangkaijie"},b[20]={"jie"};
// stringCatch(a, b, 100);
return 0;
}
//

//第5题(***)编写实现 strcmp 同功能的函数 stringCompare。

//与 strcmp 同功能的函数 , 实现比较两数组大小
//int stringCompare(char a[],char b[],int n)
//{
// for (int i = 0; i<n; i++) {
// if (a[i]-b[i]>0) {
// printf("正数");
// break;
// }else if (a[i]-b[i]<0){
// printf("负数");
// break;
// }
// }
//
// return 0;
//}
//
//int main(int argc, const char * argv[])
//{
// char a[100]={"zhangkaijie"},b[20]={"zhzae"};
// stringCompare(a, b, 100);
// return 0;
//}


/*第6题(****)模拟 ATM 机取款的过程
(1)、定义两个能保存 5 个整形数的数组,一个用于保存 5 个人的卡号,一 个用于保存对应卡号的密码。
(2)、判断输入的卡号是否在数组中。
(3)、如果在数组中就让输入密码,判断是否和卡号对应的密码匹配。
(4)、判断密码,24 小时内只允许输入 3 次 错误的密码。输入错误应该提示 还剩下的输入次数,3 次都输入错误提示 24 小时内不允许操作该卡。
(5)、密码正确就让用户对该账户进行相应的操作。
(6)、注意取款的限制。
(7)、上述功能对于一个 ATM 机是循环的过程,也就是说每个客户都会按照
上面的操作进行操作,一个用户操作完成,下一个用户来了还可以进行相应的
操作
*/
#import "ATM.h"

//int main(int argc, const char * argv[])
//{
// long datas[4][5] = {{20140812,20140813,20140814,20140815,20140816}, {123,456,789,112,345},{3,3,3,3,3},{1000,2000,3000,4000,5000}};//定义五个账户信息
// while (1)
// {
// int ID = 0;
// long money = 0;
// int flag = 1;
// ID = checkCardNumber(datas[0]); //核对卡号
// while(1) { //核对卡号与密码是否匹配,并且记录该卡号对应剩余输入密
// flag = 1; //码次数
// if (datas[2][ID] <= 0) {
// printf("您今天以经三次密码输入错误,请24小时后再次输入\n");
// break; //剩余输入密码机会小于等于0,跳出本层循环,运行上个循环
// }
// if(!checkPassword(datas[1][ID]))
// {
// printf("您输入的密码不正确,您还有%ld次机会\n", datas[2][ID]-1);
// datas[2][ID]--;
//
// if (datas[2][ID] <= 0) {
// printf("您的输入不正确,请24小时后再次输入\n");
// break;
// }
// continue; //跳出循环,继续运行while以后的代码
// }
//
// while (1) {
// datas[2][ID] = 3; //当输入密码正确后,重置该卡号可输入密码次数
// printf("1.取款\n2.查看余额\n3.存款\n4.退出\n请选择您要办的业务:");
// int choice = 0;
// scanf("%d", &choice);
// switch (choice) { //登陆成功后有四个功能,用 swit...case
// case 1: //取钱
// money = drawMoney(datas[3][ID]);
// datas[3][ID] = datas[3][ID] - money;
// break;
// case 2: //查询余额
// showMoney(datas[3][ID]);
// break;
// case 3: //存钱
// money = saveMoney(datas[3][ID]);
// datas[3][ID] = datas[3][ID] + money;
// break;
// case 4: //退卡
// flag = 0;
// break;
// default:
// break;
// }
// if (flag == 0) {
// break;
// }
// }
// break;
// }
// }
//
return 0;
}
***************
ATM.m

*********************

//一个可以实现核对卡号功能的函数
int checkCardNumber(long a[])
{
while (1) { //不知道循环次数,知道循环条件(输入的卡号在a[]中有对应的),用whil循环
printf("请输入您的卡号,以回车结束:");
long b = 0;
scanf("%ld", &b);
for (int i = 0; i < 5; i++) {//将输入的卡号于a[]中元素匹配
if (b == a[i] ){
return i;
}
}
printf("您输入的卡号不存在,请核对后重新输入\n");
}
}

//一个可以核对 卡号和密码是否匹配 的函数
BOOL checkPassword(long passWord) //返回YES或NO
{
printf("请输入您的密码,以回车结束:");
long b = 0;
scanf("%ld", &b);
return b == passWord;
}
//一个实现取款功能的函数
long drawMoney(long money)
{
while (1) {
printf("请输入您的取款金额,以回车结束:");
int b = 0;
scanf("%d", &b);
if (b > money) {
printf("您的余额不足!\n");
continue;
}
return b;
}
}
//一个实现存款功能的函数
long saveMoney(long money)
{
printf("请输入您存入的金额,以回车结束:");
int b = 0;
scanf("%d", &b);

return b;
}
//查询余额
void showMoney(long b)
{
printf("您的余额为%ld\n", b);
}

笔记::**********************************************************************************************************

函数声明内形参可以与函数定义的形参不同
//int middleValue(int x, int y, int z);
函数声明内形参可以不写
//int middleValue(int , int , int );
//
//int middleValue(int a, int b, int c);
//int middleValue(int a, int b, int c)
//{// 先求和;
// int sum = a + b + c;
// int max =a > b ? a : b;
// // 求最大值
// max = max > c ? max : c;
// int min = a < b ? a : b;
// //求最小值.
// min = min < c ? a : c;
// int middle = sum - max - min;
// return middle;
//
//}
//
//int sumvalue(int n)
//{
// //定义一个累加器
// int sum =0;
// //循环累加到n
// for (int i = 1; i < n + 1; i++) {
// sum += i;
// }
// // 将sum的结果当做返回值返回主调函数.
// return sum;
//}


//定义有参有返回值的函数
// 将以上三点结合.
//int sumValue(int a, int b)
//{
// return a +b;
// // ********return 后的语句不执行.
//
//}
定义一个有参数,无返回类型的函数
参数如何写;类型+参数名(形式参数,成为形参)
如果是多个参数,用逗号分离,(每个形参前都要声明参数类型)
//void printSumValue(int value1, int value2)
****** 无返回值类型的函数也可以使用return ,强制终止函数.
//{
// printf("%d ",value1 + value2 );
//
//
//
//}
定义一个无参数,返回值类型为int的函数
调用有返回值,无参数的函数
不需要写返回类型,直接写函数名
可以定义一个与返回之类型匹配的变量来保存函数的计算结果
//int getCount()
//{
// // return 后面的数据返回给主调函数
// // 什么是主调函数,那个函数调用本函数,那个函数就是是主调用函数
// return 33;
//}
定义一个函数
//void funA()
//{
// printf("Hello,ios!\n");
//}
定义一个无参数无返回类型函数
//void printfHello()
//{
// printf("Hello1");
//}

int main(int argc, const char * argv[]) {


回顾 函数是具有特定功能的代码段
库函数和自己定义的函数;
printf(“Hello Lanou\n”);!
scanf(“%d”,&number);!
strlen(string);!
strcpy(string1,string2);
//
// // 调用一个无参数无返回类型函数
// // 不需要写返回类型,直接写函数名及小括号,就算没有参数,括号也不能省略
// funA(); printfHello();
//
// // 定义一个无参数,返回值类型为int的函数
//
//
// int count = getCount();
// // 函数的返回值可以像普通变量一样使用
// printf("人数%d\n",count);
//
//
// // 调用无返回值,有参数的函数
// // 调用的时候传入的数据成为实参
// // 变量或变量表达式
// // 传参过程相当于赋值过程.
//
// // 调用有返回值,有参数的函数;
// int a = sumValue(3, 5);
// printf("%i\n",a);
// // 或者直接调用,而不用变量接收
// printf("sum = %i", sumValue(3, 5));


// //形参,实参
// 形参(形式参数)
// 出现在函数定义中,以假名字来表⽰示函数调⽤用时需
// 要提供的值。! 实参(实际参数)
// 出现在函数调⽤用中的表达式。!
// !
// 注意:函数调⽤用中,形参会拷⻉贝实参内容,传递参数
// 是给函数传送信息的⼀一种⽅方法。

//练习.
//1、编写函数int sumValue(int n):计算1到n的和
// printf("%d\n",sumvalue(10));

//3、编写函数,返回三个整数的中间数
// int a = middleValue(3, 4, 5);
// printf("%d \n",a);

//严格的函数通常包括三部分:

// 函数声明、函数定义、以及函数调⽤用。! 函数声明:指的就是函数的描述,也叫函数原型。!
// 函数声明:
// 1、函数定义出现在主调函数之前,可以省略函数声明。
// 2、函数定义出现在主调函数之后,需要提前声明函数。!
// 函数声明尽管可以省略,从规范来讲,不要省略

**********************************************************

MYFUNCTION.m文件

//实现冒泡排序的函数
void bubbleSort (int arry[], int count)
{ for( int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - 1 -i; j++) {
if (arry[j] > arry[j + 1]) {
int temp = arry[j];
arry[j] = arry[j + 1];
arry[j + 1] = temp;
}
}
}
}

void printfArry(int arry[], int count)
{
for (int i = 0; i < count; i++) {
printf("%2d ",arry[i]);
}

}
void randomArry(int arry[], int count, int max, int min)
{
for (int i = 0; i < count ; i++) {
arry[i] = arc4random()% (max - min + 1) + min;
}
}
int maxValue(int a, int b)
{
int max = a > b ? a : b;
return max;
}
int maxValueOfThree(int a, int b, int c)
{
int max = maxValue(a, b);
max= maxValue(max,c);
return max;

}
int maxValueOfFour(int a, int b, int c , int d)
{
int max = maxValueOfThree(a, b, c );
max= maxValue(max,d);
return max;

}
int maxValueOfFive(int a, int b, int c , int d,int f)
{
int max = maxValueOfFour(a, b, c, d);
max= maxValue(max,f);
return max;

}
//void printNum(int x)
//{
// {//第一种出口.
// if(x==0){
// return;
// }
// printf("%d ",x--);
// printNum(x);
//}
//
// // 第二种出口;
// if (x > 0) {
//
//
// printf("%d ",x--);
// printNum(x);
//}
//
//}

*******************************************************

main.m

//快捷键
//command+ctrl+⬆️⬇️切换.h 和.m
//command + shift +Y控制台 ,
//command + Alt +0控制台
//command + 0控制台
//导入文件
//#import "自己的文件"与import<系统的文件>的区别
#import "MYFuction.h"
int main(int argc, const char * argv[]) {
// //给数组赋初始值;
// int arry[10] = {0};
// //随机赋值
// randomArry(arry, 10, 10, 5);
// printfArry(arry, 10);
// printf("\n");
// 对数组进行冒泡排序
// bubbleSort(arry, 10);
//打印数组排序后的状态
// printfArry(arry, 10);
// C语⾔言不允许函数嵌套定义,但是允许函数嵌套调⽤用。! 注意避免嵌套定义

printf("max = %d\n",maxValue(3, 4));
printf("max = %d\n",maxValueOfThree(3, 4, 5));
//递归函数
// C语⾔言允许函数实现体内再次调⽤用函数本⾝身。这种调⽤用⽅方式称为递归
// 调⽤用,这个函数称为递归函数。! 在计算机中阶乘就可以使⽤用递归调⽤用。! 注意:递归⼀一定要有出⼝



//如果函数内有一个局部变量与全局变量名称相同,则调用的是局部变量.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值