三、函数形式
一、无参数无返回值
1.1 函数定义
void fun(void) //注意这里一定不要加分号 { printf ("我是fun"); }
1.1.1 函数头
// 1. 函数类型: 函数返回值类型,咱们的没有返回值,就是无类型,就要加个void,表示函数没有返回值,或者我们不使用返回值,返回值不写不会报错,C语言允许,c++不允许,不写默认是int // 2.函数名字 名字就是标识符,相当于int a;的a,变量名,其实函数本质也是个变量,只不过是比咱们基本数据类型的变量复杂点儿,仅此而已 1、合法标识符: 1.英文字母/下划线开头,大小写都习惯 2.后面的以字母,数字,下滑线组成 2、不要用与系统同名的函数 3、函数的名字尽量把函数的功能体现出来: // FindMaxNumberFromArray, FindMaxNumber 4、规范 1. 每个单词的首字母大写 // FindMaxNumberFromArray 2. 都是小写,中间用下划线分割 // find_max_number_from_array 3. 易懂(可读性),好看(统一格式)! // 3. 函数参数列表 1. C:标准C语言,函数没参数需要写个void,跟主函数一样, c++没有这层意思,c++不写==void 2. 不写void与写void的区别:不写void表示参数个数不确定,写了表示不接受任何参数
1.1.2 函数体
函数实体,也就是代码部分,代码跟主函数写法一样,没有特殊的, 要有花括号,函数体被花括号包住 // 1. 自定义函数 主函数也是函数,咱们写的函数也是函数,都是函数,本质没有区别的,只不过咱们自己写的叫自定义函数,就是咱们自己随便写的,主函数由系统调用 // 2. 系统函数 printf scanf 等等以后咱们学到会涉及上千个系统函数,这个函数跟咱们的函数也没有区别,为什么叫系统函数?因为这些函数都是微软那群提前定义好了,咱门直接使用,所以就给起个系统函数的名字,这些函数本质跟咱们自定义的一样一样的。
1.2 函数调用
1.2.1 形式
fun(); // 函数名字+小括号 小括号里是参数列表,没有参数就什么都不用写, 返回值的void也不要加
1.2.2 函数地址
/* 函数调用的本质是 函数地址+(参数列表) 函数名字就是函数地址 对函数名字& 即&fun 也是函数地址, fun == &fun (这个一定要注意,这两个等价的一模一样,用哪个都行) */ #include<stdio.h> void fun(void) { printf("This is fun\n"); } int main(void) { fun(); printf("%p, %p\n", fun, &fun); // 00291339, 00291339 return 0; }
二、无参数有返回值
2.1 函数定义
2.1.1 返回值
int fun1(void) { printf ("我是fun"); return 4; } #include<stdio.h> int fun2(void) { printf("This is fun\n"); } int main(void) { int a = fun2(); printf("%d\n", a); return 0; } /* void是无返回值,有具体类型的就是有返回值 int的意义: 1. 函数返回值类型/函数类型,我们说,函数可以理解成一个复杂点儿的变量,当有返回值的时候,该函数就会有一个值,int a = 2;a这个变量的值是2,函数的值由return的值决定,那这个函数的值就是4; 2. 不写return返回值会咋样?会随机返回一个数字 3. 注意:数据要跟函数返回值的类型一样 */
2.1.2 函数调用
#include<stdio.h> int fun() { return 4; } int main(void) { int a = fun(); printf("a = %d, fun() = %d", a, fun()); return 0; } /* 1. 就可以int a = fun(); 用一个变量装这个函数的值4,注意不能 fun() = 12; fun()相当于一个常数4,只能用,不能对其修改 2. 还可以直接输出 printf ("%d", fun()); 3. fun()还可以参与运算,int c = 12 + fun() * 3; 4. 有返回值但也可以不用理会,直接调用fun(); 5. 有返回值的函数是一个 表达式,表达式就会有一个结果,结果就是return的值,类型由返回值类型决定 6. 注意使用的时候一定要加上(),不加()是把函数地址用于运算 */
2.1.3 return
1. return 数据;
用于有返回值的函数, 终止所在函数的执行,并返回指定数据
可以多个return,但是只执行代码逻辑顺序中的第一个2. return ;
用于无返回值的函数中 , 终止函数执行
3. 返回多个值
return一次只能返回一个值
可以返回一段连续空间的首地址。这段空间里装着多个值,也就是返回一个数组的首地址
2.2 函数声明/函数原型
int fun(void); // 函数头加个分号
三、有参数无返回值
3.1 函数定义
void fun(int a, double b) { printf ("我是fun%d,%lf\n", a, b); }
3.1.1 返回值
void无返回值
3.1.2 参数列表
1. 作用
函数与外界交互的接口,将函数外部的数据传递进函数内,把内部的数据传递出去2. 写法
连续定义几个变量,用逗号隔开
这个变量不要初始化,c++有初始化的语法,c语言没有
名字别冲突
3.1.3 函数调用
fun(2,3.2); // 类型对应上,个数对应上,顺序对应上(按照位置一对一传递数据)
3.2 函数原型/函数声明
void fun(int a, int b); void fun(int , int ); // 两种类型都可以
3.3 通过参数把数据传递到外部并修改
// 通过参数修改外部变量的值 #include<stdio.h> void fun(int* p) { printf("*p = %d\n", *p);// 12 *p = 3; printf("*p = %d\n", *p); // 3 } int main(void) { int a = 12; printf("a = %d\n", a); // 12 fun(&a); printf("a = %d\n", a); // 3 return 0; }
3.4 通过函数修改指针类型
// 通过函数修改指针变量的指向 #include<stdio.h> void fun1(int *p) { // *p 代表是一个指针类型,p1, int代表指向的是int类型 printf("%p\n", p); // 00DCFAD4 p = NULL; printf("%p\n", p);// 00000000 } void fun2(int* *p) { // *p 代表的接受的是指针类型的p1数据, int* 代表 &的地址类型 printf("%p\n", *p); // 00DCFAD4 *p = NULL; printf("%p\n", *p); // 00000000 } int main(void) { int a = 12; int* p1 = &a; printf("修改前 %p\n", p1); // 00DCFAD4 fun1(p1); printf("修改后 %p\n", p1); //00DCFAD4 fun2(&p1); return 0; }
3.5 通过函数交换两个变量的值
#include<stdio.h> void fun(int a, int b) { int temp = a; b = temp; a = b; } void ExchangeValue(int* a, int* b) { int p; p = *a; *b = p; *a = *b; } int main(void) { int a = 10; int b = 12; printf("fun交换前 a = %d, b = %d\n", a, b); fun(a, b); printf("fun交换后 a = %d, b = %d\n", a, b); printf("ExchangeValue交换前 a = %d, b = %d\n",a,b); ExchangeValue(&a, &b); printf("ExchangeValue交换后 a = %d, b = %d\n",a,b); return 0; }
3.6 数组做形参
3.6.1 一维数组做形参
#include<stdio.h> void fun(int* p, int length) // 在形参的位置,C语言的数组 = 指针。 数组的个数是没用的。即等于 = void fun(int p[], int length) { int i = 0; for (i; i < length; i++) { printf("%d\n", p[i]); } } int main(void) { int a[5] = { 1,2,3,4,5 }; fun(a, 5); return 0; }
3.6.2 二维数组做参数
#include<stdio.h> void fun1(int (*p)[3], int hang, int lie) // == void fun(int p[2][3], int hang, int lie) { int i, j; for (i = 0; i < hang; i++) { for (j = 0; j < lie; j++) { printf("%d, %d\n", p[i][j], sizeof(p)); // x, 4 } } } void fun2(int*p, int hang, int lie) { int i, j; for (i = 0; i < hang * lie; i++) { printf("%d\n", p[i]); } } void fun3(int(*p)[2][3], int hang, int lie) { int i, j; for (i = 0; i < hang; i++) { for (j = 0; j < lie; j++) { printf("%d\n", (*p)[i][j]); } } } int main(void) { int a[2][3] = { {1,2,3},{4,5,6} }; fun1(a,2,3); fun2(&a[0][0], 2, 3); fun3(&a, 2,3); // 三種方式都可以 return 0; }
四、有参数有返回值
#include<stdio.h> int FindNum(int *p, int length) { int i; int maxnum = p[0]; for(i=1;i<length;i++) { if (p[i] > maxnum) { maxnum = p[i]; } } return maxnum; } int main(void) { int a[6] = {12,34,32,45,32,21}; int maxnum = FindNum(a, 6); printf("max is %d\n", maxnum); return 0; }