C语言常用函数详解

article/2025/9/21 23:41:22

函数详解:

    • strlen(字符串长度)
    • sizeof(字节大小)
    • strcmp(字符串比较)
    • strcpy(字符串拷贝)
    • strcat(字符串追加)
    • strncpy(字符串按字节拷贝)
    • strncmp(字符串按字节比较)
    • strncat(字符串按字节追加)
    • strstr(查找字符串)
    • strtok(查找符号)
    • memcpy(按字节拷贝数据(任意类型))
    • memmove(按字节拷贝数(任意类型).加强版)
    • memset(按字节修改内容)

strlen(字符串长度)

使用方法:
int 整形变量 = strlen(数组名);
首先我们看官方给出的函数参数和定义
在这里插入图片描述
可以看到,strlen的参数是一个地址,当我们要求一个字符串数组的长度是,给上数组首元素的地址即可,而字符串长度的计算是以 \0为标准的,也就是说,什么时候遇到 \0 ,什么时候就会停止计算长度,我们来模拟实现一下。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int my_strlen(char* p) //获取数组首元素地址,返回类型int
{int i = 0;//创建一个 i 变量来计算数组长度while (*p++) //p解引用的值作为循环条件,当*p == \0,循环停止{i++;//每次解引用后的值不等于\0,i++,}return i; //返回i,i存储的就是字符串的长度
}int main()
{char arr[] = {"123456789"};printf("%d\n",my_strlen(arr));printf("%d",strlen(arr));return 0;
}

在这里插入图片描述

sizeof(字节大小)

使用方法:
int 整形变量 = sizeof(参数);
sizeof计算的是给定参数的大小(以字节为单位),如果给上数组,那么计算的就是数组的大小,sizeof(数组名)计算的是数组的大小,那么使用sizeof(数组名) 除 sizeof(数组下标为0的元素)就能求出数组中有多少个元素。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int main()
{int arr1[] = {1,2,3,4,5};char arr2[] = {"12345"};double arr3[] = {1.2,3.14,6.5};short arr4[] = {1,2,3,4,5};printf("arr1 = %d \n", sizeof(arr1) / sizeof(arr1[0]));printf("arr2 = %d \n", sizeof(arr2) / sizeof(arr2[0]));printf("arr3 = %d \n", sizeof(arr3) / sizeof(arr3[0]));printf("arr4 = %d \n", sizeof(arr4) / sizeof(arr4[0]));printf("arr1 = %d 字节\n", sizeof(arr1));printf("arr2 = %d 字节\n", sizeof(arr2));printf("arr3 = %d 字节\n", sizeof(arr3));printf("arr4 = %d 字节\n", sizeof(arr4));return 0;
}

在这里插入图片描述

strcmp(字符串比较)

