C语言常用函数详解

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++)
		{
		//只要有一个字符大,直接返回1
			return 1;
		}
		else if (*p1 < *p2)
		{
		//只要有一个字符小,直接返回 -1
			return -1;
		}
		else if (*p1 == '\0' && *p2 == '\0')
		{
		//如果两个字符串都遇到了\0,说明两个字符串之前都是一样的,那么返回0
			return 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;
}

在这里插入图片描述

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值