什么是函数?
例子:
ATM机?
需求出发 --- 提供哪些功能
ATM机
|
验 证
|
取钱 存钱 查询 转账 修改 退出
提示菜单功能
|
选择取钱
|
提示输入金额
|
确认一下金额
|
驱动点钞机
|
给到用户
函数定义的一般形式:
//返回值类型
类型标识符 函数名(形式参数) //函数头 head
{
//函数体 -- body
声明部分
语句部分
}
函数头:
类型标识符 --- 写数据类型的 --- 表示的函数处理完之后,要带出的结果的类型 ---
函数名 --- 体现函数功能 --- 命名规则 符合标识符命名规则
形式参数 --- 用来接受 传递给函数中的数据的
函数体:
就是完成函数对应功能的代码
eg:
计算两个整型数相加
#include<stdio.h>
int add(int a,int b)
{
int result;
result = a +b;
return result;
}
int main(void)
{
int a,b;
scanf("%d%d",&a,&b);
int ret;
ret = add(a,b);//调用函数
printf("ret=%d\n",ret);
return 0;
}
运行结果:
函数调用:
语法:
函数名(实际参数)
使用方式:
add(a,b); //1.函数调用 语句
result = add(a,b) + 3; //2.函数调用表达式
printf("ret = %d\n",add(1,2)); //3.充当别的函数的参数
eg:
从两个整型数中找出最大值
写成函数
#include<stdio.h>
int maxofTownum(int a,int b)
{
int max;
if(a>b)
{
max=a;
}
else
{
max=b;
}
return max;
}
int main(void)
{
int a, b,ret;
scanf("%d %d",&a,&b);
ret=maxofTownum(a,b);
printf("%d",ret);
return 0;
}
运行结果:
linux@ubuntu:~/day8$ vim function_max.c
linux@ubuntu:~/day8$ gcc function_max.c
linux@ubuntu:~/day8$ ./a.out
35 78
78linux@ubuntu:~/day8$
注意:
1.形参 和 实参
一一对应
个数相同
类型匹配
顺序一致
2.函数不需要输入数据,此时形参可以设计为void 表示不需要参数
3.返回值类型
如果函数不需要带出什么结果,此时返回值类型 设计为 void
4.返回值类型
没写
此时 默认为 int类型
5.返回值类型 与 要带出的结果值的类型 可以不一致
但是 最终,以 返回值类型 为准
6. main函数
程序的入口函数
7. 从调用关系上
main 函数 -- 主调函数
其它函数 -- 被调函数
8. 函数定义 可以放到 main函数后面
但是
需要在使用之前,做 函数声明
函数声明写法 --- 将函数头复制 + 分号
eg:
打印100以内所有的素数//函数
#include<stdio.h>
#include<string.h>
int prime(int num)
{
int i,j=0,ret=0;
for(i=1;i<=num;i++)
{
if(num%i==0)
{
j++;
}
}
if(j==2)
{
ret=1;
}
return ret;
}
void printf_prime(int n)
{
int i;
for(i=2;i<=100;i++)
{
if(prime(i)==1)
{
printf("%d",i);
}
}
}
int main(void)
{
int n;
scanf("%d",&n);
printf_prime(n);
return 0;
}
eg:
输入年份 和 月份 打印对应月份的天数
#include<stdio.h>
int year_month(int year,int month)
{
int day;
switch(month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day=31;
}
switch(month)
{
case 4:
case 6:
case 9:
case 11:
day=30;
}
if((year%400==0||year%100!=0&&year%4==0)&&month==2)
{
day = 29;
}
else if
(!(year%400==0||(year%100!=0&&year%4==0))&&month==2)
{
day = 28;
}
return day;
}
int main(void)
{
int year,month;
scanf("%d %d",&year,&month);
printf("%d",year_month(year,month));
return 0;
}
运行结果:
linux@ubuntu:~/day8$ ./a.out
2023 2
28linux@ubuntu:~/day8$ ./a.out
2024 2
29linux@ubuntu:~/day8$ ./a.out
2023 5
31linux@ubuntu:~/day8$
函数设计中的问题:
1.拆分依据? ---什么时候需要拆分成函数
a.功能独立
b.重复使用
2.大原则
高内聚 ,低耦合
数组函数参数:
int a[10] = {1,2,3,4,5};
//数组元素 做函数参数 --- 和普通变量做函数参数 用法一样
//数组本身 做函数参数
a //数组名
写法:
函数的形参 --- 数组形式形参,数组长度的形参
函数的实参 --- 数组名 , 数组长度
void printArray(int a[])//形式
编译器
void printArray(int *a)//本质上 --数组传参 只是把数组所在空间的首元素地址传过去了
32位 --- 地址的大小 4字节
64位 --- 地址的大小 8字节
eg:
数组逆序
#include<stdio.h>
void array(int a[],int len)
{
int i;
for(i=0;i<len/2;i++)
{
int t;
t=a[i];
a[i]=a[len-i-1];
a[len-i-1]=t;
}
for(i=0;i<len;i++)
{
printf("a[%d]=%d",i,a[i]);
}
}
int main(void)
{
int a[5]={1,2,3,4,5};
array(a,5);
return 0;
}
运行结果:
函数传参 --- 值传递 (将实参的值传递给形参变量 ==相当于是赋值)
eg:
选择排序
#include<stdio.h>
void choice_sort(int a[],int len)
{
int i,j;
for(i=0;i<len-1;i++)
{
for(j=1+i;j<len;j++)
{
int min;
if(a[i]>a[j])
{
min=a[i];
a[i]=a[j];
a[j]=min;
}
}
}
for(i=0;i<len;i++)
{
printf("a[%d]=%d\n",i,a[i]);
}
}
int main(void)
{
int a[5]={1,2,5,4,3};
choice_sort(a,5);
return 0;
}
运行结果:
linux@ubuntu:~/day8$ vim choiceSort.c
linux@ubuntu:~/day8$ gcc choiceSort.c
linux@ubuntu:~/day8$ ./a.out
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5
linux@ubuntu:~/day8$