优化了命名
This commit is contained in:
556
C07-函数/C7-函数.md
Normal file
556
C07-函数/C7-函数.md
Normal file
@@ -0,0 +1,556 @@
|
||||
# 目录
|
||||
- [目录](#目录)
|
||||
- [函数](#函数)
|
||||
- [函数的定义](#函数的定义)
|
||||
- [函数的传参](#函数的传参)
|
||||
- [函数的调用](#函数的调用)
|
||||
- [嵌套调用](#嵌套调用)
|
||||
- [递归调用](#递归调用)
|
||||
- [函数与数组](#函数与数组)
|
||||
- [一维数组](#一维数组)
|
||||
- [二维数组](#二维数组)
|
||||
- [字符数组](#字符数组)
|
||||
- [函数与指针](#函数与指针)
|
||||
- [指针函数](#指针函数)
|
||||
- [函数指针](#函数指针)
|
||||
- [函数指针数组](#函数指针数组)
|
||||
- [指向指针函数的函数指针数组](#指向指针函数的函数指针数组)
|
||||
|
||||
|
||||
# 函数
|
||||
|
||||
## 函数的定义
|
||||
|
||||
数据类型 函数名 ( 【数据类型 形参名,数据类型 形参,...】 )
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
printf("argc = %d\n", argc);
|
||||
// 输出传入参数的个数
|
||||
|
||||
// for (int i = 0; i < argc; i++) puts(argv[i]);
|
||||
|
||||
for (int i = 0; argv[i] != NULL; i++) puts(argv[i]);
|
||||
|
||||
// printf("Hello!\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void print_hello(void);
|
||||
|
||||
// 主调函数
|
||||
int main()
|
||||
{
|
||||
print_hello();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// 被调函数
|
||||
void print_hello(void)
|
||||
{
|
||||
printf("Hello world!\n");
|
||||
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 函数的传参
|
||||
|
||||
值传递
|
||||
|
||||
地址传递
|
||||
|
||||
全局变量传参
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if 0
|
||||
int print_value(int a, int b)
|
||||
{
|
||||
printf("%d %d\n", a, b);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// void swap(int i, int j)
|
||||
// {
|
||||
// int tmp;
|
||||
|
||||
// tmp = i;
|
||||
// i = j;
|
||||
// j = tmp;
|
||||
// }
|
||||
|
||||
void swap(int *p, int *q)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = *p;
|
||||
*p = *q;
|
||||
*q = tmp;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int i = 3, j = 5;
|
||||
|
||||
// swap(i, j);
|
||||
// 实际没有交换
|
||||
|
||||
swap(&i, &j);
|
||||
|
||||
printf("%d %d\n", i, j);
|
||||
|
||||
|
||||
// print_value(i, j);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 函数的调用
|
||||
|
||||
### 嵌套调用
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int max(int a, int b, int c)
|
||||
{
|
||||
int tmp;
|
||||
tmp = a > b ? a : b;
|
||||
|
||||
return tmp > c ? tmp : c;
|
||||
}
|
||||
|
||||
int min(int a, int b, int c)
|
||||
{
|
||||
int tmp;
|
||||
tmp = a < b ? a : b;
|
||||
|
||||
return tmp < c ? tmp : c;
|
||||
}
|
||||
|
||||
int dist(int a, int b, int c)
|
||||
{
|
||||
return max(a, b, c) - min(a, b, c);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 3, b = 5, c = 10;
|
||||
|
||||
printf("result = %d\n", dist(a, b, c));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 递归调用
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void c(void)
|
||||
{
|
||||
printf("[%s]begin!\n", __FUNCTION__);
|
||||
printf("[%s]end!\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void b(void)
|
||||
{
|
||||
printf("[%s]begin!\n", __FUNCTION__);
|
||||
printf("[%s]call c()!\n", __FUNCTION__);
|
||||
c();
|
||||
printf("[%s]c() returned!\n", __FUNCTION__);
|
||||
printf("[%s]end!\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void a(void)
|
||||
{
|
||||
printf("[%s]begin!\n", __FUNCTION__);
|
||||
printf("[%s]call b()!\n", __FUNCTION__);
|
||||
b();
|
||||
printf("[%s]b() returned!\n", __FUNCTION__);
|
||||
printf("[%s]end!\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("[%s]begin!\n", __FUNCTION__);
|
||||
printf("[%s]call a()!\n", __FUNCTION__);
|
||||
a();
|
||||
printf("[%s]a() returned!\n", __FUNCTION__);
|
||||
printf("[%s]end!\n", __FUNCTION__);
|
||||
// out:
|
||||
// [main]begin!
|
||||
// [main]call a()!
|
||||
// [a]begin!
|
||||
// [a]call b()!
|
||||
// [b]begin!
|
||||
// [b]call c()!
|
||||
// [c]begin!
|
||||
// [c]end!
|
||||
// [b]c() returned!
|
||||
// [b]end!
|
||||
// [a]b() returned!
|
||||
// [a]end!
|
||||
// [main]a() returned!
|
||||
// [main]end!
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 函数与数组
|
||||
|
||||
### 一维数组
|
||||
|
||||
```c
|
||||
int a[N] = {1,2,3,4,5,6};
|
||||
int *p = a;
|
||||
```
|
||||
|
||||
| 传参 | 类型 |
|
||||
| ----- | ----- |
|
||||
| a | int * |
|
||||
| *a | int |
|
||||
| a[0] | int |
|
||||
| &a[3] | int * |
|
||||
| p[i] | int |
|
||||
| p | int * |
|
||||
| *p | int |
|
||||
| p+1 | int* |
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void print_arr(int *p, int size)
|
||||
{
|
||||
int i;
|
||||
printf("%s:%d\n", __FUNCTION__, sizeof(p));
|
||||
// out: 8 指针
|
||||
|
||||
for (i = 0; i < size; i++) printf("%d ", *(p + i));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void func(int *p, int size)
|
||||
{
|
||||
int *tmp;
|
||||
|
||||
for (int i = 0; i < size / 2; i++)
|
||||
{
|
||||
*tmp = *(p + i);
|
||||
*(p + i) = *(p + size - 1 - i);
|
||||
*(p + size - 1 - i) = *tmp;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a[] = {1, 3, 5, 7, 9};
|
||||
|
||||
// printf("%s:%d\n", __FUNCTION__, sizeof(a));
|
||||
// out: 20 5*4
|
||||
|
||||
// print_arr(a, sizeof(a) / sizeof(*a));
|
||||
|
||||
|
||||
for (int i = 0; i < sizeof(a) / sizeof(*a); i++)
|
||||
{
|
||||
printf("%d ", a[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
func(a, sizeof(a) / sizeof(*a));
|
||||
|
||||
for (int i = 0; i < sizeof(a) / sizeof(*a); i++)
|
||||
{
|
||||
printf("%d ", a[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 二维数组
|
||||
|
||||
```c
|
||||
int a[M][N]={...};
|
||||
|
||||
int *p = *a;
|
||||
// p 是指向数组第一行的第一个元素的指针,等价于 &a[0][0]。
|
||||
// 列指针
|
||||
|
||||
int (*q)[N] = a;
|
||||
// q 是指向由 N 个 int 组成的数组的指针,即指向二维数组每一行的指针
|
||||
// 行指针
|
||||
```
|
||||
|
||||
|
||||
|
||||
| 传参 | 类型 |
|
||||
| -------------------------- | -------------------------------------- |
|
||||
| `a[i][j]` | int |
|
||||
| `*(a+i)+j` | int * |
|
||||
| `a[i]+j` 等同于*(a+i)+j | ~~int~~ 正确答案: int * |
|
||||
| `p[i]` | ~~int [N] *~~ 正确答案: int |
|
||||
| `*p` | ~~int [N] *~~ 正确答案: int |
|
||||
| `q[i][j]` | int |
|
||||
| `*q` | ~~int [N] *~~ 正确答案: int * |
|
||||
| `q` | int (*) [N] |
|
||||
| `p+3` | ~~int [N] *~~ 正确答案: int * |
|
||||
| `q+2` | ~~int [N] *~~ 正确答案: int (*) [N] |
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define M 3
|
||||
#define N 4
|
||||
|
||||
void print_douarr(int *p, int n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
printf("%d ", *(p + i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// void print_douarr1(int (*p)[N], int m, int n)
|
||||
void print_douarr1(int (*p)[N], int m, int n)
|
||||
{
|
||||
printf("sizeof(p)=%d\n", sizeof(p));
|
||||
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
// printf("%4d", *(*(p + i) + j));
|
||||
printf("%4d", p[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
float average_score(int *p, int n)
|
||||
{
|
||||
float sum = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
sum += *(p + i);
|
||||
}
|
||||
|
||||
return sum / n;
|
||||
}
|
||||
|
||||
|
||||
void find_num(int (*p)[N], int num)
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
printf("%d ", *(*(p + num) + i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, j;
|
||||
int a[M][N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
|
||||
float ave;
|
||||
|
||||
// ave = average_score(*a, M * N);
|
||||
// printf("ave = %f\n", ave);
|
||||
|
||||
find_num(a, 2);
|
||||
|
||||
|
||||
// print_douarr(&a[0][0], M * N);
|
||||
|
||||
// printf("sizeof(a)=%d\n", sizeof(a));
|
||||
// print_douarr1(a, M, N);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 字符数组
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
char *mystrcpy(char *dest, const char *src)
|
||||
{
|
||||
char *ret = dest;
|
||||
if (NULL != dest && NULL != src)
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *mystrncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n && (dest[i] = src[i]); i++)
|
||||
;
|
||||
|
||||
for (; i < n; i++)
|
||||
dest[i] = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
char str1[] = "helloworld";
|
||||
char str2[128];
|
||||
|
||||
// mystrcpy(str2, str1);
|
||||
|
||||
mystrncpy(str2, str1, 5);
|
||||
|
||||
puts(str2);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 函数与指针
|
||||
|
||||
### 指针函数
|
||||
|
||||
是一个**函数**,返回值是**指针**。
|
||||
|
||||
返回值 * 函数名 (形参)
|
||||
|
||||
如:`int * fun(int);`
|
||||
|
||||
|
||||
|
||||
### 函数指针
|
||||
|
||||
是一个**指针**,指向**函数**。
|
||||
|
||||
类型 (* 指针名) (形参)
|
||||
|
||||
如: `int (*p)(int);`
|
||||
|
||||
|
||||
|
||||
### 函数指针数组
|
||||
|
||||
由**函数指针**组成的数组。
|
||||
|
||||
类型 (*数组名【下标】) (形参)
|
||||
|
||||
如: `int (*arr[N])(int);`
|
||||
|
||||
|
||||
|
||||
### 指向指针函数的函数指针数组
|
||||
|
||||
`int *(*funcp[N])(int)`
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int sub(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 3, b = 5;
|
||||
int ret;
|
||||
// int (*p)(int, int);
|
||||
// int (*q)(int, int);
|
||||
|
||||
int (*funcp[2])(int, int);
|
||||
|
||||
// p = add;
|
||||
// q = sub;
|
||||
|
||||
funcp[0] = add;
|
||||
funcp[1] = sub;
|
||||
|
||||
// ret = p(a, b);
|
||||
// ret = q(a, b);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ret = funcp[i](a, b);
|
||||
printf("ret = %d\n", ret);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user