我们平时学的数学中就懂了函数是什么,如, y = kx + b,k和b都是常数,给定任意 x 就能求得 y
在C语言中,函数可以将一个大的任务给予一个函数,通过使用函数可以简化我们的代码,提升我们写代码的效率
C语言中函数我们已经学了很多了,如 printf 函数、scanf 函数等等,其实它们的底层逻辑都是很复杂的,但是标准库将底层逻辑封装成了简单的 printf 函数后,我们便可以很简单的将想要打印的内容打印在屏幕上
在C语言中,我们通常会见到两类函数:库函数、自定义函数
我们前面说的 printf 和 scanf 都是库函数,都是已经装好的函数,我们直接使用就可以了
要使用这些函数,需要包含它们对应的头文件,如 printf 和 scanf 需要的是 stdio 这个头文件
#include
库函数还有很多,并不要求我们都能记住,只需要适当的了解就好了,需要的时候再去相应的查询
自定义函数就是我们自己创造出一个属于我们自己的函数,格式如下
type fun_name(形式参数)
{
语句;
}
这里的 type 可以是整型(int)也可以是浮点型(float)等等,这里的类型表示的是我们最后return 语句返回值的类型,甚至也可以是 void ,没有任何类型,可以不用写return
fun_name是函数名,由自己定义,最好有意义,能够让人记住,方便使用
小括号中是你需要的参数,参数的个数由自己决定
最后在大括号里面加入你需要的语句即可
如果我们要创建一个加法函数
#include
int Add(int x, int y)
{
int ret = x + y;
return ret;
}
int main()
{
int a = 5;
int b = 4;
int c = Add(a,b);
printf("%d",c);
return 0;
}
//输出:9
int 为函数下面语句中 return 要返回的类型,ret即为int类型,Add为函数的名字,x,y为参数
因为x,y都是int类型的,所以我们下面主函数main里调用的Add里给的参数a和b也是int类型的,要保持一致
最后main里的c的值就为Add函数执行时的返回值
当然Add函数也可以简化为
int Add(int x, int y)
{
return x + y;
}
函数中的参数分为形参和实参
形参,也叫形式参数,字面意思来理解就是走个形式的参数而已,这个形参就是上面Add里的 x,y
实参,也叫实际参数,字面意思就是真实存在的参数,我们main函数中传递给Add的a、b就是实参
当main函数的a、b作为参数传递给Add里的x、y的时候,只是将a、b的值传给了x、y,但x、y本身并不是a、b,所以x、y是新开辟出来的地址,a、b和x、y的地址是不一样的
所以说,形参是实参的一份临时拷贝
一个函数使用前是需要让main函数知道这个函数的存在的,所以一般我们在定义一个函数的时候都写在main函数的前面
#include
int Add(int , int );
int main()
{
int a = 5;
int b = 4;
int c = Add(a,b);
printf("%d",c);
return 0;
}
int Add(int x, int y)
{
int ret = x + y;
return ret;
}
但如果写在了后面呢?
#include
int Add(int x, int y);
int main()
{
int a = 5;
int b = 4;
int c = Add(a,b);
printf("%d",c);
return 0;
}
int Add(int x, int y)
{
int ret = x + y;
return ret;
}
如果放在了后面,那么我们需要在main函数前将定义函数的第一行直接复制在main函数的前面,这个就是函数的声明,我们只需要告诉main函数这个Add函数需要的类型就可以了,所以我们还可以这样
#include
int Add(int , int );
int main()
{
int a = 5;
int b = 4;
int c = Add(a,b);
printf("%d",c);
return 0;
}
int Add(int x, int y)
{
int ret = x + y;
return ret;
}
如果是在企业中,一个项目可能需要多行代码,那么不可能都将所有的东西都放在同一个文件下,所以我们可以放在多个文件中
函数的声明、类型的声明放在头文件 (.h) 中,函数的实现是放在源文件 (.c) 中
例如刚刚的加法函数:
add.h
add.c
test1.c
但是最好我们可以在我们函数的实现时,加上这么一句代码
包含一下我们自己写的头文件,算是函数的声明了
static 和 extern 都是C语言中的关键字
static 是静态的的意思
我们可以先来看一段代码
#include
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
聪明的你肯定能够知道最后的输出为:1 1 1 1 1
那么如果我们在test函数里的 int i = 0 前面加上个static会发生什么?
#include
void test()
{
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
输出结果为:1 2 3 4 5
从这样的结论我们可以分析出来,当我们第一次进入函数的时候 i 是1,那么再次进入函数的时候 i 怎么就不是1而是2了呢?
因为static让 i 出函数时 i 并不会被销毁,而是保留了原有的值,所以我们再次进入的时候就进行了累加,所以最后五次的结果就是 1 2 3 4 5
static修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本来是存储在栈区的,但是被static修饰后存储到了静态区,存储在静态区的变量和局部变量是一样的,只有程序结束,变量才销毁,内存才收回
extern是用来声明外部符号的,如果一个全局符号在文件A中定义,想要在文件B中使用,那么我们可以在文件B中使用extern声明,就可以使用文件A中的符号
add.c
test.c
输出结果:
这样就可以在test.c文件中使用add.c中的全局变量了
如果像上面的代码,我们不想让文件B中使用文件A中的符号,那么我们可以使用static限制:
add.c
那么如果这时候编译运行会发生什么?
即使我们在test.c中使用extern也不能使用这个符号了
结论:当被static修饰后,这个符号就只能在本文件内部使用
感谢观看,希望对你有所帮助
---------------------------------------------------------------------------------------------------------------------------------
完