使用方法:
int 整形变量 = strcmp(数组名1,数组名2);
strcmp比较两个字符串的时候,是一个字节一个字节比较的,比如说:abcdef和abcdeq比较,当比较到f和q时,按照ASCII码比,q的ASCII码值比f的要大,所以后者要比前者大,假设arr1和arr2比较,strcmp(arr1,arr2),如果arr1 > arr2,返回一个大于0的数字,如果arr1 < arr2,返回一个小于0的数字,如果arr1 == arr2,返回0。
下面我们来模拟实现一下strcmp。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>int my_strcmp(const char* p1, const char* p2)
{while (1){if (*p1++ > *p2++){//只要有一个字符大,直接返回1return 1;}else if (*p1 < *p2){//只要有一个字符小,直接返回 -1return -1;}else if (*p1 == '\0' && *p2 == '\0'){//如果两个字符串都遇到了\0,说明两个字符串之前都是一样的,那么返回0return 0;}}
}int main()
{char arr1[] = {"abcdef"};char arr2[] = {"abcde"};int i = my_strcmp(arr1, arr2);int j = strcmp(arr1,arr2);if (i > 0){printf("arr1大");}else if (i < 0){printf("arr2大");}else{printf("一样大");}printf("\n");if (j > 0){printf("arr1大");}else if (j < 0){printf("arr2大");}else{printf("一样大");}return 0;
}

在这里插入图片描述

strcpy(字符串拷贝)

使用方法:
char * 字符指针 = strcpy(数组名1,数组名2)

模拟实现:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>char* my_strcpy(char* p1, const char* p2)
{char* p = p1;//记录下 p1 的地址,也就是拷贝后字符串的地址//将 p1 和 p2 的元素交换,交换一次 ++一次,直到将\0拷贝纸p1,拷贝结束while (*p1++ = *p2++){;}return p;//返回第一个元素的地址
}int main()
{char arr1[30] = {"*****************************"};char arr2[] = {"hello world!!!"};printf("%s",my_strcpy(arr1,arr2));return 0;
}

在这里插入图片描述
拷贝后,会将\0也拷贝过去,所以现在arr1中的内容是:
在这里插入图片描述
因此只会打印到第一个\0的位置

strcat(字符串追加)

使用方法:
char* 字符指针 = strcat(数组名1,数组名2);

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>char* my_strcat(char* p1,const char* p2)
{char* p = p1;while (*p1 != '\0')//将p1的位置++到最后,也就是字符串末尾{p1++;}while (*p1++ = *p2++)//然后将p2的内容依次追加到p1{;}return p;//返回p1的起始位置
}int main()
{char arr1[20] = {"hello "};char arr2[] = {"world!!!"};printf("%s",my_strcat(arr1,arr2));return 0;
}

在这里插入图片描述
追加字符串会先找到\0的位置再进行追加,然后从\0的位置开始覆盖,所以arr1追加后的内容是:
在这里插入图片描述

strncpy(字符串按字节拷贝)

使用方法:
char* 字符指针 = strncpy(数组名1,数组名2,字节);

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = {"*******************"};char arr2[20] = {"###################"};int arr3[20] = {1,2,3,4,5,6,7,8,9};int arr4[20] = {0,0,0,0,0,0,0,0,0};strncpy(arr1,arr2,1);//将起始位置往后1个字节的内容拷贝到arr1中printf("%s\n",arr1);strncpy(arr1,arr2,5);//将起始位置往后5个字节的内容拷贝到arr1中printf("%s\n",arr1);strncpy(arr3,arr4,4);//将起始位置往后4个字节的内容拷贝到arr3中int i = 0;for (i = 0; i < 9; i++){printf("%d",arr3[i]);}printf("\n");strncpy(arr3, arr4, 36);//将起始位置往后36个字节的内容拷贝到arr3中for (i = 0; i < 9; i++){printf("%d", arr3[i]);}return 0;
}

在这里插入图片描述

strncmp(字符串按字节比较)

使用方法:
char* 字符指针 = strncmp(数组名1,数组名2,字节);
strncmp比较字符串,可以自己设置要比较的的内容,如果要比较前5个字节的内容,只需要把5传给函数即可,返回值和strcmp是一样的。


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = {"abcdef"};char arr2[] = {"abcdefd"};int i = strncmp(arr1,arr2,4);int z = strncmp(arr1,arr2,5);int y = strncmp(arr1,arr2,7);printf("%d\n",i);printf("%d\n",z);printf("%d\n",y);return 0;
}

在这里插入图片描述

strncat(字符串按字节追加)

使用方法:
char* 字符指针 = strncat(数组名1,数组名2,字节);
在这里插入图片描述
和strcat不同的是,strcat是追加整个数组,而strncat是你想要追加几个字节的内容,就会追加几个字节的内容。

strstr(查找字符串)

使用方法:
char* 字符指针 = strstr(数组名1,数组名2);
在一个字符串中查找另一个字符串
如果有,返回被查找的字符串首元素地址,如果没有返回NULL.
我们来模拟实现一下

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>char* my_strstr( char* p1, char* p2)
{char* tmp1 = p1;char* tmp2 = p2;char* p = tmp1;while (*p){p1 = p;p2 = tmp2;while (*p1 != '\0' && *p2 != '\0' && (*p1 == *p2)){p1++;p2++;}if (*p2 == '\0'){return p;}p++;}return NULL;
}int main()
{char arr1[] = { "abccccd" };char arr2[] = { "ccd" };char* p = my_strstr(arr1, arr2);if (p == NULL){printf("找不到");}else{printf("%s", p);}return 0;
}

在这里插入图片描述

strtok(查找符号)

这个函数的使用方法就比较复杂了。
首先假设有一个字符串是zhangsan@11.com
我们要将zhangsan,11,com 分解出来。
也就是说按照符号的分割,截取字符串。
我们知道在上述的字符串当中有两个符号,@ .
我们先将@和.存入一个字符串指针中
然后在使用与strstr函数进行分割
char *p = “@.”;
strstr(arr,p);

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = {"zhangsan@qq.com"};char arr2[100];//使用strstr函数会直接修改数组中的内容,所以我们将数据拷贝到另一个数组中strcpy(arr2,arr1);//将分割的符号存入一个字符指针char* p = "@.";//第一次使用strtok函数,会自动找到@符号,并将@符号改成\0,然后返回@符号之前的字符串首元素地址//除了第一次使用,传参需要字符串首元素地址,往后使用都传NULL即可/*char* str = strtok(arr2,p);printf("%s\n",str);//第二次使用,strtok会自动保存上一次@符号的位置,从@符号的位置往后号分隔符,将第二个分割付改成\0,返回第二个分隔符分割的字符串首元素地址str = strtok(NULL,p);printf("%s\n",str);//第三次使用,从第二个分隔符往后找,如果遇到\0,会默认找完了,返回第二个分隔符后的字符串首元素地址str = strtok(NULL, p);printf("%s\n", str);*/char* str;//这里我们用一个for循环来使用这个函数for (str = strtok(arr1, p); str != NULL; str = strtok(NULL, p)){printf("%s\n",str);}return 0;
}

