day13-函数
1.函数的概念
main scanf printf putchar getchar puts strlen strcpy strcmp strcap srand rand...
实现某一具体功能的代码模块,代码重复使用、简洁优化主程序
2.函数的定义
<数据类型> 函数名(参数列表)
{
代码块;
return 返回值;
}
1)返回类型:char int short float double long... char * 、 int *、 void
函数的返回类型应与返回值的数据类型保持一致,如果函数没有返回值,则为void空类型
2)函数名:标识符
满足命名规则
3)参数列表:参数可以为1个,多个,或者没有,多个参数之间用逗号隔开
4)代码块:功能代码
5)return:代码函数模块的结束,一般后面跟上函数的返回值,也可以不加返回值return;
6)返回值:返回值代表调用的是得到的具体结果(可以先用if判断函数返回值,找出错误信息,确保函数正确再使用)
函数三要素:返回类型、返回值、参数
eg:封装一个函数,该函数实现打印n行的"hello world";
void my_print(int n)
{
for(int i = 0; i < n; i++)
printf("hello world \n");
return ;
}
3.函数的声明
在使用函数之前,对函数进行声明,让编译器找到函数
void my_print(int n);//n可以省略
函数的声明一般放在主函数之上,或者.h文件中,只要是在调用之前声明都可以
函数定义在主函数之上,既定义也声明
4.函数的调用
函数名(实参列表);
my_print(5);
实参列表与参数列表的参数要一一对应(参数个数,参数类型)
5.函数参数的传递
1)值传递
2)地址传递[1] 值传递
eg1:封装一个函数,实现两元素之和
int add(int a, int b)
{
return a+b;
}
int main()
{
int a = 10, b = 20;
add(a,b); //将a变量的值复制给函数中的变量a,将b变量的值复制给函数中的变量b
}
函数add中的变量a,与main函数中的变量a,不是同一片存储空间,所以在add函数内部不会访问到主函数中的变量a
[2] 地址传递
eg2:封装函数,实现两个整型数据的交换
void my_swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
return ;
}
int main()
{
int a = 10, b = 20;
my_swap(&a,&b);
}
地址传递是将变量的地址传入函数内部,函数内部对变量地址进行操作
[3] 全局变量
eg3:1.c文件中
int a = 10, b = 20; //定义两个全局变量a b,在1.c文件中,所有模块都可以访问这两个全局变量
void my_swap()
{
int temp = a; //交换两个全局变量的值
a = b;
b = temp;
return ;
}
int main()
{
my_swap(a,b); //交换两个全局变量的值
}
3)全局变量
1)函数参数与一维数组
[1] 复制传递
void print_arr(int a[], int len)
{
for(int i = 0; i < len; i++){
printf("%d ", a[i]);
}
}
[2] 地址传递
void print_arr(char *a, int len)
{
for(int i = 0; i < len; i++){
printf("%d ", a[i]);
}
}
复制传递与地址传递本质都是操作的指针
[3] 全局数组
eg1:
a、对一维数组进行随机赋值 b、打印一维数组,封装一个函数,查找一维数组中最大的元素,并作为函数的返回值
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//对一维数组随即赋值
void arr_rand(int *a,int len)
{
srand(time(NULL));
for(int i = 0; i < len; i++)
a[i] = rand()%50;
}
//打印一维数组
void arr_print(int *a,int len)
{
for(int i = 0; i < len; i++)
printf("%d ",a[i]);
puts("");
}
//查找一维数组中的最大值
int arr_max(int *a,int len)
{
int max = a[0];
for(int i = 0; i < len ;i++)
{
if(max < a[i])
max = a[i];
}
return max;
}
//一维数组冒泡排序
void arr_sort(int *a,int len)
{
for(int i = 0; i < len-1; i++)
{
for(int j = 0; j < len-i-1; j++){
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
int main(int argc, char *argv[])
{
int a[32];
arr_rand(a,5);
arr_print(a,5);
printf("max = %d\n",arr_max(a,5));
arr_sort(a,5);
arr_print(a,5);
return 0;
}
eg2:
封装一个函数,统计字符串中小写字符的个数,并将字符串中小写字母转换成大写字母
#include <stdio.h>
int str_len(char *s)
{
int cnt = 0;
int i = 0;
while(*s){
if(*s >= 'a' && *s <= 'z'){
*s-=32;
cnt++;
}
s++;
}
return cnt;
}
int main(int argc, char *argv[])
{
char s[32] = "zcJHJosujcHSJcSLNHc";
printf("len = %d\n",str_len(s));
puts(s);
return 0;
}
2)函数参数与二维数组
eg:对二维数组求和
eg:封装一个函数,求二维数组所有元素之和
int arr_sum(int (*p)[3],int row)
{
int sum = 0;
for(int i = 0; i < row; i++){
for(int j = 0; j < 3; j++)
sum+= p[i][j];
}
return sum;
}
int main(int argc, char *argv[])
{
int a[][3] = {1,2,3,4,5,6};
printf("sum = %d\n",arr_sum(a,2));
return 0;
}
6.指针函数
<数据类型> *函数名(参数列表)
{
代码块;
return 地址值;
}
指针函数的返回值类型为地址值;
不能返回局部变量的地址;
作业:
封装函数实现 strlen strcat strcpy strcmp