一:函数分类
函数是指具有特定的功能代码的代码段,后面只要想要使用该功能只要调用函数就可以,可以减少代码的重复性,效率自然也会高很多。
函数的分类:
(1)库函数:系统提供好的函数,例如printf()输出函数;输入函数scanf();strlen()求字符串长度的函数;strcat()拼接函数;strcmp()比较函数;strcpy()赋值函数,这些均是适用于字符串数组的操作的库函数。
(2)自定义函数(开发者自主定义的函数)
根据功能需要定义函数,可以有返回值,也可以没有返回值,类型也是必须的。
二:函数声明和定义
声明:放于xxx.h文件,可以放结构体定义、函数定义的类型修饰符+函数名+(形参列表)+分号“;”
定义:放于xxx.m文件,但不是main.m文件
调用:放于main.m文件,在头文件还要引入xxx.h文件,才能实现调用函数
定义:
返回值类型(void/int/char/float```)函数名(形式参数列表)
{
语句;
return 返回值;
//这里的返回值,也成为函数的值,只能通过return语句返回给主函数,并且一个函数最多只能有一个返回值,函数即使没有返回值,也可以只是一个return;或者return 0;来结束函数的执行,从而返回到主函数里面。return后面的语句不会再执行。
}
无参函数举例:
void hello(void)
{
printf("Hello word!");
}
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);在函数里面就会显示出结果来。
}
三:函数调用
(1)有返回值的,直接定义一个跟函数的类型相同的变量来接收函数调用后的结果
int result=getNmuner(str);//计算一个字符串的长度
如://1、定义函数int sumValue(int n):计算1到n的和
int sumValue(int n)
{
int sum=0;
for (int i=0; i<=n; i++) {
sum+=i;
}
return sum;
}
//1、调用函数int sumValue(int n):计算1到n的和
// int sum=sumValue(5);
// printf("sum=%d",sum);
// printf("\n");
(2)没有返回值的,则直接调用函数名,并且传实参进去就可以了
sortArray(str,4);//冒泡排序
如:
//练习3:定义冒泡排序(无需返回值)的函数
void sortArray(int a[],int n)//这里void表示执行功能,不返回任何东西
//形参传的是(数组名+[]即"a[]",数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
{
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;
}
}
}
}
调用冒泡排序:
//练习3:
int array[]={1,2,3,4,5,6,3,2,4,5};
unsigned int count=sizeof(array)/sizeof(int);//也就是sizeof(array)/4,因为sizeof()是计算字符字节数的,而int型恰好是4个字节,而char是一个字节的。
//int b[10]=sortArray(int a[],count);//错,因为是、void型的函数定义,无返回值的,则无需b[]来接受
sortArray(array,count);
//形参传的是(数组名+[]即"a[]",数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
printf("排序后:\n");
for (int i=0; i<count; i++) {
printf("array[%d]=%d\n",i,array[i]);
}
四:形参实参
在定义函数是,函数名(这里放的是形参)
在调用函数时,函数名(这里放的是实参)
在函数调用时,形参会拷贝实参的内容,传递参数是给函数传递信息的一种方法
需要注意的是数组作为参数时
函数定义时,如冒泡排序,void sortArray(char str[],int count)这里数组的类型修饰符char 数组名str 以及数组的标志[ ],都需要传进去,整型的count 也需要传;
函数调用时,如冒泡排序,sortArray(str,5);这里传的实参里,则只需要数组名str,以及实参5就可以调用了
五:函数嵌套调用
在定义函数时,调用已经定义好的函数,叫做函数嵌套调用
如:
//练习4(函数嵌套调用)
//求两个数的最⼤大值!
//!求三个数的最⼤大值!
//!求四个数的最⼤大值!
int getTwoMax(int a,int b)
{
int max=a>b?a:b;
return max;
}
int getThreeMax(int a,int b,int c)
{
int max=getTwoMax(a, b);
max=getTwoMax(max, c);
return max;
}
int getFourMax(int a,int b,int c,int d)
{
int max=getThreeMax(a,b, c);
max=getTwoMax(max, d);
return max;
}
int getFiveMax(int a,int b,int c,int d,int e)
{
int max=getFourMax(a, b, c, d);
max=getTwoMax(max, e);
return max;
}
六:函数的递归调用
递归调用,是指函数调用本身
//计算s = (1*1)!+(2*2)! + (3*3)!
//1、整型数的平⽅方sql
//2、⼀一个整型数的阶乘factorial
int sql(int a)
{
int result=a*a;
return result;
}
//int factorial(int n)//方法1用for循环实现求阶乘
//{
// int result=1;
// for (int i=1; i<=n; i++) {
// result*=i;
// }
// return result;
//}
int factorial(int n)//方法2用递归实现求阶乘
{
//if条件是递归的出口,不然是死循环
if(n<=1){//负数没有阶乘,n=0时,0的阶乘是1,1的阶乘也是1
return 1;
}
return factorial(n-1)*n;//如n=5,5Xfactorial(4)=5X4Xfactorial(3)=5X4X3Xfactorial(2)=5X4X3X2Xfactorial(1)=5X4X3X2X1
}
int getSqlFact(int n){
int s=0;
// int a=0;
for (int i=1; i<=n; i++) {
// a=sql(i);//方法一,拆分先求平方,再求阶乘
// s+=factorial(a);
s+=factorial(sql(i));//函数的嵌套调用,再调用,方法二
}
return s;
}
七:变量的作用域
局部变量(在各个函数领域内的),只作用于本函数体内
全局变量(在整个主函数内有效,甚至是定义在头文件和main函数体之间的,则作用于所有的代码,但是局部变量的优先级高于全局变量)
如:
int number1=1;//全局变量,并且只能在它以下的代码使用,并且如果下面局部变量有重名的,则局部变量会优先使用,如下面的number1=2,输出是2.
int main(int argc, const char * argv[]){
int number1=2;//局部变量
printf("number1=%d\n",number1);
输出的结果是number1=2的
八:
课上代码:
.h文件
#import <Foundation/Foundation.h>
//.h文件放的全是声明
//函数调用,函数定义放于头文件则可以不用函数声明,如果是放于主函数后面则必须在头文件声明,如下:记得加上“;”
//求和
int sum(int a);
//求最大值
int max_value(int a,int b);
//求累计和
int sumValue(int n);
//计算该年的那一日
int dayOfYear(int year,int month,int day);
//求三个数中的中间值
int middle(int a,int b,int c);
//统计一个数的位数
int number(unsigned int n);
//求和
int getsum(int a,int b);
//求差
int getjian(int a,int b);
//求两个数的乘积
int getcheng(int a,int b);
//求两个数的商(除法)
float getchu(int a,int b);
//冒泡排序
void sortArray(int a[],int n);//冒泡排序无需返回值,则为void,并且传个数组名以及标识a[],以及数组元素个数n
//求两个数的最大值
int getTwoMax(int a,int b);
//求三个数的最大值
int getThreeMax(int a,int b,int c);
//求四个数的最大值
int getFourMax(int a,int b,int c,int d);
//求五个数的最大值
int getFiveMax(int a,int b,int c,int d,int e);
//求一个数的平方
int sql(int a);
//求一个数的阶乘
int factorial(int n);
//求一个数的平方的阶乘
int getSqlFact(int n);
.m文件
#import "Operator.h"
//函数定义
//定义求和函数(返回和,并且返回值在主函数里面有用,如果有函数声明则可以防于后面)
int sum(int a){
int sum=0;
sum+=a;
return sum;
}
//定义取最大值,并且最大值在主函数中有用,
int max_value(int a,int b)
{
int max=0;
max=a>b?a:b;
//printf("%d",max);//这种就只是显示,max在主函数中并没有用。
//return 0;
return max;
}
//课上练习1
//1、编写函数int sumValue(int n):计算1到n的和
int sumValue(int n)
{
int sum=0;
for (int i=0; i<=n; i++) {
sum+=i;
}
return sum;
}
//2、编写函数dayOfYear(year, mouth,day),使得函数返回由这三个参数确定的那⼀一天是⼀一年中的第⼏几天
int dayOfYear(int year,int month,int day)
{
int date=0;
int TodayYear;
printf("Please input TodayYear:");
scanf("%d",&TodayYear);
//判断合法性
for (int i;;i++ ) {
printf("Please input a date:");
scanf("%d%d%d",&year,&month,&day);
if (year<=TodayYear) {
if (year%400==0||(year%4==0&&year%10!=0)) {
if (month==2) {
if (day>=1&&day<=29) {
printf("您输入的是润年的2月份,输入的日期合法\n");
break;
}else{
printf("您输入的是润年的2月份,输入的日期不合法!请输入的日期范围是1~29\n");
}
}else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
if (day>=1&&day<=31) {
printf("您输入的是大月份,输入的日期合法\n");
break;
}else{
printf("您输入的是大月份,输入的日期不合法!请输入的日期范围是1~31\n");
}
}else if(month==4||month==6||month==9||month==11){
if (day>=1&&day<=30) {
printf("您输入的是小月份,输入的日期合法\n");
break;
}else{
printf("您输入的是小月份,输入的日期不合法!请输入的日期范围是1~30\n");
}
}else{
printf("请输入合法的月份,范围1~12月\n");
break;
}
}else {
if (month==2) {
if (day>=1&&day<=28) {
printf("您输入的是平年的2月份,输入的日期合法\n");
break;
}else{
printf("您输入的是平年的2月份,输入的日期不合法!请输入的日期范围是1~28\n");
}
}else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
if (day>=1&&day<=31) {
printf("您输入的是大月份,输入的日期合法\n");
break;
}else{
printf("您输入的是大月份,输入的日期不合法!请输入的日期范围是1~31\n");
}
}else if(month==4||month==6||month==9||month==11){
if (day>=1&&day<=30) {
printf("您输入的是小月份,输入的日期合法\n");
break;
}else{
printf("您输入的是小月份,输入的日期不合法!请输入的日期范围是1~30\n");
}
}else{
printf("请输入合法的月份,范围1~12月\n");
}
}
}else{
printf("请输入合法的年份,必须小于等于今年%d\n!",TodayYear);
}
}
int a[][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
if (month==1&&day>0&&day<31) {
date=day;
}else if(month>1&&month<13){
for (int i=1; i<month; i++) {
if (year%400==0||(year%4==0&&year%100!=0)) {
date+=a[0][i];
}else{
date+=a[1][i];
}
}
date+=day;
}else{
printf("error!");
}
printf("date=%d\n",date);
return date;
}
//3、编写函数,返回三个整数的中间数
int middle(int a,int b,int c)//或者命名getMidValue,驼峰命名法首个单词的首字母小写,其他单词首字母大写
{
int max=a>b?a:b;
max=max>c?max:c;
int min=a<b?a:b;
min=min<c?min:c;
int mid=a+b+c-max-min;
return mid;
}
//4、编写函数,返回正整数n中的数字的个数
int number(unsigned int n)
{
int count=1;
while (n/10!=0) {
n=n/10;
count++;
}
return count;
}
//练习2:创建⼀一对⽂文件:operator.h operator.m实4个函数,分别求两个整型数的加、减、乘、除
//和
int getsum(int a,int b)
{
return a+b;
}
//减
int getjian(int a,int b)
{
return a-b;
}
//乘法
int getcheng(int a,int b)
{
return a*b;
}
//除法
float getchu(int a,int b)
{
if(b!=0){
return a/b*1.0;//由整型强制变成浮点型或者a/(float)b
}else{
printf("除数不能为0!");
return -1;//表示程序出问题
}
}
//练习3:冒泡排序(无需返回值)
void sortArray(int a[],int n)
//形参传的是(数组名+[]即"a[]",数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
{
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;
}
}
}
}
//练习4(函数嵌套调用)
//求两个数的最⼤大值!
//!求三个数的最⼤大值!
//!求四个数的最⼤大值!
int getTwoMax(int a,int b)
{
int max=a>b?a:b;
return max;
}
int getThreeMax(int a,int b,int c)
{
int max=getTwoMax(a, b);
max=getTwoMax(max, c);
return max;
}
int getFourMax(int a,int b,int c,int d)
{
int max=getThreeMax(a,b, c);
max=getTwoMax(max, d);
return max;
}
int getFiveMax(int a,int b,int c,int d,int e)
{
int max=getFourMax(a, b, c, d);
max=getTwoMax(max, e);
return max;
}
//计算s = (1*1)!+(2*2)! + (3*3)!
//1、整型数的平⽅方sql
//2、⼀一个整型数的阶乘factorial
int sql(int a)
{
int result=a*a;
return result;
}
//int factorial(int n)//方法1用for循环实现求阶乘
//{
// int result=1;
// for (int i=1; i<=n; i++) {
// result*=i;
// }
// return result;
//}
int factorial(int n)//方法2用递归实现求阶乘
{
//if条件是递归的出口,不然是死循环
if(n<=1){//负数没有阶乘,n=0时,0的阶乘是1,1的阶乘也是1
return 1;
}
return factorial(n-1)*n;//如n=5,5Xfactorial(4)=5X4Xfactorial(3)=5X4X3Xfactorial(2)=5X4X3X2Xfactorial(1)=5X4X3X2X1
}
int getSqlFact(int n){
int s=0;
// int a=0;
for (int i=1; i<=n; i++) {
// a=sql(i);
// s+=factorial(a);
s+=factorial(sql(i));//递归调用,方法二
}
return s;
}
main.m文件
//
// main.m
// LessonC05
//
// Created by lanou on 15/8/24.
// Copyright (c) lanou. All rights reserved.
//
#import <Foundation/Foundation.h>
#import"Operator.h"//导入声明的文件.h就可以了,并且要用“”双引号
//声明都放于.h文件,实现函数的定义放于.m文件,在main.m里面导入声明文件就可以了。#import"Operator.h"
int number1=1;//全局变量,并且只能在它以下的代码使用,并且如果下面局部变量有重名的,则局部变量会优先使用,如下面的number1=2,输出是2.
int main(int argc, const char * argv[]){
int number1=2;//局部变量
printf("number1=%d\n",number1);
//1、调用函数int sumValue(int n):计算1到n的和
// int sum=sumValue(5);
// printf("sum=%d",sum);
// printf("\n");
//2、调用函数dayOfYear(year, mouth,day),使得函数返回由这三个参数确定的那⼀一天是⼀一年中的第⼏几天
// int date=dayOfYear(,3,23);
// printf("date=%d",date);
// printf("\n");
//3、编写函数,返回三个整数的中间数
// int mid=middle(3,5,2);
// printf("mid=%d",mid);
// printf("\n");
//4、函数调用,返回正整数n中的数字的个数
// int count=number(1005);
// printf("count=%d",count);
// printf("\n");
//练习2:创建⼀一对⽂文件:operator.h operator.m实现4个函数,分别求两个整型数的加、减、乘、除
// int he=getsum(6,2);
// printf("he=%d\n",he);
// int jian=getjian(6, 2);
// printf("jian=%d\n",jian);
// int cheng=getcheng(6, 2);
// printf("cheng=%d\n",cheng);
// float chu=getjian(6, 2);
// printf("chu=%f\n",chu);
//练习3:
int array[]={1,2,3,4,5,6,3,2,4,5};
unsigned int count=sizeof(array)/sizeof(int);//也就是sizeof(array)/4,因为sizeof()是计算字符字节数的,而int型恰好是4个字节,而char是一个字节的。
//int b[10]=sortArray(int a[],count);//错,因为是、void型的函数定义,无返回值的,则无需b[]来接受
sortArray(array,count);
//形参传的是(数组名+[]即"a[]",数组元素个数)
//实参传送的是(数组名aray,数组元素个数)
printf("排序后:\n");
for (int i=0; i<count; i++) {
printf("array[%d]=%d\n",i,array[i]);
}
//练习4:
//两个数求最大值
// int maxValue1=getTwoMax(6, 2);
// printf("%d\n",maxValue1);
// //三个数求最大值
// int maxValue2=getThreeMax(9,78,6);
// printf("%d\n",maxValue2);
// //四个数求最大值
// int maxValue3=getFourMax(5,6,1,23);
// printf("%d\n",maxValue3);
// //五个数求最大值
// int maxValue4=getFiveMax(56,24,45,345,3421);
// printf("%d\n",maxValue4);
//练习5(函数调用)
计算s = (1*1)!+(2*2)! + (3*3)!
//1、整型数的平⽅方sql
//2、⼀一个整型数的阶乘factorial
// int n;
// printf("please input a number:");
// scanf("%d",&n);
// int result=getSqlFact(n);
// printf("result=%d\n",result);
//函数
// //函数的定义
// 返回值类型(void/int/char/foat....)函数名(形式参数列表)
// {
// 语句(功能段代码);
// return 返回值;
// }
// 返回值类型:(void/int/char/foat....)
// void表示执行功能,不返回任何东西
//课上练习:
// int max=max_value(4, 5);//函数调用:
// //返回值类型(void/int/char/foat....)函数名(实参)
// printf("%d\n",max);
return 0;
}