函数就是子程序,是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
123456789101112131415 | int Add(int x,int y)//最前面的int表示这个函数最终会返回一个int型的值。{ int z = 0; z = x + y; return z;} int main() { int a = 10; int b = 20; int sum = Add(a,b); printf("%d\n",sum); return 0;} |
上面的Add就是一个函数。
C语言中函数分类:
- 库函数
- 自定义函数
库函数
什么是库函数?
——C语言本身提供使用的的就是库函数。
查询库函数参考:
strcpy - string copy - 字符串拷贝
strlen - string length - 字符串长度有关
我们可以根据函数名称猜测用途
123456789 | int main(){ char arr1[] = "bit"; char arr2[20] = "########"; strcpy(arr2,arr1); printf("%s\n",arr2);} |
char * strcpy ( char * destination, const char * source );
memset - memory set - 内存设置
123456789 | int main(){ char arr[] = "hello world"; memset(arr, '*', 5);//双引号引用字符串,单引号引用字符 printf("%s\n",arr); //打印的结果是:***** world} |
void * memset ( void * ptr, int value, size_t num );
打印的结果是:***** world
双引号引用字符串,单引号引用字符
自定义函数
自定义函数和库函数一样,有函数名,返回值类型和函数参数。但不一样的是这些都由程序员自己设计。
举个例子:写一个函数找出两个整数的最大值
123456789101112131415161718 | int MAX(int x,int y){ if (x>y) { return x; }else{ return y; }} int main() { int a,b,max; printf("请输入两个整数:->"); scanf("%d,%d",&a,&b); max = MAX(a,b); printf("%d",max); return 0;} |
指针变量和解引用:
123456789 | int main(){ int a = 10; int* pa = &a;//pa就是指针变量 *pa = 20;//解引用操作-通过pa里边存的地址找到a printf("%d",a); return 0;} |
举个例子:写一个函数交换两个整型变量的内容
1234567891011121314151617 | void Exchange(int* pa,int* pb)//用指针接收a,b的地址{ int temp; temp = *pa; *pa = *pb; *pb = temp;} int main() { int a,b; printf("请输入a,b两个整型数字:->"); scanf("%d,%d",&a,&b); printf("输入的a = %d,b = %d\n",a,b); Exchange(&a, &b);//调用Exchange函数 printf("输出的a = %d,b = %d\n",a,b); return 0;} |
注意:下面的函数不能完成要求
1234567 | void Exchange(int x,int y){ int temp; temp = x; x = y; y = temp;} |
实参传给形参时,形参其实是实参的一份临时拷贝。
对形参的修改无法变成对实参的修改。
可以通过上面的指针(将地址传过去)的形式进行修改。
函数的参数
实际参数
真实传递给函数的参数。
实际参数可以是:常量、变量、表达式、函数等。
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。
形式参数
函数名后括号中的变量。
形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。
形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。
函数的调用
传值调用:
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。max = MAX(a,b);
传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
- 这种传参方式可以让函数和函数外边的变量建立起正真的联系,也就是函数内部可以直接操作函数外部的变量。
Exchange(&a, &b);
函数的嵌套调用和链式访问
- 嵌套调用:在一个函数中调用另一个函数。
- 链式访问:把一个函数的返回值作为另外一个函数的参数。
123456789101112
int main() { int len = 0; //1 len = strlen("abc"); printf("%d\n",len); //2、链式访问 printf("%d\n",strlen("abc"));//把strlen的返回值打印,和printf和strlen串在一起,像链条一样。 printf("%d",printf("%d",printf("%d",43)));//打印的结果是4321,因为printf的返回结果是打印在屏幕上的字数。 return 0;}
函数的声明和定义
可以让代码逻辑更清晰,结构明了。
函数的声明和定义在同一文件(一般不这样用):
123456789101112131415161718 | int Add(int x,int y);//在同一文件,函数的声明一般出现在函数的使用之前。要满足先声明后使用。int main() { int a = 10; int b = 20; int sum = 0; //函数调用 sum = Add(a,b); printf("%d\n",sum); return 0;} //函数的定义int Add(int x,int y){ int z = x + y; return z;} |
函数的声明和定义分开写(结构明了):
main.h
1234567891011 | int main() { int a = 10; int b = 20; int sum = 0; //函数调用 sum = Add(a,b); printf("%d\n",sum); return 0;} |
Add.h
1234 | int Add(int x,int y); |
Add.c
12345 | int Add(int x,int y){ int z = x + y; return z;} |