目录
一、函数分为库函数和自定义函数
1.库函数
概念:C语言库函数是C语言标准库(C Standard Library)中提供的一系列预定义函数,这些函数用于执行常见的任务,比如输入输出、字符串操作、数学计算、内存管理、时间日期处理等。这些函数大大简化了C语言编程的复杂性,使得开发者能够更容易地编写出高效、可移植的代码。
下面是一些常用的C语言库函数分类及其示例:
(1)
目录
输入输出函数(stdio.h)
printf()
: 向标准输出设备(通常是屏幕)输出格式化的字符串。scanf()
: 从标准输入设备(通常是键盘)读取格式化的输入。fprintf()
: 向文件写入格式化的字符串。fscanf()
: 从文件读取格式化的输入。fgets()
: 从指定的流中读取一行。fputs()
: 向指定的流写入一个字符串。
(2)字符串操作函数(string.h)
strcpy()
: 复制字符串。strcat()
: 连接两个字符串。strlen()
: 计算字符串的长度(不包括结束符'\0')。strcmp()
: 比较两个字符串。strncpy()
: 复制指定长度的字符串。strncat()
: 连接两个字符串的前n个字符。
(3)数学函数(math.h)
sqrt()
: 计算平方根。pow()
: 计算幂(底数的指数次幂)。sin()
: 计算正弦值。cos()
: 计算余弦值。tan()
: 计算正切值。fabs()
: 计算浮点数的绝对值。
(4)内存管理函数(stdlib.h)
malloc()
: 动态分配内存。free()
: 释放之前用malloc等函数分配的内存。calloc()
: 动态分配内存并清零。realloc()
: 重新调整之前分配的内存大小。
(5)时间日期函数(time.h)
time()
: 获取当前时间(自1970年1月1日以来的秒数)。localtime()
: 将time_t类型的时间转换为本地时间。difftime()
: 计算两个时间点之间的差异(以秒为单位)。
(6)其他库函数
ctype.h
:字符处理函数,如isalpha()
,isdigit()
,toupper()
等。stdlib.h
:除了内存管理外,还包括随机数生成(rand()
,srand()
)、程序控制(exit()
,system()
)等函数。
例1:strcpy函数 - 复制字符串
int main()
{
char arr1[20] = { 0 };
char arr2[] = "hello word";
strcpy(arr1, arr2); //把arr2放到arr1
printf("%s\n", arr1);
return 0;
}
例2:memset函数 - 改变字符串
void main(void)
{
char arr[] = "hello word";
printf("Before: %s\n", arr);
memset(arr, '!', 5);
printf("After: %s\n", arr);
}
2.自定义函数
概念:在C语言中,自定义函数是一种强大的特性,它允许你将代码块组织成可重用的单元。自定义函数不仅可以提高代码的可读性和可维护性,还可以减少代码重复,使程序更加模块化。
基本结构:函数返回类型 函数名(函数参数)
ret_type fun_name(para1, *)
{
statement;//语句项
}
例3:写一个函数可以找出两个整数中的最大值
int get_max(int x, int y)
{
int z = 0;
if (x > y)
z = x;
else
z = y;
return z; //返回较大值
}
int main()
{
int a = 10;
int b = 20;
//函数的调用
int max = get_max(a, b);
printf("max = %d\n", max);
return 0;
}
例4:写一个函数,可以交换两个整形变量的值
void Swap2(int* pa, int* pb) //pa就是a的地址
{
int z = 0;
z = *pa;
*pa = *pb;
*pb = z;
}
int main()
{
int a = 10;
int b = 20;
//函数使用时,函数的参数为:实际参数—实参
//实参可以是:常量、变量、函数、表达式,进行函数调用时,统统传递给形参
Swap2(&a, &b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
二、函数的嵌套调用和链式访问
1.嵌套访问
概念:在C语言中,函数的嵌套调用指的是在一个函数内部调用另一个函数。
下面是一个嵌套调用实例:
void test3()
{
printf("hehe\n");
}
int test2()
{
test3();
return 0;
}
int main()
{
test2();
return 0;
}
2.链式访问
概念:把一个函数的返回值作为另外一个函数的参数
下面是一个链式访问实例:
#include <string.h>
int main()
{
//(1)
int len = strlen("abc");
printf("%d\n", len);
printf("%d\n", strlen("abc")); //链式访问
//(2)
char arr1[20] = { 0 };
char arr2[] = "haha";
strcpy(arr1, arr2);
printf("%s\n", arr1);
printf("%s\n", strcpy(arr1, arr2)); //链式访问
//(3)
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}
三、函数的声名和定义
函数的声明:
(1)告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,无关紧要。
(2)函数的声明一般出现在函数的使用之前。要满足先声明后使用。
(3)函数的声明一般要放在头文件中的。
int main()
{
int a = 10;
int b = 20;
//函数声明一下
int Add(int, int);
int c = Add(a, b);
printf("%d\n", c);
return 0;
}
//函数的定义
int Add(int x, int y)
{
return x + y;
}
四、函数的递归
递归的主要思考方式在于:把大事化小
递归的两个必要条件:
(1)存在限制条件,当满足这个限制条件的时候,递归便不再继续;
(2) 每次递归调用之后越来越接近这个限制条件。
例5:接受一个整型值(无符号),按照顺序打印它的每一位。例如:输入:1234,输出1234.
void print(unsigned int n)
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0; //unsigned:无符号型
scanf("%u", &num); //1234
//递归 - 函数自己调用自己
print(num); //print函数可以打印参数部分数字的每一位
return 0;
}
例6:编写函数不允许创建临时变量,求字符串的长度
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "haha";
//模拟实现一个strlen函数
printf("%d\n", my_strlen(arr));
return 0;
}