一、函数的定义
数据类型 函数名 (数据类型 形参名,数据类型 形参名,···)
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main()
5 {
6 printf("hello world!\n");
7
8 return 0;
9 }
-----------------------------
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./main
hello world!
jxs@jxs-ubuntu:~/Desktop/c language/functions$ echo $?
0
---------------------------
//注释 return 0
jxs@jxs-ubuntu:~/Desktop/c language/functions$ echo $?
0
main
函数传递的参数:int main(int argc,char *argv[])
int argc:
(整形)。计数器,计算从终端窗口中传递的参数个数。char *argv[]:
(char型指针数组)。用于保存从终端中传递过来的参数。
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc,char *argv[])
5 {
6 int i;
7 printf("argc = %d\n",argc);
8 printf("argv[%d]:\n",argc);
9 for(i = 0;i < argc;i++)
10 puts(argv[i]);
11
12 return 0;
13 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./main 313 4 56afs 44 4as5d6f4
argc = 6
argv[6]:
./main
313
4
56afs
44
4as5d6f4
二、函数的传参
1.值传递
传值方式:将实参的值拷贝给形参,在函数内对形参进行操作,操作的对象是实参的拷贝,对实参本身没有影响,在函数结束返回后,形参被丢弃释放,实参的内容不会发生改变。
2.地址传递
传址方式:将实参的地址传递给函数,在函数内对形参的操作等同于对实参进行相同(间接)的操作,函数调用结束返回后,形参同样被释放,实参最后的变化结果就是形参的变化结果。
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void swap(int i,int j) //被调函数
5 {
6 int tmp;
7
8 tmp = i;
9 i = j;
10 j = tmp;
11
12 printf("swap: i = %d,j = %d\n",i,j);
13 }
14
15 int main() //主调函数
16 {
17 int i = 3,j = 8;
18 swap(i,j);
19 printf("main: i = %d,j = %d\n",i,j);
20
21 exit(0);
22 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./func
swap: i = 8,j = 3 //形参的值发生了交换
main: i = 3,j = 8 //实参的值未发生交换
因为在调用
swap
函数后,仅仅是对形参进行了操作,实参并没有受到影响。
//对swap函数进行一下更改:
int swap (int *p,int *q)
{
int tmp;
tmp = *p;
*p = *q;
*q = tmp;
//main() 中更改:
swap(&i;&j);
}
3.全局变量
三、函数的调用
1.函数的嵌套调用
求解一个数组的最大最小值,并求解其差值。
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 //求最大值
4 int max_value(int *arr,int num)
5 {
6 int max,i;
7 max = arr[0];
8
9 for(i = 1;i < num;i++)
10 {
11 if(max < arr[i])
12 {
13 max = arr[i];
14 }
15 }
16 printf("max = %d\n",max);
17 return max;
18 }
19 //求最小值
20 int min_value(int *arr,int num)
21 {
22 int min,i;
23 min = arr[0];
24
25 for(i = 1;i < num;i++)
26 {
27 if(min > arr[i])
28 {
29 min = arr[i];
30 }
31 }
32 printf("min = %d\n",min);
33 return min;
34 }
35 //求差值
36 int min_max(int *arr,int num)
37 {
38 return max_value(arr,num) - min_value(arr,num);
39 }
//主函数
40 int main()
41 {
42 int i = 5;
43 int j;
44 int arr[5] = {1,2,5,6,8};
45 j = min_max(arr,i);
46 printf("max - min = %d\n",j);
47
48 return 0;
49 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./max-min
max = 8
min = 1
max - min = 7
2.函数的递归调用
一个函数在它函数体内调用其自身称为递归调用,这种函数称为递归函数。执行递归函数将反复调用其自身,每调用一次就会进入新的一层,当最内层的函数执行完毕后,再一层一层的由里向外退出。
-
递归求阶乘
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int factor(int n)
5 {
6 //n=5,n! = 5 * 4! = 5 * 4 * 3! = ...
7 if(n < 0)
8 return -1;
9 if(n == 1 || n == 0)
10 return 1;
11 return n * factor(n - 1);
12 }
13
14 int main()
15 {
16 int num,fac;
17
18 printf("input number: ");
19 scanf("%d",&num);
20 fac = factor(num);
21 printf("%d! = %d\n",num,fac);
22
23 return 0;
24 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./factorial
input number: 5
5! = 120
-
Fibonacci 数列
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int fibo(int num)
5 {
6 if(num < 1)
7 return -1;
8 if(num == 1 || num == 2)
9 return 1;
10 return fibo(num -1) + fibo(num - 2);
11 }
12
13 int main()
14 {
15 int res,n;
16
17 printf("input num : ");
18 scanf("%d",&n);
19 res = fibo(n);
20 printf("fib %d = %d\n",n,res);
21
22 return 0;
23 }
输出结果:
// 1 1 2 3 5 8 13 21
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./Fibonacci
input num : 5
fib 5 = 5
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./Fibonacci
input num : 7
fib 7 = 13
四、函数与数组
1.函数与一维数组
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void print_arr(int *arr,int n)
5 {
6 int i;
7 printf("[%s]:size of arr = %ld\n",__FUNCTION__,sizeof(arr));
8 for(i = 0;i < n;i++)
9 printf("%d ",arr[i]);
10 printf("\n");
11 }
12
13 int main()
14 {
15 int arr[] = {1,12,41,12,3,12};
16 print_arr(arr,sizeof(arr)/sizeof(*arr));
17
18
19 return 0;
20 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./func_arr
[print_arr]:size of arr = 8
1 12 41 12 3 12
其中,
void print_arr(int *arr,int n)中的形参可以修改为(int arr[],int n)
,但是arr[]
本质上仍是一个指针。形参中arr[]
是指针,定义中arr[]
是一维数组。
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 void print_arr(int *arr,int n)
5 {
6 int i;
7 printf("[%s]:size of arr = %ld\n",__FUNCTION__,sizeof(arr));
8 for(i = 0;i < n;i++)
9 printf("%d ",arr[i]);
10 printf("\n");
11 }
12
13 void reverse_order(int arr[],int n)
14 {
15 int i = 0,j = n - 1;
16 int tmp;
17 for(;j - i >= 1;i++,j--)
18 {
19 tmp = arr[i];
20 arr[i] = arr[j];
21 arr[j] = tmp;
22 }
23 }
24 int main()
25 {
26 int arr[] = {1,56,98,36,45,87,659,552,12,2};
27 print_arr(arr,sizeof(arr)/sizeof(*arr));
28 reverse_order(arr,sizeof(arr)/sizeof(*arr));
29 print_arr(arr,sizeof(arr)/sizeof(*arr));
30
31 return 0;
32 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./func_arr
[print_arr]:size of arr = 8
1 56 98 36 45 87 659 552 12 2
[print_arr]:size of arr = 8 //在形参中 *arr --> arr[]后 arr 仍然是一个指针
2 12 552 659 87 45 36 98 56 1
2.函数与二维数组
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define M 3
5 #define N 2
6
7 //void print_douarr(int p[][N],int m,int n)
8 void print_douarr(int (*p)[N],int m,int n)
9 {
10 int i,j;
11 for(i = 0;i < m;i++)
12 {
13 for(j = 0;j < n;j++)
14 {
15 //printf("%4d ",p[i][j]);
16 printf("%4d ",*(*(p + i) + j));
17 }
18 printf("\n");
19 }
20
21 }
22
23 int main()
24 {
25 int arr[M][N] = {1,25,6,8,9,2};
26 print_douarr(arr,M,N);
27
28 return 0;
29 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./douarr
1 25
6 8
9 2
求解平均值:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define M 3
5 #define N 4
6
7 void find_num(int (*p)[N],int num)
8 {
9 int i;
10 for(i = 0;i < N;i++)
11 {
12 printf("%d ",*(*(p + num)+i));
13 }
14 printf("\n");
15 }
16
17 float avr(int *p,int n)
18 {
19 int i;
20 float sum;
21
22 for(i = 0;i < n;i++)
23 {
24 sum += p[i];
25 }
26 return sum/n;
27 }
28
29 int main()
30 {
31 int a[M][N] = {1,5,6,8,9,4,9,49,45,78,2,48};
32 float avr_value = avr(&a[0][0],M * N);
33 int num;
34 printf("the average value of a is : %f\n",avr_value);
35 scanf("%d",&num);
36 find_num(a,num);
37
38 return 0;
39 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./average
the average value of a is : 21.416666
1
9 4 9 49
3.函数与字符数组
示例代码:strcpy
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define M 128
5
6 char *mystrcpy(char *dest,const char *src)
7 {
8 char *res = dest;
9 if(dest != NULL && src != NULL)
10 while((*dest++ = *src++) != '\0');
11
12 return res;
13
14 }
15
16 int main()
17 {
18 char str1[] = "hello";
19 char str2[M];
20
21 mystrcpy(str2,str1);
22 puts(str2);
23
24 return 0;
25 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./chararr
hello
五、函数与指针
1.指针函数(本质是函数,返回值是指针)
使用格式:返回值 *函数名(形参);
示例:int *func(int);
示例代:指针函数int *find_num(int (*p)[N],int num)
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define M 3
5 #define N 4
6
7 #if 0
8 void find_num(int (*p)[N],int num)
9 {
10 int i;
11 for(i = 0;i < N;i++)
12 {
13 printf("%d ",*(*(p + num)+i));
14 }
15 printf("\n");
16 }
17 #endif
18 int *find_num(int (*p)[N],int num)
19 {
20 if(num > M - 1) //前提条件(行)
21 return NULL; //指针函数返回为NULL
22 return *(p + num); //指针函数返回为第num行首地址
23
24 }
25 float avr(int *p,int n)
26 {
27 int i;
28 float sum;
29
30 for(i = 0;i < n;i++)
31 {
32 sum += p[i];
33 }
34 return sum/n;
35 }
36
37 int main()
38 {
39 int a[M][N] = {1,5,6,8,9,4,9,49,45,78,2,41};
40 float avr_value = avr(&a[0][0],M * N);
41 int i, num;
42 int *res;
43
44 printf("the average value of a is : %f\n",avr_value);
45 scanf("%d",&num); //输入要查找的行
46 res = find_num(a,num);
47
48 if(res != NULL)
49 {
50 for(i = 0;i < N;i++)
51 printf("%d ",*(*(a + num) + i)); //顺序读取第num行的列元素
52 printf("\n");
53 }
54 else
55 {
56 printf("Can't find it!\n");
57 }
58
59 return 0;
60 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./average
the average value of a is : 21.416666
1
9 4 9 49
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./average
the average value of a is : 21.416666
2
45 78 2 41
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./average
the average value of a is : 21.416666
0
1 5 6 8
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./average
the average value of a is : 21.416666
3
Can't find it!
jxs@jxs-ubuntu:~/Desktop/c language/functions$
2.函数指针:(本质是一个指针,是指向函数的一个指针)
使用格式:类型 (*指针名)(形参);
示例:int (*p)(int);
示例代码:函数指针是int (*sum)(int[i],int[j]),
i,j
可省.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int add(int a,int b)
5 {
6 return a + b;
7 }
8
9 int main()
10 {
11 int i = 6,j = 10 ;
12 int (*sum)(int,int);
13 sum = add; //sum = &add is also true.
14 int ret = sum(i,j); //... = *sum(i,j) is also true.
15
16 printf("sum of %d & %d is : %d",i,j,ret);
17 printf("\n");
18
19 exit(0);
20 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./func_point
sum of 6 & 10 is : 16
3.函数指针数组:(本质是数组,数组中的元素是多个函数指针构成的)
使用格式:类型 (*数组名[下标])(形参);
示例:int (*arr[N])(int);
示例代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int add(int a,int b)
5 {
6 return a + b;
7 }
8
9 int sub(int a,int b)
10 {
11 return a - b;
12 }
13
14 int main()
15 {
16 int i = 10,j = 9;
17 int k;
18 int (*func[2])(int,int);
19 func[0] = add;
20 func[1] = sub;
21 int ret;
22 for(k = 0;k < 2;k++)
23 {
24 printf("func[%d]-->%s : %d\n",k,__FUNCTION__,func[k](i,j));
25 }
26
27 exit(0);
28 }
输出结果:
jxs@jxs-ubuntu:~/Desktop/c language/functions$ ./func_point_arr
func[0]-->main : 19
func[1]-->main : 1
指向指针函数的函数指针数组:int *(*funcp[N])(int)