在这里插入图片描述

memcpy(按字节拷贝数据(任意类型))

使用方法:
char* 字符指针 = memcpy(数组名1,数组名2,字节);
我们来模拟实现一下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>void* my_memcpy(void* p1,const void* p2,size_t num)
{void* p = p1;while (num--){*((char*)p1)++ = *((char*)p2)++;}return p;
}int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9};int arr2[] = {6,6,6,6,6};my_memcpy(arr1, arr2, 20);int i = 0;for (i = 0; i < 9; i++){printf("%d ",arr1[i]);}printf("\n");char arr3[] = {"*****************************"};char arr4[] = {"hello world!!!"};char* p = my_memcpy(arr3,arr4,14);printf("%s", p);return 0;
}

在这里插入图片描述
memcpy和strncpy很相似,但是memcpy可以拷贝任意类型的数据,并且是以字节为单位的,想拷贝几个字节的数据只需要在参数商做修改即可

memmove(按字节拷贝数(任意类型).加强版)

使用方法:
char* 字符指针 = memmove(数组名1,数组名2,字节);
memmove和memcpy的使用方法是一样的,但是有一点强于memcpy,比如说,有一个数组,内容是1 2 3 4 5 6,现在我要将 1 2 3拷贝到 4 5 6的位置上,将数组的前三个元素,拷贝到后三个元素商,就会变成123123,而memcpy做不到这个功能。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>void* my_memmove(void* p1,const void* p2,size_t num)
{void* p = p1;if (p1 < p2){while (num--){*((char*)p1)++ = *((char*)p2)++;}}else{while (num--){*((char*)p1 + num) = *((char*)p2 + num);}}return p;
}int main()
{int arr1[] = {1,2,3,4,5,6,7,8,9};char arr2[] = {"aaaaabbbbb"};my_memmove(arr1+3,arr1,16);my_memmove(arr2+5,arr2,5);printf("%s\n",arr2);int i = 0;for (i = 0; i < 9; i++){printf("%d ",arr1[i]);}return 0;
}

在这里插入图片描述

memset(按字节修改内容)

使用方法:
memset(数组名1,修改内容,字节);

memset,将指点字节的内容进行修改

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>int main()
{int arr[] = {1,2,3,4,5};memset(arr,0,16);int i = 0;for (i = 0; i < 5; i++){printf("%d ",arr[i]);}return 0;
}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/g1l3FKF5.shtml

相关文章

C语言的中常用的函数

一、main函数 一个C程序就是由若干头文件和函数组成&#xff0c;有且只有一个主函数&#xff0c;即main函数。 #include <stdio.h>int main(){printf("c语言主函数");return 0; } C程序就是执行主函数里的代码&#xff0c;C语言中的唯一入口。 main前面的int…

C语言中常用的函数

C语言中常用的函数 1、putchar()函数2、getchar()函数3、pow( a , b )函数4、sqrt( a )函数5、fabs(a)函数6、puts(字符数组)函数——输出字符串的函数7、gets(字符数组)——输入字符串的函数8、strcat(a , b)函数——字符串连接函数9、strcpy函数——字符串复制函数10、strncp…

C语言中的函数(详解)

目录 1.函数是什么 2.c语言中函数的分类&#xff1a; 2.1. 库函数 2. 自定义函数 3. 函数的参数 3.1 实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 4. 函数的调用&#xff1a; 4.1 传值调用 4.2 传址调用 5. 函数的嵌套调用和链…

linux Ubuntu将默认bash修改为csh

Ubuntu将默认bash修改为csh 前言Linux系统中的shell版本问题修改方法bash切换csh方法 前言 为什么要将默认bash修改为csh&#xff0c;有时候安装的软件命令是基于csh写的&#xff0c;如果用bash使用软件就会报错&#xff0c;如&#xff1a;“No command ‘setenv’ found”&…

配置你的 csh/tcsh

配置你的 csh/tcsh 选择 csh/tcsh 和许多刚从 Linux 转到 BSD 的人不同&#xff0c;我并没有装完 BSD 就顺手安装 bash&#xff0c;因为之前除了打命令&#xff0c;我没有用到额外的功能&#xff0c;bash 也好&#xff0c;csh 也罢&#xff0c;在我眼里都是当做 shell 来用。但…

bash 和 tcsh(csh)的不同,带例子

