Files
Linux-C-Notes/C07-函数/C7-函数.md
2024-06-23 17:45:58 +08:00

518 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 目录
- [目录](#目录)
- [函数](#函数)
- [函数的定义](#函数的定义)
- [函数的传参](#函数的传参)
- [函数的调用](#函数的调用)
- [嵌套调用](#嵌套调用)
- [递归调用](#递归调用)
- [函数与数组](#函数与数组)
- [一维数组](#一维数组)
- [二维数组](#二维数组)
- [字符数组](#字符数组)
- [函数与指针](#函数与指针)
- [指针函数](#指针函数)
- [函数指针](#函数指针)
- [函数指针数组](#函数指针数组)
- [指向指针函数的函数指针数组](#指向指针函数的函数指针数组)
# 函数
## 函数的定义
数据类型 函数名 【数据类型 形参名,数据类型 形参,...】
```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);
}
```