这篇将介绍C语言函数的基本知识
程序的艺术来源于生活
目录
1.什么是C语言中的函数
2.C语言中函数的分类
2.1库函数以及如何学习使用库函数
2.2自定义函数
3.函数的参数
3.1实际参数(实参)
3.2形式参数(形参)
4.函数的调用
4.1传值调用
4.2传址调用
5.函数的嵌套调用和链式访问
5.1 嵌套调用
5.2 链式访问
6. 函数的声明和定义
6.1 函数声明
6.2 函数定义
在数学中,我们经常看到函数的函数:F(x)= 2*x+1
而在C语言中函数又被称为子程序,我们最常见到的main就是一个函数
- 在计算机科学中,函数被命名为子程序,它是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
- 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
C语言的编译器提供的函数,我们最常见的 printf scanf strlen等就是库函数
库函数的使用一定要包含其对应的头文件
库函数的学习:www.cplusplus.com
在C library下我们可以看到C语言中所有的头文件,以及每个头文件下所包含的库函数
也可以直接在搜索框里直接搜索你想查找的库函数
C语言常见的库函数有:
1.IO函数
2.字符串操作函数
3.字符操作函数
4.内存操作函数
5.时间/日期函数
6.数学函数
7.其他库函数
库函数的使用
例如:
strcpy的使用
通过查看我们可以知道 destination是目的地数组,source是源头数组,返回值是destination数组的起始地址
strcpy的作用就是把source数组中的内容拷贝到destination数组
#include
#include
int main()
{
char arr1[15] = { 0 };
char arr2[15] = "Hello world";
strcpy(arr1, arr2);
printf("%s",arr1);
return 0;
}
memset的使用
通过了解我们发现
ptr 是你想修改内个数组的首元素地址
value 是将要设置的值
num 是想修改的字节数
#include
#include
int main()
{
char arr2[15] = "Hello world";
memset(arr2, '*', 5);
printf("%s",arr2);
return 0;
}
注:
使用库函数,必须包含 #include 对应的头文件
虽然库函数有许多种,但是库函数也有许多特殊的功能实现不了,更加重要的是自定义函数
自定义函数是由我们自己来设置的
自定义函数和库函数一样,有函数名,返回值类型和函数参数
函数的灵魂在于自定义函数
函数的组成:
ret_type fun_name( para1 )
{
statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数(0个,1个,或多个)
例:
找出两个数的较大值
#include
int get_max(int x, int y)
{
return (x > y ? x : y);
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);//输入
int m = get_max(a, b);
printf("%d\n", m);
return 0;
}
交换两个整形内容
如果我们仿照上面这样写
错误:
#include
void Swap(int x, int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
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;
}
我们会发现结果并没有改变
原因是因为在调用Swap函数时,实参传递给形参,形参将是实参的一份临时拷贝
而形参和实参在空间中存储的地址是不一样的,此时在Swap函数中交换形参的值并不会影响到实参,所以在main函数中x,y的值并没有发生改变.
而当我们需要通过自定义函数改变外部变量时,我们需要传递外部变量的地址
正确:
#include
void Swap(int* px, int* py)
{
int t = 0;
t = *px;
*px = *py;
*py = t;
}
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;
}
真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等。
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
形式参数是指函数名后括号中的变量
因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了
因此形式参数只在函数中有效
在上面举例自定义函数时,Swap()函数中的参数x,y都是形式参数。
在main函数中传给Swap()函数的 &a,&b 是实际参数。
代码内存分配
总结:形参实例化之后其实相当于实参的一份临时拷贝,而当我们需要通过自定义函数改变外部变量时,我们需要传递外部变量的地址,也就是传递实参。
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。
例:每调用一次这个函数,就会将 num 的值增加1
#include
void main_1(int* num)
{
(*num)++;
}
int main()
{
int num = 0;
int i = 0;
for (i = 0; i < 6; i++)
{
main_1(&num);
}
printf("%d",num);
return 0;
}
函数和函数之间可以根据实际的需求进行组合的,也就是互相调用
嵌套调用就是在函数中可以调用其他定义的函数
例如在three_line函数中调用new_line函数
#include
void new_line()
{
printf("hehe\n");
}
void three_line()
{
int i = 0;
for (i = 0; i < 3; i++)
{
new_line();
}
}
int main()
{
three_line();
return 0;
}
注:函数可以嵌套调用,但是不能嵌套定义
把一个函数的返回值作为另外一个函数的参数。
#include
#include
int main()
{
char arr[20] = "hello";
int ret = strlen(arr);
printf("%d\n", ret);
printf("%d\n", strlen(arr));
return 0;
}
这两个打印出来的结果是相同的
1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函 数声明决定不了。
2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
3. 函数的声明一般要放在头文件中。
我们来看下面这组程序
#include
int main()
{
int a = 10;
int b = 20;
int s = Add(a, b);
printf("%d\n", s);
return 0;
}
int Add(int x, int y)
{
return x + y;
}
通过运行我们可以发现
虽然编译通过了,但是生成路径中会提示我们自定义的函数Add未定义
这是因为编译器执行程序的时,是从上到下依次执行的,在上面遇到Add函数时,还没有遇到Add函数的定义,所以报错了,但由于在后面遇到Add函数的定义,所以程序运行成功
解决方法是在main函数前面添加对Add函数的声明,告诉程序有这个Add函数,这样程序就不会报错
#include
//函数声明
//int Add(int, int);
int Add(int x, int y); // 两种声明方式都可以
int main()
{
int a = 10;
int b = 20;
int s = Add(a, b);
printf("%d\n", s);
return 0;
}
int Add(int x, int y)
{
return x + y;
}
函数的定义是指函数的具体实现,交待函数的功能实现。
在一般工程中,不会像上面那种,声明的函数在main函数的后面,都是分文件写
例:
test.h的内容
放置函数的声明
#ifndef __TEST_H__
#define __TEST_H__
//函数的声明
int Add (int x, int y)
#endif //__TEST_H__
test.c的内容
放置函数的实现
#include "test.h"
//函数Add的实现
int Add (int x, int y)
{
return x+y;
}
这种分文件的书写方式,后面写小游戏时会用到
结语:本篇是函数的基础知识,如果本篇对你有用,请大家点赞关注!!!
现在关注是新粉,以后就是老粉了
下期预告:函数递归的详细讲解
感谢你的观看,我们下期再见