c语言函数的基础知识,包括实例

函数

函数的概念

c语言的函数就是一个完成某项特定任务的一小段代码,这段代码有特殊写法和调用方法

C语⾔的程序其实是由⽆数个⼩的函数组合⽽成的,也可以说:⼀个⼤的计算任务可以分解成若⼲个较

⼩的函数(对应较⼩的任务)完成。同时⼀个函数如果能完成某项特定任务的话,这个函数也是可以

复⽤的,提升了开发软件的效率。

函数分为两类

  • 库函数:可以直接使用的函数
  • 自定义函数:自己设计的函数

库函数

库函数的定义

C语⾔标准中规定了C语⾔的各种语法规则,C语⾔并不提供库函数;C语⾔的国际标准ANSI C规定了⼀ 些常⽤的函数的标准,被称为标准库,那不同的编译器⼚商根据ANSI提供的C语⾔标准就给出了⼀系列 函数的实现。这些函数就被称为库函数。

各种编译器的标准库中提供了⼀系列的库函数,这些库函数根据功能的划分,都在不同的头⽂件中进

⾏了声明

库函数的使用

例子:sqrt

double sqrt(double f);
sqrt是计算一个数的平方根
double 表示sqrt函数的返回值类型是浮点型
sqrt是这个函数的函数名字
f是函数的参数,若是想调用这个函数需要传一个浮点型的值

调用一个库函数需要调用对应的头文件,比如sqrt对应的头文件就是#include

自定义函数

自己定义一个函数,自己设计其中的功能,供自己使用

函数的语法形式

ret_type fun_name(形式参数)
{
    函数体
}
  • ret_type表示函数的返回值类型(所有基本类型都可以当返回值),如果不需要返回类型就void
  • fun_name表式函数的名字,函数名字要尽量有意义,
  • 形式参数也可以有多个,但是类型一定是一样的
  • 函数的功能是在大括号实现的

函数的举例

计算两个数相加的过程

int Add(int a, int b)//设计一个返回值是整形类型的函数,名字为Add,里面的形式参数对应主函数里面的i,k
{
	return a + b;//将a+b的值返回给Add
}
int main()
{
	int i = 0;
	int k = 0;
	scanf("%d%d", &i, &k);//输入i,k的值
	int r = Add(i, k);//调用i,k的值赋值给r
	printf("%d", r);//输出r的值
	return 0;
}

实际参数的值也可以是一个变量

比如:

写一个函数,输入一个数字,屏幕上打印相对应数量的*

void print(a)//返回类型为空,不需要返回任何值,函数名字为print,形参为a,对应下面的n
{
	for (int i = 0;i <= a;i++)
	{
		printf("*");
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);//输入n的值
	print(n);//调用print函数,
	return 0;
}

形参和实参

先写一个函数,求两个数的较大值,并输出出来

int Max(int i, int k)//函数定义中,括号里面的参数就叫形参
{
	return (i > k ? i : k);
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	int r = Max(a, b);//函数调用时真实传递给函数的参数就是实参,也叫实际参数
	printf("%d", r);
	return 0;
}

实参

在上面代码中,主函数里面,调用Max函数时,传递给函数a,b的值为实参

形参

在函数定义时,括号里面的I,k就是形参

如果只定义了Max而不调用这个函数,Max函数中的i,k只是在形式上存在,也不会像内存申请空间,不是真实存在的,所以叫形参。

形参的实例化

形式参数只有在函数被调⽤的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化。

形参和实参的关系

int Add(int a, int b)
{
	return a + b;
}
int main()
{
	int i=20;
	int k=50;
	
	int r = Add(i, k);
	printf("%d", r);
	return 0;
}

c语言函数的基础知识,包括实例_第1张图片

c语言函数的基础知识,包括实例_第2张图片

可以发现,i,k向a,b传参的过程中虽然值没变但是地址变了,说明形参是重新开辟了一块内存空间。也就是形参其实是实参的一份儿临时拷贝。

return语句

  • return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式

的结果。

  • return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。

  • return返回的值和函数返回类型不⼀致,系统会⾃动将返回的值隐式转换为函数的返回类型。

  • return语句执⾏后,函数就彻底返回,后边的代码不再执⾏。

  • 如果函数中存在if等分⽀的语句,则要保证每种情况下都有return返回,否则会出现编译错误

