目录
[1. 定义:](#1. 定义:)
[4. 函数声明](#4. 函数声明)
[5. 函数调用](#5. 函数调用)
[6.1. 值传递](#6.1. 值传递)
[6.2. 地址传递](#6.2. 地址传递)
[6.3. 数组传递](#6.3. 数组传递)
[2. strlen](#2. strlen)
[3. strcat](#3. strcat)
1. 定义:
一个完成特定功能的代码模块
2.三要素
功能、参数、返回值
3.格式
存储类型 数据类型 函数名(参数列表)
{
函数体;
return 函数返回值;
}
-
没有参数:参数列表可以省略,也可以使用 void
-
没有返回值:数据类型为void,函数内部没有return
-
有返回值:要根据返回值的数据类型定义函数的数据类型
-
定义子函数时可以直接定义在主函数上面,如果定义在主函数下面需要提前声明函数
4. 函数声明
数据类型函数名(参数列表);//形参
5. 函数调用
-
没有返回值:直接调用:函数名(参数列表); // 实参
-
有返回值:
如果需要接收返回值,就要定义一个与返回值数据类型相同的变量接收
如果不需要接收返回值,就要直接调用函数
简单的使用:
#include <stdio.h>
void fun()
{
printf("hello\n");
}
void add1(int a, int b)
{
printf("%d\n", a+b);
}
int add2(int a, int b)
{
return a + b;
}
int sub(int a, int b);
int main(int argc, char const *argv[])
{
int a = 2, b = 3;
fun();
add1(1, 2);
int num = add2(a, b);
printf("%d\n", num);
int sum = sub(5, 4);
printf("%d\n", sum);
printf("%d\n", sub(5,4));
return 0;
}
int sub(int a, int b)
{
return a-b;
}
练习1:编写一个函数,函数的2个参数,第一个是一个字符,第二个是一个char *,返回字符串中该字符的个数。
练习2:编程实现strlen函数的功能,strlen计算字符串实际长度,不包含'\0'
6.函数传参
6.1. 值传递
单向传递,将实参传递给形参使用,改变形参实参不会受到影响
#include <stdio.h>
int fun(int a, int b)
{
a++;
b++;
return a + b;
}
int main(int argc, char const *argv[])
{
int a = 3, b = 4;
int num = fun(a, b);
printf("%d %d %d\n", a, b, num);
return 0;
}
6.2. 地址传递
双向传递,在函数中修改形参,实参随之变化
#include <stdio.h>
int fun(int *a, int *b)
{
*a = *a + *b;
*b = *b + 2;
return *a + *b;
}
int main(int argc, char const *argv[])
{
int a = 3, b = 4;
// 因为你是拿到了地址,对地址进行赋值,并不是拿到值
int num = fun(&a, &b);
printf("%d %d %d\n", a, b, num);
return 0;
}
6.3. 数组传递
和地址传递一样,参数中存在数组的定义,它也会认为是指针
#include <stdio.h>
char *fun(char str[32])
{
str = "hello";
printf("%d\n", sizeof(str)); // 4
return str;
}
int main(int argc, char const *argv[])
{
char *ch = fun("abc");
printf("%s\n", ch);
return 0;
}
补充:
// s 在栈区空间开辟4字节空间存放字符串常量 "hello" 的首地址
char *s = "hello";
// 在栈区开辟 32 个字节的空间,存放 "hello" 字符串
char str[32] = "hello";
string函数族
1.strcpy
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:实现字符串的复制
参数:dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
#include <stdio.h>
#include <string.h>
int main()
{
char str[32];
char ch[32] = "world";
strcpy(str, ch);
printf("%s\n", str);
return 0;
}
复制包括\0
char *strncpy(char *dest, const char *src, size_t n);
功能:实现字符串复制
参数:dest:目标字符串首地址
src:源字符串首地址
n:字符的个数
返回值:目标字符串首地址
#include <stdio.h>
#include <string.h>
int main()
{
char str[32] = "hello";
char ch[32] = "world";
strncpy(str, ch, 2);
printf("%s\n", str);
return 0;
}
2. strlen
#include <string.h>
size_t strlen(const char *s);
功能:计算字符串的实际长度
参数:s:字符串的首地址
返回值:实际长度
3. strcat
#include <string.h>
char *strcat(char *dest, const char *src);
功能:用于字符串拼接
参数:dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
#include <stdio.h>
#include <string.h>
int main()
{
char str[32] = "hello";
char ch[32] = "world";
strcat(str, ch);
printf("%s\n", str);
return 0;
}
char *strncat(char *dest, const char *src, size_t n);//拼接str的前n个内容
功能:实现字符串拼接
参数:dest:目标字符串首地址
src:源字符串首地址
n:字符的个数
返回值:目标字符串首地址
4.strcmp
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:用于字符串比较
参数:s1、s2字符串的首地址
返回值:
从字符串首个字符开始比较字符ASCII的大小,如果相等继续向后比较
1 s1 >s2
0 s1 == s2
-1 s1 < s2
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "hello";
char s2[] = "worldworld";
char *s3 = "ikun";
char *s4 = "nihao";
char *s5 = "helloworld";
char *s6 = "helloworld";
// int ret = strcmp(s1, s2); // -1
// int ret = strcmp(s1, s3); // -1
// int ret = strcmp(s2, s3); // 1
// int ret = strcmp(s2, s4); // 1
int ret = strcmp(s5, s6); // 0
printf("%d\n", ret);
return 0;
}
int strncmp(const char *s1, const char *s2, size_t n);比较两个字符串前n个字符的大小
递归函数
-
定义:自己调用自己
-
执行过程分为两个阶段
a. 递推阶段:从原问题出发,按递推公式从未知到已知最终达成递归的终止条件
b. 回归阶段:按递推的终止条件求出结果,逆向逐步带入递归公式,回到原问题求解
- 递归的两个必要条件
a. 存在限制条件,当满足这个限制条件的时候,递推便不再继续
b. 每次递推之后会越来越接近这个限制条件
例子:求 5-1的阶乘
例子2:打印一个数的每一位
接收一个整型值,按照顺序打印它的每一位
示例:1234;
输出:1,2, 3, 4;
思路:递归就是把大事化小,函数自己调用自己
按照顺序打印它的每一位我们就用 1234 % 10就会等于4,这样就打印出一个4,那怎么打印其他的数?123 怎么来呢?1234 / 10 = 123,再继续123 % 10 就等于3以此类推