文章目录
前言
函数(function)是完成特定任务的独立程序代码单元
一、函数
函数是完成特定任务的独立程序代码单元
分为自定义函数(自己写的函数)和库函数(C语言内部提供的函数)
1.函数的定义
由函数头和函数体组成,而函数体包括了函数的返回类型、函数名、函数参数
返回类型 函数名(函数的参数) //函数头
{
语句项; //函数体
}
其中,函数定义中的参数是形参,即形式参数;在调用函数时要传给函数的值叫做实参,即实际参数
2.函数的声明
函数声明就是告诉编译器有一个函数,这个函数的函数名、返回类型、参数都是什么
返回类型 函数名(参数1,参数2,...);
分号表明这是在声明函数,不是定义函数
3.函数的调用
函数调用就是使用函数
函数名(参数1,参数2,...);
括号里的参数是形参,函数调用时的实参传给形参
4.传值调用和传址调用
传值调用:函数的形参和实参分别占有不同的内存块,改变形参,不能改变实参
传址调用:把函数外部创建变量的内存地址传递给函数参数
对于传值调用,实参传给形参,其实形参是实参的一份临时拷贝
对于传址调用,函数内部可以通过函数接收的实参的地址从而访问实参,进而修改实参
二、写一个函数,交换两个整型变量的值
错误的函数定义(传值调用)
//写一个函数,交换两个整型变量的值
/*
思路:将函数定义为,创建一新变量z,将其
中一个变量x的值赋给z,另一个变量y的值再赋
给x,再将z变化后的值赋给y完成交换
*/
#include<stdio.h>
void exchange(x, y); //函数声明
int main()
{
int a = 22;
int b = 33;
printf("交换前:a=%d b=%d\n", a, b);
exchange(a, b); //函数调用
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
void exchange(int x, int y) //函数定义
//(传值调用)
//exchange函数在被调用的时候,实参传给形参,其实形参是实参的一份临时拷贝
{
int z = 0; //实现两个值的交换,思路正确,但函数写法有误!!
z = x;
x = y;
y = z;
}
运行结果:变量 a 和 b 的结果没有互换,函数并没有实现预先的要求
分析:a 和 b 的值确实分别传给了形 x 和 y,但函数交换的是形参 x、y 的值,并没有影响实参 a 和 b 的值,实参传给形参,形参是实参的一份临时拷贝;正确写法应为,将函数的形参改为指针变量,分别指向主函数中两个变量的地址,即通过指针访问到两个实参
正确的函数定义(传址调用)
将函数的参数修改为指针变量,分别指向主函数中两个变量的地址 (传址调用)
#include<stdio.h>
void exchange(x, y);
int main()
{
int a = 22;
int b = 33;
printf("交换前:a=%d b=%d\n", a, b);
exchange(&a, &b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
void exchange(int* x, int* y) //(传址调用)
{
int z = 0; //*x和*y访问的就是主函数中的变量a和b
z = *x;
*x = *y;
*y = z;
}
运行结果:成功实现两个变量的值的交换
三、考虑函数定义的位置
定义函数和调用函数的顺序也是有讲究的
比如在 main 函数中调用了一个函数,并且这个函数的定义是在 main 函数之后的,而又没有提前声明这个函数,那么这种写法就是不合法的
默认情况下,调用一个函数时,在调用的地方之前必须定义过这个函数
具体原因是,程序在第一次使用函数之前必须知道函数的类型,有两种写法:
1.把完整的函数定义放在第一次调用函数的前面
如主函数中调用了一个函数,那么这个函数的定义就得放在主函数前面
2.提前声明函数,把函数信息告知编译器
即在一个程序的开头就声明函数,那么这个函数的定义就写在后面的任意位置就可以了
总结
通用的写法是,将函数声明写在程序的开头;这样,函数的定义写在调用函数的位置的前面还是后面都可以
四、函数的嵌套调用和链式访问
1、函数的嵌套调用
函数不能嵌套定义,但可以嵌套调用
#include<stdio.h>
int test3()
{
printf("Hello!\n");
}
int test2()
{
test3();
return 0;
}
int main()
{
test2();
return 0;
}
2、函数的链式访问
函数的链式访问:把一个函数的返回值作为另一个函数的参数
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[10] = { 0 };
char arr2[] = "Hello";
printf("%s\n", strcpy(arr1, arr2));//(strcpy 函数:把arr2复制给arr1)
return 0;
}
注:**strcpy 函数:**把一个字符串复制给另一个字符串
又例如:
int main()
{
printf("%d", printf("%d", printf("%d", 66)));
return 0;
}
注:printf()函数返回的是打印在屏幕上的字符的个数
分析:先执行第三个printf,即打印66,返回值为2,故第二个printf()打印2,同理第一个printf()打印1