C语言之函数详解

Posted sjp151

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言之函数详解相关的知识,希望对你有一定的参考价值。

C语言函数!=数学函数

在C语言当中,我们会经常用到函数,但是C语言当中的函数是一段代码块,也叫子程序。可以被其它函数调用,增加代码的复用性。

C语言的函数分为库函数和自定义函数

库函数

库函数就是C语言当中本来就存在的函数,可以帮助我们实现某种功能,但是使用的时候要引用头文件。就比如 strcpy 就是字符串拷贝函数,有两个参数,第一个是要拷贝到的字符数组,第二个是字符数组的源头。

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

在使用库函数的时候,一定要引用头文件,strcpy 的头文件是 #include<string.h> 。这里就是把 arr2 字符串拷贝到 arr1 字符串当中。拷贝的时候也会把 \\0 拷过去。
还有 strcmp 库函数,是为了对比比较两个字符串是否相等,如果相等,就返回 0 。要引的头文件也是 #include<string.h> 。

int main()
{
	char arr1[10] = "hello";
	char arr2[] = "hello";
	if (strcmp(arr1, arr2) == 0)
	{
		printf("arr1与arr2相等\\n");
	}
	return 0;
}


strcmp 这个库函数就是为了比较两个字符串是否相等。

memset 这个库函数是设置内存,有三个参数,第一个是要指向填充的内存块,第二个是修改成什么字符,第三个是设置修改的大小。

int main() 
{
	char arr[10] = ""; 
	(char*)memset(arr, 'x', 5);
	printf("%s\\n", arr);
	return 0;
}

在使用 memset 函数操作的时候,是把第二个 x 覆盖到原有的字符数组上面,就算原来字符数组上面有字符也会被覆盖。memset 前面的 (char*) 是强制类型转换,强制转换成 (char*) 因为本来就是对已有的内存进行操作。所以强制转换一下更安全。

自定义函数

自定义函数就是程序员自己写一个函数去实现某些功能。自定义函数是由函数名,函数参数,返回值类型组成。
求两个整型中的较大值:

int Max(int x, int y)
{
	return x > y ? x : y;
}
int main()
{
	int a = 3;
	int b = 5;
	int ret = Max(a, b);
	return 0;
}

求较大值的函数名为 Max ,因为要求的是较大值,所以要返回一个整型,所以返回类型是整型。因为函数传的参数是 a,b 都是整型,所以在函数里面要用整型来接收,就是 int x int y 。这里是用 x ,y 来接收的,也可以写成 a b 传的参数名和变量名可以一样。

写一个函数交换两个变量的值,在 main 函数当中完成两个值的交换,我们可以创建第三个变量来完成交换。那么在函数当中是否也可以这样呢,一起来看看:

void swap(int a,int b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前 a=%d b=%d\\n", a, b);
	swap(a, b);
	printf("交换后 a=%d b=%d\\n", a, b);
	return 0;
}

运行结果如下:

发现并没有完成想要的参数交换。因为这里就涉及到形参与实参。
形参,又叫形式参数,在自定义函数的时候,括号里的就是参数,形式参数就是 main 函数里面参数的一份值拷贝。mian 函数里面的参数是实参。
实参就是在 mian 函数里面创建的参数,指向一块内存。形参是实参的值拷贝,所以又拷贝了一份到另外一块内存上面,指向的不是同一块内存,所以对形参修改的时候只是修改了形参,并没有对实参完成修改。所以这里要完成交换的话,就要通过形参对实参进行修改。
如何通过形参对实参进行修改
既然上面说了实参与形参操作的不是同一块内存,那么只要使形参与实参指向同一块内存,操作同一块内存就可以完成交换了。所以就用到指针。因为通过指针,就能指向同一块内存,从而通过形参操作实参。所以传参的时候就应该传指针,从而达到修改实参。

void swap(int* a,int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int a = 3;
	int b = 5;
	printf("交换前 a=%d b=%d\\n", a, b);
	swap(&a, &b);
	printf("交换后 a=%d b=%d\\n", a, b);
	return 0;
}

这里就通过指针完成了两个数的交换。

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

嵌套调用:就是一个函数里面还能调用另外一个函数:

void test01()
{
	printf("嵌套调用的函数\\n");
}
void test()
{
	printf("第一个函数\\n");
	test01();
}
int main() 
{
	test();
	return 0;
}


从输出结果就能看出调用的顺序,支持函数嵌套使用。

链式访问:把函数的返回值作为另外一个函数的参数。

int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

输出结果是 4321 因为第三个 printf 先打印出 43 因为打印了两位数,所以返回值是2个字符,所以打印2,2是一个字符,所以再返回,再打印1。所以最后就是 4321 。

函数的声明与定义

声明就是告诉编译器有这个函数,参数是什么,返回值是什么。定义就是函数的代码,通过代码来实现功能,就是函数的定义。

int Add(a, b);				//函数的声明
int main()
{
	int a = 3;
	int b = 5;
	int ret = Add(a, b);
	printf("%d\\n", ret);
	return 0;
}
Add(int a, int b)			//函数的定义
{
	return a + b;
}

因为如果写声明的话,声明就要写在 main 函数上面,实现写在后面,所以为了方便。我们统一把函数写在 main 函数上面,这样就不用声明了。

int Add(int a, int b)			
{
	return a + b;
}			
int main()
{
	int a = 3;
	int b = 5;
	int ret = Add(a, b);
	printf("%d\\n", ret);
	return 0;
}

像这样写在 main 函数上面,就不用声明函数了。就会方便很多。

以上是关于C语言之函数详解的主要内容,如果未能解决你的问题,请参考以下文章

C语言实现数据结构之栈的详解

C语言学习内存操作函数之------->memcpy memmove 详解与手动实现

C语言学习内存操作函数之------->memcpy memmove 详解与手动实现

C语言之printf( )详解

C语言sscanf()函数详解的代码

C语言详解:函数递归专题