内存函数

上章我们简单介绍了几个字符串函数,这里先补充几个。

 嘿咻咻咻咻咻,鸡汤来咯。

目录

1.strtok

2. strerror  

3.字符分类函数:

4.内存函数

4.1memcpy

4.2 memmove 

4.3memcmp

 4.4 memset


1.strtok

char * strtok ( char * str , const char * sep );

 这个是cplusplus上的介绍,简单介绍: 

sep 参数是个字符串,定义了用作分隔符的字符集合。
第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或者多个分隔符分割的标 记。
strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
strtok 函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串 中的位置。
strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。
如果字符串中不存在更多的标记,则返回 NULL 指针。

如果我们有这样一个字符数组

char ch[ ] = "abcdefgh.ijk";

我想要拿到abc,用数组也可以达到我们预想的效果,用strtok也可以拿到,上代码:

#include <stdio.h>
#include <string.h>
int main()
{
	char ch[] = "abcdefgh.ijk";
	char buff[200];
	srtcpy(buff, ch);
	const char* p = ".";//可以作为分割符的字符的集合,可以是多个
	strtok(buff,p);//这个函数就是一个分割符,把我们的字符串分割成n段
	//该函数每次找到p中的其中一个字符(一个标记),就将该字符改成'\0',并返回指向这个标记的指针,这里就是a的地址
	//(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
	//所以我们用另一个字符数组来拷贝ch

	return 0;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
	char ch[] = "abcdefgh.ijk";
	char buff[200];
	strcpy(buff, ch);
	const char* p = ".";
	char* str = strtok(buff, p);//strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置。
	printf("%s\n", str);
	char* str1 = strtok(NULL, p);//第二次使用时保存了上一次使用保存好的位置开始继续查找,然后返回这个字段的启示位置。
	printf("%s\n", str1);
	return 0;
}

结果如下:

2. strerror  

strerror 返回错误码,所对应的错误信息。

解释 errnum 的值,生成一个字符串,其中包含一条消息,该消息描述错误条件,就好像库的函数设置为 errno 一样。

返回的指针指向静态分配的字符串,程序不得修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。

拿计算机跑一跑:

 我们传参 0 1 2 3 4都有自己的意义。这里的0 1 2 3 4 都是错误码,比如浏览网站时会看见 404 等。

3.字符分类函数:

这里有很多经常使用的库函数:

iscntrl
任何控制字符
isspace                                    
空白字符:空格 ‘ ’ ,换页 ‘\f’ ,换行 '\n' ,回车 ‘\r’ ,制表符 '\t' 或者垂直制表符 '\v'
isdigit
十进制数字 0~9
isxdigit
十六进制数字,包括所有十进制数字,小写字母 a~f ,大写字母 A~F
islower
小写字母 a~z
isupper大写字母a~z
isalpha
字母 a~z A~Z
isalnum
字母或者数字, a~z,A~Z,0~9
ispunct
标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph
任何图形字符
isprint
任何可打印字符,包括图形字符和空白字符

4.内存函数

4.1memcpy

mem —> memory  记忆,但是在我们计算机语言中一般翻译为内存。

函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 '\0' 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。

它和strcpy很像,但是不一样。我们strcpy只能拷贝字符串,我们看memcpy的参数,都是void*型的,所以我们可以是任意类型。

我们用int类型试一试:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };
	int arr2[10];
	memcpy(arr2, arr1, 40);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

 memcpy第三个参数的单位是字节,所以我这里写的是40。

4.2 memmove 

 将数字字节的值从指向的位置复制到目标所指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和重叠。
指针和目标指针所指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
该函数不检查源代码中的任何终止空字符 - 它始终精确复制数字字节。
为避免溢出,目标和参数所指向的数组大小应至少为数字字节。

可以说memmove是memcpy的一部分。

它和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。
我们写一段代码来试试自己给自己拷贝,看看结果如何:
先看看模拟实现的memcpy:
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
	void* ret = dest;
	assert(dest);
	assert(src);
	while(num--)//这里我们一个字节一个字节的交换
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memcpy(arr1+2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

 再来看看memmove 的结果:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
	memmove(arr+2, arr, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

4.3memcmp

比较从ptr1ptr2指针开始的num个字节

我们重点来看它的返回值:

 对于strcmp相比,memcmp的参数是不固定的,而strcmp的参数都是const chat* 类型。                 相比之下memcmp功能更加强大。

我们跑一段代码试试:

#include <stdio.h>
#include <string.h>
int main()
{
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";
	int n;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));
	if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
	return 0;
}

 4.4 memset

顾名思义memset是内存设置函数,这个函数作为补充,想要了解更多,可以查cplusplus.com

这是未调用memset之前的内存。

 

这是调用之后的内存。 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值