- 函数是什么
维基百科中对函数的定义:子程序
在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
- C语言中函数的分类
库函数
自定义函数
2.1 库函数
为什么会有库函数?
在学习C语言编程的时候,总是在一个代码编写完成之后想要知道结果,就需要把结果打印到屏幕上。这个时候我们会频繁地使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。
在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。
在编程时我们也计算,总是会计算n的k次方这样的运算(pow).
像上面描述的基础功能,他们不是业务性的代码。在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。
注意:使用库函数,必须包含#include对应的头文件
库函数查询工具的使用,可下载MSDN用于查询,
或者在线点击https://cplusplus.com/reference/ 或者http://en.cppreference.com
2.2 C语言常见的库函数
IO函数 (输入输出函数,如printf/scanf/getchar/putchar等)
字符串操作函数(strcpy/strlen等)
字符操作函数(toupper/tolower等)
内存操作函数(memcpy/memcmp/memset等)
时间/日期函数(time等)
数学函数(strt/pow等)
其他库函数
3. 举例库函数的使用
①. strcpy
功能:复制一个字符串
char*是指针 指针是用来接收地址的。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main(void)
{
char arr1[20] = { 0 };
char arr2[] = "Hello world";
strcpy(arr1, arr2); //第一个元素是目的地,第二个元素是源头。将arr2复制到arr1
printf("%s\n", arr1); //%s--以字符串的形式打印 输出Hello world
return 0;
}
②. memset
功能:将缓冲区设置为指定的字符
void*memset(void*dest,intc,size_tcount);
size_t:无符号整型
Remarks
The memset function sets the first count bytes of dest to the character c.
memset函数将dest的第一个count字节设置为字符c。
4. 自定义函数
自定义函数和库函数一样,有函数名,返回值类型和函数参数。但是函数的功能由我们设置。
例如:char*strcpy(char*strDestination,constchar*strSource);
char为函数的返回类型
strcpy为函数名
()中内容为函数的参数
- 函数的组成
ret_type fun_name(para1, * )
{
statement;//语句项
}//函数体
ret_type 返回类型
fun_name 函数名
para1 函数参数
- 写一个函数可以找出两个整数中的最大值
#include<stdio.h>
//函数的定义
int get_max(int x, int y) //为什么是int 因为在运行完成后会返回一个整型的值
{
int z = 0;
if (x > y)
z = x;
else
z = y;
return z; //返回z —— 返回最大值
}
int main(void)
{
int a = 5;
int b = 10;
//函数的调用
int max = get_max(a, b);
printf("max = %d\n", max);
return 0;
}
main()函数 = 我 我请求张三给我带一份麻辣香锅,15元
get_max()函数 = 张三 张三获得信息: 带饭(麻辣香锅,15元)
我请求张三给我带饭,带什么饭?我给他两个信息(参数):带麻辣香锅,要15块钱的。
张三接收到信息,给我带回了饭(给我一个返回值:饭)
- 写一个函数可以交换两个整型变量的内容
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//函数返回类型为void,表示这个函数不需要返回任何值,也不需要换回
void swap1(int x, int y) //交换后不需要返回什么值
{
int z = 0; //临时变量
z = x;
x = y;
y = z;
}
int main(void)
{
int a = 10;
int b = 20;
//写一个函数——交换两个整型变量的值
printf("交换前:a = %d b = %d\n", a, b);
//输出 交换前:a = 10 b = 20
swap1(a, b);
printf("交换后:a = %d b = %d\n", a, b);
//输出 交换后:a = 10 b = 20
return 0;
}
发现并没有交换 为什么呢?
程序里主函数里a、b和swap()函数的x、y是两个独立的空间,所以对swap()函数的x、y操作只是交换了x、y并不会影响主函数的a、b
加入指针可解决
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//函数的定义
//函数返回类型的地方写成:void,表示这个函数不需要返回任何值,也不需要换回
void swap2(int*pa, int*pb) //这样就将主函数和swap()函数联系起来
//int*pa, int*pb的pa、pb就是指针变量,他们有能力找到a、b
{
int z = 0; //临时变量
z = *pa;
*pa = *pb;
*pb = z;
}
int main(void)
{
int a = 10;
int b = 20;
//写一个函数——交换两个整型变量的值
printf("交换前:a = %d b = %d\n", a, b);
//输出 交换前:a = 10 b = 20
swap2(&a, &b); //把a、b的地址给到swap()
printf("交换后:a = %d b = %d\n", a, b);
//输出 交换后:a = 20 b = 10
return 0;
}
5. 函数的参数
实际参数(实参):真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
形式参数(形参):形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。
形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
上面 Swap1 和 Swap2 函数中的参数 x,y,px,py 都是形式参数。在main函数中传给 Swap1 的 num1 , num2 和传 给 Swap2 函数的 &num1 , &num2 是实际参数。
上面swap1在被调用的时候,是传值调用,实参传给形参,其实形参是实参的一份临时拷贝,改变形参,并不会导致实参改变
6. 函数的调用
传值调用:
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。eg:swap1
传址调用:
传址调用时把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外部的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。eg:swap2