C语言函数详细讲解
函数【1】什么是函数:
[*]在计算机中,子程序是一个大型程序中的某部分代码,由一个或多个语句块组成,它负者完成某项特定任务而且相较于其他代码,具备独立性。
[*]一般会有输入参数并有返回值,提供对过程的封装和细节的隐蔽。这些代码通常被集成为软件库。
#include <stdio.h>
int add(int c,int d)
{
int z = c + d;
return z;
}
int main()
{
int a = 10;
int b = 20;
int sum = add(a,b);
printf("sum = %d\n",sum);
return 0;
}
运行结果:30代码分析:上面代码就是一个简单的加法函数,sum = add(a,b)就是调用 add 这个函数,并把实参 a 和 b 传给形参 c 和 d ,所以 c = 10,d = 20,把 c 和 d 相加值赋给 z,再把 z 的值返回给主函数并赋给变量 sum ,再把 sum 打印出来
【2】C语言中函数的分类:
[*]库函数
[*]自定义函数
①、库函数:
[*]IO函数 —— 输入/输出函数(i指input;o指output)
[*]字符串操作函数 —— strlen()
[*]字符操作函数
[*]内存操作函数 —— memset()
[*]时间/日期函数 —— time()
[*]数学函数 —— sqrt()
[*]其他库函数
使用库函数必须包含 #include 对应的头文件
这里给大家推荐一个C语言函数的学习网站:https://www.cplusplus.com/reference/ 不懂的函数可以在里面查询使用方法
下面就结合工具的使用来了解一些函数
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "hello world";
memset(arr,'*',5);//内存操作函数
printf("%s\n",arr);
return 0;
}
运行结果:***** world代码作用:把原字符串的前 5 个字符换成 *
疑问:工具里面说了,第二个参数为 int 型,可是 * 不是字符型吗?这说明前面的文章你没读,哈哈,之前说过字符型在内存中是以对应的ASCII码的值进行存储的,值是十进制,所以也是 int 型。
【拓展】这里再推荐几个学习函数的工具
[*]MSDN
[*]http://en.cppreference.com 英文版(C语言官网)
[*]http://zn.cppreference.com 中文版(C语言官网)
②、自定义函数:
自定义函数和库函数一样,有函数名、返回值类型和函数参数。但是不一样的是这些都由我们自己来设计
[*]函数的组成
ret_type fun_name(paral,*)
{
statement; //语句项
}
//ret_type:返回值类型
//fun_name:函数名
//paral:函数参数例子1:写一个函数打印两个数最大值
代码:
#include <stdio.h>
int Max(int a,int b)
{
if(a > b)
return a;
else
return b;
}
int main()
{
int a1 = 0;
int a2 = 0;
int ret = 0;
printf("请输入两个数:>");
scanf("%d%d",&a1,&a2);
ret = Max(a1,a2);
printf("%d\n",ret);
return 0;
}
例子2:写一个函数实现交换两个变量的值
这里容易犯下一个错误
错误代码:
这里有人会纳闷了,为什么 a1 和 a2 的值没有交换啊,代码好像也没问题,那么接下来我们就来分析一些问题出在哪里
正确代码:
#include <stdio.h>
void exchange(int* a,int* b)
{
int temp = 0;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a1 = 10;
int a2 = 20;
printf("a1 = %d,a2 = %d\n",a1,a2);
exchange(&a1,&a2);
printf("a1 = %d,a2 = %d\n",a1 ,a2);
return 0;
}
代码分析:把 a1 和 a2 的地址传给函数,这样 a 和 b 就可以通过解引用找到 a1 和 a2 的地址来改变他们的值,不会像前面的代码一样使得 a 和 b 有独立的空间
结论:当实参传给形参的时候,形参其实是实参的一份临时拷贝,对形参的修改是不会改变实参的,而改进后的代码是传给形参地址,通过地址间接找回来
【3】函数的参数:
[*]实际参数
[*]形式参数
实际参数:实际参数可以是常量、变量、表达式、函数等,无论何种类型,在进行函数调用时,他们都必须有确定的值,以便把这些值传给形参。
形式参数:形式参数指形式上的参数,它一般情况下是不存在的,假设 main() 函数中没有代码去调用自定义函数那自定义函数中的形参是不存在的,所以才说形式参数只有在函数被 调用的过程中才实例化(分配内存单元)。形式参数当函数调用完成之后就自动销毁了,因此形式参数只在函数中有效。
举例一下函数实际参数是函数的情况:
#include <stdio.h>
int get_max(int x,int y)
{
if(x > y)
return x;
else
return y;
}
int main()
{
int a = 10;
int b = 20;
int max = get_max(a,b);
printf("max = %d\n",max);
max = get_max(100,get_max(3,7));
printf("max = %d\n",max);
return 0;
}代码中 max = get_max(100,get_max(3,7)); 的 get_max(3,7) 意思是先得到最大值 7 再把 7 传给形参,与 100 进行比较大小
【4】函数的调用:
[*]传值调用:函数的形参和实参分别占有不同的内存块,对形参的修改影响实参
[*]传址调用:(1)传址调用是把函数外部创建变量的内存地址传给函数参数的一种调用函数的方式
[*] (2)这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量
【5】函数的嵌套调用和链式访问:
①、嵌套调用:
#include <stdio.h>
void new_line()
{
printf("hehe\n");
}
void new_line1()
{
int i = 0;
for(i = 0;i < 3;i++)
{
new_line();
}
}
int main()
{
new_line1();
return 0;
}
②、链式访问:
[*]把一个函数的返回值作为另一个函数的参数
代码一:
#include <stdio.h>
#include <string.h>
int main()
{
int len = 0;
len = strlen("abc");
printf("%d\n",len);
printf("%d\n",strlen("abc"));
return 0;
}
运行结果:
3
3代码二:
#include <stdio.h>
int main()
{
printf("%d",printf("%d",printf("%d",43)));
return 0;
}
运行结果:4321代码二分析:printf的返回值是打印在屏幕上的字符个数,首先屏幕打印的值是43,43是两个字符,返回值是2,就变成printf("%d",printf("%d",2));,所以打印 2 ,2 是一个字符,返回值为 1 ,变成 printf(“%d”,1); 打印 1 ,所以结果就是:4321
【6】函数的声明和定义:
①、函数声明:
[*]告诉编译器有一个函数叫什么,参数是什么,返回值类型是什么。但是具体是不是存在无关紧要
[*]函数的声明一般出现在函数的使用之前。要满足先声明后使用
[*]函数的声明一般要放在头文件中的
②、函数定义:
[*]指函数的具体实现,交代函数的功能实现
#include <stdio.h>
int add(int x,int y);//先声明
int main()
{
int a = 10;
int b = 20;
int max = add(a,b);
printf("%d\n",max);
return 0;
}
add(int x,int y)//后使用
{
if(x > y)
return x;
else
return y;
}
但是完全没必要像上面的格式写,太啰嗦了,下面的写法比较常用也更简洁
#include <stdio.h>
int add(int x,int y)
{
if(x > y)
return x;
else
return y;
}
int main()
{
int a = 10;
int b = 20;
int max = add(a,b);
printf("%d\n",max);
return 0;
}但是函数声明的真正用法并不是如上面所示,下面就来介绍日后在多人完成项目时函数声明的正确用法:
解析:在 add.h 中声明函数,在 add.c 中完成函数功能,在主函数中调用 Add() 函数#include "add.h" 中的 “ ” 用法,在引用自己写的头文件时用 “ ” ;引用库函数里的头文件时用 < >
文档来源:51CTO技术博客https://blog.51cto.com/u_15304931/3260229
页:
[1]