C语言函数 二
一 函数的参数
函数的参数有二种分类
1. 形式参数(形参)
形参是指函数后面()括号里的变量,形参只有在函数在被调用的时候才会被分配空间(内存单元)
形式参数当函数调用完成之后就自动销毁了,因此形式参数只在函数中有效
形参实例化之后其实相当于实参的一份临时拷贝
对形参的修改不能改变实参
例如:
void Add(int x,int y)
{
int z = x+y;
return z;
出了这个函数的范围变量 x 和 y 就销毁了
}
2. 实际参数(实参)
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形
参,实参可以是:常量、变量、表达式、函数
例如:
int main()
{
int a = 10;
int b = 20;
int c = Add(10,b); 常量
int c = Add(a,b); 变量
int c = Add(a+3,b) 表达式
int c = Add(Add(a,3),b); 函数
函数的形式写的话一定要有返回值
}
二 函数的调用
1. 传值调用
传值调用是变量a和b本身的数值,传给了 x 和 y
x 和 y 的是形参,对 x 和 y 不会对实参 a 和 b修改
形参是实参的一份临时拷贝,对形参的修改不能改变实参
void Add(int x,int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
int main()
{
int a = 10;
int b = 20;
Add(a,b);
}
2.传址调用
传址调用是传的是 a 和 b 的地址,x 和 y 存的是 a 和 b 的地址,那么 *x 和 *y 指针变量就能通过地址找到 a 和 b对数值进行修改
这种传址方式可以通过函数的方式对函数外部的变量进行修改
void Add(int* x,int* y)
{
int z = 0;
z = *x;
*x = *y;
*y = z;
}
int main()
{
int a = 10;
int b = 20;
Add(&a,&b);
}
三 函数的嵌套调用
1. 嵌套调用
函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的
函数可以嵌套调用,但是不能嵌套定义
例如:
void test()
{
printf("24号\n");
}
void test2()
{
int i = 0;
for (i = 0; i < 3; i++)
{
test(); 调用test函数
}
}
int main()
{
test2();
return 0;
}
结果:
2.什么是嵌套定义
例如:
这是错误的
int Add(int x, int y)
{
return x + y;
int Sub(int x, int y)
{
return x - y;
}
}
int main()
{
return 0;
}
四 函数的链式访问
链式访问是把一个函数的返回值作为另外一个函数的参数
例如:
int main()
{
正常书写:
int n = stelen("abcdef");
printf("%d\n", n);
结果:6
链式访问
例如 1:
printf("%d\n", strlen("abcdef"));
结果:6
例如 2:
1 2 3
printf("%d", printf("%d", printf("%d", 43)));
结果:4321
return 0;
}
例子2里 最先打印 printf 3 ,---------------------------------------打印 4 3
printf2打印的是 printf 3的字符个数的返回值 ----------------- 打印 2
printf 1 打印的是 printf 2的字符个数的返回值也就是1 ----- 打印 1
总结:printf 函数返回值是字符的个数
五 函数的声明和定义
1. 函数声明
1. 函数的声明必须要有函数名、函数的参数、返回类型,
2. 函数具体是不是存在,函数声明是决定不了,要看函数的定义
3. 函数的声明一般出现在函数的使用之前,要满足先声明后使用
4.函数的声明一般要放在头文件中的
函输的定义一定要在主函数的前面,不然编译器会有警告,因为程序是从上往下执行的
假设一定要在主函数的后面定义函数的话,那在前面要先函数声明
2. 函数定义:
函数的定义是指函数的具体实现,交待函数的功能实现
函输的定义一定要在主函数的前面,不然编译器会有警告,因为程序是从上往下执行的
假设一定要在主函数的后面定义函数的话,那在前面要先函数声明
例如:
函数声明
int Add(int x, int y);
程序是从上往下执行的,如果一定要在主函数
int main() 的后面定义函数的话,要先定义头文件
{
int a = 10, b = 20;
int sum = Add(a, b);
printf("%d\n", sum);
return 0;
}
函数的定义
int Add(int x, int y)
{
return x + y;
}
那么这样用什么用呢
在初学编程的时候,觉得把所有代码都写在一个文件中最方便
但是在工作的时候并不是这样的,而是把程序分为一个一个模块来写
什么是模块呢?
模块是一个功能的实现
例如:
在主函数中定义个<add.h>头文件就可以使用了
例如:
#include"add.h"
#include"sub.h"
int main()
{
int a = 0, b = 0;
scanf("%d %d", &a, &b);
加法 add.h 和 add.c
int sum = Add(a, b);
减法 sub.h 和 sub.c
int n = sub(a, b);
printf("%d\n", sum);
return 0;
}
假设程序员A在业余时间写了一个游戏引擎,想把它卖给 B 公司,但是你又不想它知道你写的源代码暴露给B公司,那么就可以把 add.c文件编译成静态库,在把 add.c 和 add.h 文件卖给B公司就可以了
那么静态库是怎么编译的呢?
假设你已经完成了游戏引擎的代码
完成后,执行 F7 完成静态库,OK后就可以在你代码存储的地方找到 Debug 文件中找到 add.lid 文件,
然后就可以把 add.lid 和 add.h 文件卖给 B公司就可以了
那买回来那怎么用呢?