数组作为函数参数

数组传参的基本格式

设置一个数组,把里面的值都变成-1,并且打印出来

void init_arr(int arr[10], int sz)//arr后面的10可以省略,但[]不可以省略
{
	int i = 0;
	for (i = 0;i < sz;i++)
	{
		arr[i] = -1;//将数组的值初始化为-1
	}
}
void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0;i < sz;i++)
	{
		printf("%d", arr[i]);
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//设计一个数组
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的元素个数
	print_arr(arr, sz);//先打印出原本的数组的值
	init_arr(arr,sz);//数组初始化的过程,实参要包括数组名字和元素个数
	print_arr(arr, sz);//打印初始化后的数组的值
	return 0;
}

这⾥的init_arr函数要能够对数组内容进⾏设置,就得把数组作为参数传递给函数,同时函数内部在设

置数组每个元素的时候,也得遍历数组,需要知道数组的元素个数。所以我们需要给init_arr传递2个参

数,⼀个是数组名字,另外⼀个是数组的元素个数。仔细分析print_arr也是⼀样的,只有拿到了数组和元

素个数,才能遍历打印数组的每个元素。

数组传参的注意事项

  • 函数的形式参数要和函数的实参个数匹配

  • 函数的实参是数组,形参也是可以写成数组形式的

  • 形参如果是⼀维数组,数组⼤⼩可以省略不写

  • 形参如果是⼆维数组,⾏可以省略,但是列不能省略

  • 数组传参,形参是不会创建新的数组的

  • 形参操作的数组和实参的数组是同⼀个数组

二维数组作为函数参数

void print_arr(int arr[3][5], int i, int j)//参数接收数组大小,行数,列数
{
	for (int a = 0;a < i;a++)//打印行
	{
		for (int b = 0;b < j;b++)//打印列
		{
			printf("%d", arr[a][b]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5},{5,6,9,8,5},{5,6,4,5,8} };//初始化二维数组
	print_arr(arr, 3, 5);//将数组名,行数,列数传给参数
	return 0;
}

函数的嵌套调用和链式访问

嵌套调用

嵌套调用就是函数之间可以互访访问,互相调用

例子实现

计算某年某月有多少天

思路:因为平年二月有28天,闰年二月有29天,所以我们要写一个函数判断是不是闰年,再写一个函数,如果是闰年的话在计算某月对应的天数

int is_run(int y)
{
	if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)//判断是不是闰年,闰年返回1,否则返回0
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int run(int y, int m)
{
	int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//创建一个数组,放各个月份对应的天数
	int day = days[m];
	if (is_run(y) && m == 2)//创建一个函数,判断是不是闰年,要是闰年并且是二月的话天数+1
	{
		day += 1;
	}
	return day;
}
int main()
{
	int year = 0;
	int mouth = 0;
	scanf("%d%d", &year, &mouth);
	int day=run(year, mouth);//创建一个函数,实参为year,mouth返回的值放到day
	printf("%d", day);//打印day的值

	return 0;

链式访问

将一个函数的返回值作为另一个函数的参数,就叫链式访问

int main()
{
	size_t len = strlen("abcdef");
	printf("zd",len);

	return 0;
}

上述函数先计算出字符串长度在打印,但是,可以通过链式访问可以一步实现。

int main()
{
	printf("%zd", strlen("abcdef"));
	return 0;
}

将strlen(“abcdef”)作为printf的参数,然后printf再调用这个参数,这就叫链式访问。


### 链式访问

将一个函数的返回值作为另一个函数的参数,就叫链式访问

```c
int main()
{
	size_t len = strlen("abcdef");
	printf("zd",len);

	return 0;
}

上述函数先计算出字符串长度在打印,但是,可以通过链式访问可以一步实现。

int main()
{
	printf("%zd", strlen("abcdef"));
	return 0;
}

将strlen(“abcdef”)作为printf的参数,然后printf再调用这个参数,这就叫链式访问。

‘’

你可能感兴趣的:(c语言,开发语言)