原文:C语言常用的库函数总结(道友,看这个飞升吧) - XT杂谈 (yzre.cn)
一,前言:
因为c中的库函数种类非常多,所以我总结了我认为非常重要的库函数放在这里,希望大家可以熟记,早日走出新手村。
我的顺序是按照一种新奇的顺序排列的,因为我认为你可能这样学会更加有利于你对C语言的理解,因为有一种似曾相识的感觉。
注意:本文章适合那些刚学完c基础或者对库函数不理解的那些道友们,所以大佬和纯小白可以直接走啦!还有就是留下一个免费的赞鼓励一下博主吧,我真的真的很努力啦。
那么,开始了道友!
二,库函数大总
###
一,内存函数(头文件<stdlib.h>)
1.memcpy(内存拷贝函数)
先看代码原型:
//代码原型: void* memcpy(void*destination,const void* source,size_t num); //翻译:destination(方向) source(来源) num(数)
解释: 从存储区 soure 复制 num 个字节到存储区 destination
1.这里前两个指针的类型还有函数的返回值都是void*,因为memcpy这个函数是内存拷贝函数,它有可能拷贝整形,浮点型,结构体等各种类型的数据(虽然返回值是void* ,但他也是必不可少的,void*也表示一个地址,用户可以把它强制转换为自己需要的类型去使用)
2.destination指向要在其中赋值内容的目标数组,source指向要复制的数据源,num是要复制的字节数
代码举例:
#include<stdio.h> #include<string.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9 }; int arr1[20] = { 0 }; memcpy(arr1, arr, sizeof(arr)); for (int i = 0; i <= 9; i++) printf("%d", arr1[i]); return 0; }
让我们编译并运行上面的程序,这将产生以下结果:
1234567890
2.memmove(内存拷贝函数)
函数原型和memcpy一样,作用也一样,不同的是可以拷贝自己,并且重叠不会出bug!
(后期本人会单独出一期详细解释其中的原理)
3.memcmp(内存比较函数)
先看代码原型:
int memcmp(const void* str1,const void* str2,size_t n )
解释: 把存储区 str1 和存储区 str2 的前 n 个字节进行比较(比较ascll码和的大小)
1.返回值:
-
如果返回值 < 0,则表示 str1 小于 str2。
-
如果返回值 > 0,则表示 str1 大于 str2。
-
如果返回值 = 0,则表示 str1 等于 str2。
2.你可以想象一下登录密码时便可以用这种方式验证,如果返回值非0则密码错误
4.memset(内存充填函数)
先看代码原型:
void* memset(void*str,int value,size_t num)
解释:用于将一段内存区域设置为指定的值。memset() 函数将指定的值 vlaue 复制到 str 所指向的内存区域的前 num个字节中,这可以用于将内存块清零或设置为特定值。在一些情况下,需要快速初始化大块内存为零或者特定值,memset() 可以提供高效的实现。在清空内存区域或者为内存区域赋值时,memset() 是一个常用的工具函数。
1.形参value可以是整型,也可以是字符,因为字符在内存中存的是ASCII(value如果是整数的话,需要注意它的取值范围,因为一个字节最大可以存储255,超过255就会发生截断)
5.malloc(分配内存函数)
先看函数原型:
void* malloc(size_t size)
解释:
分配所需的内存空间,并返回一个指向它的指针。
1.返回值:该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。
代码举例:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char* str; str=(char*)malloc(15); strcpy(str,"hellow"); printf("%s",str); return 0; }
6.calloc(分配内存函数)
先看函数原型:
void* calloc(size_t nitems,size_t size)
参数:
-
nitems -- 要被分配的元素个数。
-
size -- 元素的大小。
解释:
分配所需的内存空间,并返回一个指向它的指针。malloc 和 calloc 之间的不同点是,malloc 不会设置内存为零,而 calloc 会设置分配的内存为零。
1.calloc() 函数将分配的内存全部初始化为零。如果不需要初始化,可以使用 malloc() 函数代替。另外,使用 calloc() 函数时需要注意,如果分配的内存块过大,可能会导致内存不足的问题。
2.返回值:该函数返回一个指针,指向已分配的内存。如果请求失败,则返回 NULL。
7.realloc(分配内存函数)
先看函数原型:
void* realloc(void* ptr,size_t size)
解释:用于重新分配内存空间。它在动态内存管理中非常重要,尤其是在需要调整已分配内存大小的情况下。尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小。
1.ptr -- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
2.size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。
3.返回值:如果成功,realloc()
返回指向新内存块的指针,如果失败,返回 NULL
,并且原来的内存块仍然保持不变(并没有释放)。
注意:
-
realloc()
可能会将内存块移动到新的位置(如果在原位置没有足够的空间容纳新的大小)。如果移动成功,ptr
会指向新位置。需要特别注意,旧的ptr
指针需要被更新为realloc()
返回的新地址。 -
如果内存分配失败,
realloc()
返回NULL
,而原始的内存块不会被释放。为避免内存泄漏,应该使用一个临时指针来接收realloc()
的返回值,并检查是否为NULL
。
代码举例:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char *str; str=(char*)malloc(15); strcpy(str,"hellow"); //重新分配内存 str=(char*)realloc(str,25); strcat(str,"666666") free(str); return 0; }
代码举例2:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { int *arr1=(int*)malloc(5); if(arr1==NULL) { printf("failed"); return 1; } for(int i=0;i<5;i++) { arr1[i]=i*2; } int* arr2=realloc(arr1,10*sizeof(int)); if(arr2==NULL) { printf("failed"); return 1; } for(int i=5;i<10;i++) { arr2[i]=i*2; } for(int i=0;i<10;i++) printf("%d",arr2[i]); free(arr2); arr2=NULL; return 0; }
8.free(释放内存函数)
先看函数原型:
void free(void*ptr)
解释:用于释放由 malloc()
, calloc()
, realloc()
等动态分配函数分配的内存。当动态分配的内存不再需要时,调用 free()
函数可以避免内存泄漏,确保程序有效地管理内存。
1.避免重复释放:同一个内存块不能多次释放,否则可能导致未定义行为。
2.释放内存后,指针仍然指向已释放的内存位置。为了避免悬空指针,可以将指针设为 NULL
。
3.检查空指针:
if (array != NULL) { free(array); array = NULL; }
小结:到目前为止常用的内存管理函数就总结到这里了,由于本人水平有限,如果有错误大家可以在评论区加以更正,我会实时跟新的,让这篇文章变得更加完美。同时我会在后续进一步完善文章内容。
二,字符串函数(头文件<string.h>)
补充:memcmp,memcpy,memmove,memset等函数也可以归结为字符串函数,同时 他们在<stdlib.h>和<string.h>中都有声明。
1.strlen(求字符串长度函数)
先看 函数原型:
size_t strlen(const char*str)
解释:
计算字符串 str 的长度,直到'\0'结束字符,但不包括'\0'结束字符。
1.size_t这是无符号整数类型,它是 sizeof 关键字的结果。
2.因为返回值是size_t,strlen(“abc”)算出的结果是3, strlen("abcde")算出的结果是5,可能想着3-5得到-2,实际上并不是这样的,这里算出的3和5都是无符号整型,算出的-2也是一个无符号整型,-2在内存中以补码的形式存储,从无符号整型的视角看去,这串补码就表示一个很大的正数。
代码举例:
#include <stdio.h> #include <string.h> int main () { char str[50]; int len; strcpy(str, "你好呀,道友 !"); len = strlen(str); printf("|%s| 的长度是 |%d|\n", str, len); return(0); }
2.1strcpy(字符串拷贝函数1)
先看函数原型:
char* strcpy(char*destination, const char*source);
解释:
把 source 所指向的字符串复制到 destination。需要注意的是如果目标数组 destination 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。
代码举例:
#include <stdio.h> #include <string.h> int main() { char src[40]; char dest[100]; memset(dest, '\0', sizeof(dest)); strcpy(src, "你好呀,道友!"); strcpy(dest, src); printf("最终的目标字符串: %s\n", dest); return(0); }
2.2strncpy(字符串拷贝函数2)
先看函数原型:
char* strncpy(char* destination,const char*source,size_t num)
解释:把 source 所指向的字符串复制到 destination,最多复制 num 个字符。当 source 的长度小于 num 时,destination 的剩余部分将用空字节填充。
和strcpy极其相似,希望大家可以对比学习
3.1 strcat(追加字符串1)
函数原型:
char* strcat(char*destination,const char* source)
解释:
字符串追加函数,将源字符串追加到目标字符串后面,目标中的终止字符’\0’会被源字符串的第一个字符覆盖
1.该函数的本质是将\0覆盖了,再再最后追加\0,但是自己改自己会把 \0覆盖不见,最后造成死循环。
代码举例:
#include <stdio.h> #include <string.h> int main () { char src[50], dest[50]; strcpy(src, "This is source"); strcpy(dest, "This is destination"); strcat(dest, src); printf("最终的目标字符串: |%s|", dest); return(0); }
3.2 strncat(追加字符串2)
函数原型:
char* strncat(char* destination,const char* source,size_t num)
解释:
把 source 所指向的字符串追加到 destination 所指向的字符串的结尾,直到 num 字符长度为止。
和strcat极其相似,希望大家可以对比学习
4.1 strcmp(字符串比较函数)
函数原型:
int strcmp (const char* str1,const char* str2)
解释:
把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
1.根据相同位置的ASCII值进行大小的比较。并不是比字符串长度
2.返回值:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
代码举例:
#include <stdio.h> #include <string.h> int main () { char str1[15]; char str2[15]; int ret; strcpy(str1, "abcdef"); strcpy(str2, "ABCDEF"); ret = strcmp(str1, str2); if(ret < 0) { printf("str1 小于 str2"); } else if(ret > 0) { printf("str1 大于 str2"); } else { printf("str1 等于 str2"); } return(0); }
4.2 strncmp(字符串比较函数)
代码原型:
int strncmp(const char* str1,const char*str2,size_t n)
解释:是一个标准库函数,用于比较两个字符串的前 n 个字符是否相等
和strcmp极其相似,希望大家可以对比学习
5.strstr(字符串查找函数)
代码原型:
char*strstr(const char* string,const char*str)
解释:
在字符串 string 中查找第一次出现字符串 str 的位置,不包含终止符 '\0'。
1.返回一个指向string中第一次出现str的指针
2.如果str不是string中的一部分,则返回一个空指针NULL
6.strerror(错误信息查找函数)
代码原型:
char* strerror(int errnum);
解释:
从内部数组中搜索错误号 errnum,并返回一个指向错误消息字符串的指针。strerror 生成的错误字符串取决于开发平台和编译器。
代码举例:
#include <stdio.h> #include <string.h> #include <errno.h> int main () { FILE *fp; fp = fopen("file.txt","r"); if( fp == NULL ) { printf("Error: %s\n", strerror(errno)); } return(0); }
运行结果:
Error: No such file or directory
7.perror(printf和sterror结合的函数)
解释:从内部数组中搜索错误号 errnum,并输出一个指向错误消息字符串的指针
你可以参考strerror这个函数
8.1tolower(转为小写字母函数)
函数原型:
int tolower(int c);
解释:
把给定的字母转换为小写字母。
代码示例:
#include <stdio.h> #include <ctype.h> int main() { int i = 0; char c; char str[] = "RUNOOB"; while( str[i] ) { putchar(tolower(str[i])); i++; } return(0); }
8.2toupper(转为大写字母函数)
这个不多解释,参照tolower即可。
三,数学计算库函数(<math.h>)
<math.h>
是 C 标准库中的一个头文件,包含了大量用于数学运算的函数和宏。这些函数和宏提供了基本的算术运算、三角函数、指数函数、对数函数、幂函数、舍入函数等。这里呢总结了大部分常用的函数内容,希望大家可以从中有所收获。
1.acos()【同理思考asin()和atan()和cos(),sin(),tan()】
函数原型:
double acos(double x);
解释:
acos()
函数接受一个介于 -1 和 1 之间的实数,并返回该值的反余弦值,以弧度为单位。
1.返回值为double类型
代码举例:
#include <stdio.h> #include <math.h> int main() { double x = 0.5; double result = acos(x); printf("acos(%f) = %f radians\n", x, result); return 0; }
2.atan2()
函数原型:
double atan2(double y,double x);
解释:
用于计算两个参数的反正切值。这两个参数表示一个点的 y 坐标和 x 坐标,atan2()
函数返回从 x 轴到点 (x, y) 的角度,以弧度为单位。这个函数比单独使用 atan()
函数更强大,因为它考虑了 x 和 y 的符号,从而可以确定正确的象限。
3.exp()(log()和log10()同理推出)
函数原型:
double exp(double x); double log(double x) //返回 x 的自然对数(基数为 e 的对数) double log10(double x) //返回 x 的常用对数(基数为 10 的对数)。
解释:
用于计算 e 的 x 次幂,其中 e 是自然对数的底数(约为 2.71828)。这是一个常用的数学函数,广泛应用于科学计算、金融和工程等领域。
代码案例:
#include <stdio.h> #include <math.h> int main () { double x = 0; printf("e 的 %lf 次幂是 %lf\n", x, exp(x)); printf("e 的 %lf 次幂是 %lf\n", x+1, exp(x+1)); printf("e 的 %lf 次幂是 %lf\n", x+2, exp(x+2)); return(0); }
4.sqrt()
函数原型:
double sqrt(double x);
解释:
用于计算一个非负数的平方根。这个函数在数学和工程中经常被使用。
代码举例:
#include <stdio.h> #include <math.h> int main () { printf("%lf 的平方根是 %lf\n", 4.0, sqrt(4.0) ); printf("%lf 的平方根是 %lf\n", 5.0, sqrt(5.0) ); return(0); }
5.常量拓展:
以下是 <math.h>
中定义的一些常用数学常量:
常量 | 值 | 描述 |
---|---|---|
M_PI | 3.14159265358979323846 | 圆周率 π |
M_E | 2.71828182845904523536 | 自然对数的底数 e |
M_LOG2E | 1.44269504088896340736 | log2(e) |
M_LOG10E | 0.43429448190325182765 | log10(e) |
M_LN2 | 0.69314718055994530942 | ln(2) |
M_LN10 | 2.30258509299404568402 | ln(10) |
M_PI_2 | 1.57079632679489661923 | π/2 |
M_PI_4 | 0.78539816339744830962 | π/4 |
M_1_PI | 0.31830988618379067154 | 1/π |
M_2_PI | 0.63661977236758134308 | 2/π |
M_2_SQRTPI | 1.12837916709551257390 | 2/√π |
M_SQRT2 | 1.41421356237309504880 | √2 |
M_SQRT1_2 | 0.70710678118654752440 | 1/√2 |
心中无女人,代码自然神。————路仁
2024-11-28 18:50:30 星期四