维基百科中对于函数的定义:子程序

子程序是一个大型程序中的部分代码,由一个或多个语句块组成,负责完成某项特定任务且相较于其他代码有一定的独立性。

一般会有输入参数和返回值,提供对过程的封装和细节的隐藏。

C语言中的两种函数

  • 库函数
  • 自定义函数

库函数

C语言早期没有库函数,但存在一些一些频繁使用到的功能,开发的人都可能会用到;为了可移植性和提高效率提供了库函数。

可以在手册/参考网站了解库函数 C library - C++ Reference (cplusplus.com)

库函数简单归类:

  • IO函数
  • 字符串操作函数
  • 字符操作函数
  • 内存操作函数
  • 时间/日期函数
  • 数学函数
  • 其他库函数

使用库函数,必须引头文件(#include)

可以参照文档学习库函数,以下是两个示例:

eg1:strcpy

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>

#include <stdio.h>
int main()
{
	char arr1[] = "test";
	char arr2[20] = "#######";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

在监视窗口中监视arr1和arr2可知strcpy将\0也拷贝到arr2中,\0是字符串的结束标志,printf只打印\0前的字符

除此之外还有形参/返回值的介绍

eg2:memset

工地英语翻译:把ptr所指向空间的前num个字节设置成特定值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	char arr[] = "just a test";
	memset(arr, '*', 4);
	printf("%s\n", arr);
	return 0;
}

运行结果为:**** a test

自定义函数

自定义函数和库函数一样,有函数名、返回值类型和参数,不过全部由自己设计;

函数的组成

ret_type fun_name(paral,*)
{
   statement; //函数体:交代函数的实现
}
  • fun_name:函数名
  • ret_type:返回类型
  • paral:参数

写一个找出两个整数间最大值的函数:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
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);
	return 0;
}

写一个交换两个整形变量的函数;

不用函数的写法:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20 ;
	int tmp = 0;
	tmp = a;
	a = b;
	b = tmp;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

用函数:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void swap(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;

}
int main()
{
	int a = 10;
	int b = 20 ;
	swap(a, b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

这样能起到交换的作用吗?答:不能(a,b/x,y都是独立存在的,地址不同,交换了xy但并不能交换a和b,需要使用指针)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void swap(int* pa, int* pb)
{
	int tmp = 0;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;

}
int main()
{
	int a = 10;
	int b = 20 ;
	swap(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

函数的参数

  • 实际参数(实参):真实传递给函数的参数,可以说常量、变量、表达式、函数等;无论实参是何种类型的量,在进行函数调用时都必须有确定的值,以便把这些值传给形参。
  • 形式参数(形参):指函数名后括号中的变量,因为形参只有在被函数调用的过程中才实例化(分配内存单元),故称为形式参数;形参在函数调用完成之后就销毁,因此形参只在函数中有效。

当实参传给形参时,形参相当于实参的临时拷贝,对形参的修改不会改变实参;因此在上一个实例中,第一种写法之所以不成功原因便是如此。

函数的调用

  • 传值调用:函数的形参和实参分别占有不同内存块,对形参的修改不影响实参。
  • 传址调用:把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式;这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操作函数外部的变量。

在上一个实例中,第一种写法便是传值调用,第二种为传址调用。


我们所度过的每个平凡的日常,也许就是连续发生的奇迹