目录
一、C语言中函数的分类
1、库函数
2、自定义函数
二、简单介绍两个库函数
1、实现字符串拷贝(strcpy)
2、设置内存(memset)
三、函数的参数
1、实际参数(实参)
2、形式参数(形参)
四、函数的调用
1、传值调用
2、传址调用
在C语言中,函数分为库函数和自定义函数。
①我们知道在学习C语言编程的时候,总是在一个代码写完之后就迫不及待想知道结果,想把结果打印到屏幕上,这时候我们就会频繁的使用printf函数。(printf)
②在编程的过程中我们会频繁的做一些字符串的拷贝工作。(strcpy)
③在编程中,我们有时也会计算n的k次方这样的运算。(pow)
以上的代码在开发的过程中每个程序员都可能用到的,为了支持可移植性和提高程序效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。
那我们应该如何学习C语言呢?这里给大家一个网站(以往也提到过),可以帮我们深入了解库函数(https://legacy.cplusplus.com/) (嘎嘎好用)
但是库函数必须知道的一个秘密就是:使用库函数,必须包含#include对应的头文件。
如果库函数能干所有事情,那还需要程序员干什么?
所有自定义函数就显得尤为重要。
自定义函数和库函数一样,有函数名,返回类型和函数参数。
但是不一样的是这些都需要我们自己来设计,这个程序员一个很大的发挥空间。
现在写一个自定义函数来找出两个整数之间的最大值。
代码实现:
#include
//定义函数
int MAX(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//写一个自定义函数
int ret = MAX(a, b);
printf("%d", ret);
return 0;
}
程序结果:
如果目前对于函数还是有点懵的,可以看看这篇博客https://blog.csdn.net/Weraphael/article/details/127417675
再举一个例子:写一个自定义函数可以交换两个整型变量的内容。
我想大部分人可以会这么写:
#include
void Swap(int x,int y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
//交换
Swap(a, b);
//输出
printf("交换后:a=%d b=%d\n", a,b);
return 0;
}
但是结果却和我们想的不太一样,当输入10和20,会发现交换后和交换前一模一样。
我们可以按F10来监视程序
大家注意看a,x,b和y的地址,a对应x和b对应y的地址都不一样怎么可能交换的了值呢?
官方说法:a,b叫做实际参数,x和y叫做形式参数,当函数调用时,实参传递给形参,形参就会有自己的空间(地址),所以形参的修改不会影响实参。
可以用指针来建立联系,代码修改后:
#include
void Swap(int* x, int* y)
{
int tmp = *x;
*x= *y;
*y = tmp;
}
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
//交换
Swap(&a, &b);
//输出
printf("交换后:a=%d b=%d\n", a,b);
return 0;
}
程序效果:
代码详解:把a的地址交给x,b的地址交给y,此时x中存的就是a的地址,y中存的是b的地址,所以*x就是a,*y就是b,这里运用到指针中的解引用,想了解指针请点击后面的链接https://blog.csdn.net/Weraphael/article/details/127601704
最后来讲讲void在自定义函数中的应用
#include
void tmp(void)
{
printf("666\n");
}
int main()
{
tmp();
return 0;
}
代码详解:假设自定义函数tmp,但是我不给它传任何参数,所有我们可以在定义函数括号里写上void,表明这个函数在调用时不能传参,现在只希望函数内部打印“666”,因为不需要任何返回,所以它的返回类型为void。
目的:把arr2中的字符串拷贝到arr1中。
代码实现:
#include
#include //使用strcpy需要包含的头文件
int main()
{
char arr1[10] = { 0 };
char arr2[] = "welcome to China";
strcpy(arr1, arr2); //数组名就是指针
printf("%s\n", arr1); //%s用来打印字符串
return 0;
}
程序结果:
代码实现:
#include
#include //memset需要包含头文件
int main()
{
char arr1[20] = "welcome to China";
memset(arr1, 'x', 7); //'x'对应的是ASCII码,是整型
printf("%s\n", arr1);
return 0;
}
程序结果:
真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等
无论实参是何种类型,在进行函数调用时,它们都必须有确定的值,以便把这些值传递给形参。
形式参数是值函数名后括号的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完之后就自动销毁了。因此形式参数只有在函数中有效。可以简单认为:形参实例化之后其实相当于实参的一份临时拷贝。
特点:函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参。
在开头写了一个自定义函数来找出两个整数之间的最大值,就是传值调用。
●传址调用就是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
●这种传参方式可以让函数和函数外部的变量建立起真正的练习,也就是函数内部可以直接 操作函数外部的变量。
那前面写了自定义函数可以交换两个整型变量的内容,则就是传址调用。
有关自定义函数练习
传送门:https://blog.csdn.net/Weraphael/article/details/127823692