我使用bash和tcsh(csh)过程中总结出的一些异同&#xff0c;附我的彩色的提示行配置 效果&#xff1a; 自做的彩色提示符 bash PS1 命令提示符 ## PS1\[\033[01;33m\][\D{%y-%m-%d} \t]\[\033[00m\]\[\033[01;32m\][\!]\[\033[00m\]${debian_chroot:($debian_chroot)}\[\03…

Bash与Csh的区别

zz &#xff1a;http://dangdanding.blog.163.com/blog/static/27992981201262595221896/ 一、csh的while循环控制结构及if then: #!/bin/csh -f while ($#argv > 1) if ("$1" "-s") then shift if ($#argv > 1) then set source …

CSH脚本学习

CSH脚本学习笔记(不常见的命令用法) csh中的 > ! 命令与bash中的> 和>| 命令相同&#xff0c;都是写入文件内容。但在bash中表示没有文件则不创建文件。 foreach var &#xff08; list ) command end 是CSH脚本中的循环命令&#xff0c;将list的值逐一赋值给变量var…

Shell编程之Csh和Bash的经验总结

文章目录 前言1. 变量和环境变量设置1. csh2. bash 2. if语句1. csh2. bash 3. while循环1. csh2. bash 4. 数组1. csh2. bash 5. 获取当前文件路径1. csh2. bash 6. 获取当前时间1. csh2. bash 7. 产生随机数并测试1. csh2. bash 8. 补充1. 查看系统默认用的 Shell2. 查看系统…

矩阵转置基本性质

一个矩阵的转置与本身相乘得到对称矩阵 一个矩阵的逆矩阵与本身相乘得到单位矩阵 行列式不等于零&#xff0c;矩阵可逆&#xff0c;反之不可逆 满秩矩阵一定是可逆的

Maple: 矩阵转置

在Maple中用%T的命令执行矩阵转置&#xff0c;具体效果如下

5*5矩阵转置

编写程序&#xff1a;对一个5X5的二维整型数组转置&#xff0c;即行列互换。 要求从键盘输入数组的值&#xff0c;输出转置前及转置后的结果。 如&#xff1a; 输入格式: 输入数组前有如图示的提示&#xff1b; 输出格式: 输出转置前及转置后的结果&#xff0c;输出前有提示…

矩阵转置输出

输入样例 3 2 1 2 3 4 5 6 #include<stdio.h> int main() {int m,n;int a[15][15]{0};//二维数组int i,j;scanf("%d %d",&m,&n);for(i0;i<m;i)for(j0;j<n;j)scanf("%d",&a[i][j]);//先全部输入再进行其他操作for(i0;i<m;i){for…

c语言函数矩阵转置代码,C语言实现矩阵转置

讲解对象&#xff1a;C语言实现矩阵转置 作者&#xff1a;融水公子 rsgz 1随机函数生成矩阵 #include #include #include int main(){ int i,j; int a[5][3]; printf("生成矩阵:\n"); //srand(time(NULL)); for(i0;i<5;i){ for(j0;j<3;j){ a[i][j]rand()%20; }…

vue报错:Failed to resolve directive: modle

问题原因&#xff1a;我把model写成了modle

[Vue warn]: Failed to resolve directive: modle (found in ComponentA)

报错原因&#xff1a;单词拼写错误 解决方法&#xff1a;检查是否将model写成了modle 温馨提示&#xff1a;编写代码要细心且严谨&#xff08;这已经是我第二次犯类似的错误了&#xff09;

Proteus找不到模型文件 Could not find the modle file

这一部分和你Proteus的文件夹地址一样 这些也要一样 且安装路径需要选择英文路径 同理 最后再用管理员模式打开一下就可以了。。。&#xff08;这些都是弱智问题&#xff09;&#xff08;我是弱智&#xff09;

Vue:解决[Vue warn]: Failed to resolve directive: modle (found in Anonymous)

解决问题 [Vue warn]: Failed to resolve directive: modle (found in <ComponentA>) console.error(("[Vue warn]: " msg trace)); 原因是 我把model 写成了 modle 这类错误一般是单词写错了 (found in <Anonymous>) 解决思路

modle bulinder 实践1.Excel坐标转面

1.结果&#xff1a; 1.工具放在内存里可以加快运行速度 2.步骤 a.Excel转表工具 b.创建XY事件图层&#xff08;选用投影坐标系--高斯克吕格-CGCS2000-34坐标系&#xff09; c.筛选工具<生成的是临时表&#xff1b;点转线需要真实存在的表&#xff1b;故进行筛选&#xf…

vue v-modle修饰符.number .trim

语法糖&#xff1a; 在不影响功能的情况下&#xff0c;添加某种方法实现同样的效果&#xff0c;从而方便程序开发。 .number&#xff1a;可以将输入转换成Number类型&#xff0c;否则虽然输入的是数字&#xff0c;但它的类型其实是String。 .trim&#xff1a;自动过滤输入的首尾…