字符函数及内存相关函数

目录

一、字符函数

1.字符分类函数

2.字符转换函数

二、内存函数

1.1 memcpy

1.2 模拟实现memcpy函数:

2.1 memmove

2.2模拟实现memmove函数

3.1 memset

4.1 memcmp


一、字符函数

字符函数为库函数,包含在头文件<ctype.h>中,函数参数形式为 int funname(int x),参数和返回值都为int型(传参传char是可以的,int是ASCII码),若参数符合条件则返回真。

1.字符分类函数

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

2.字符转换函数

tolower将大写字母转换为小字字母
toupper将小写字母转换为大写字母

演示:

#include <stdio.h>
#include <ctype.h>
int main()
{
	int i = 0;
	char str[] = "Test, Hello World";
	char c;
	while (str[i])
	{
		c = str[i];
		if (isupper(c))
			c = tolower(c);
		putchar(c);
		i++;
	}
	return 0;
}

结果:

二、内存函数

头文件——<string.h>

1.1 memcpy

·函数memcpy从source的位置开始向后复制num个字节的数据到的destination的内存位置

·函数遇到'\0'不会停下,直到拷贝够了num个字节才停下

·一般用于不重复内容的拷贝

/* memcpy example */
#include <stdio.h>
#include <string.h>

struct {
  char name[40];
  int age;
} person, person_copy;

int main ()
{
  char myname[] = "Pierre de Fermat";

  /* using memcpy to copy string: */
  memcpy ( person.name, myname, strlen(myname)+1 );
  person.age = 46;

  /* using memcpy to copy structure: */
  memcpy ( &person_copy, &person, sizeof(person) );

  printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );

  return 0;
}
//cplusplus网站示例

运行结果:

1.2 模拟实现memcpy函数:

memcpy函数的功能是将一个内存中的内容拷贝到另一个内存中去,与大家更熟悉的strcpy的功能类似,只不过strcpy只能实现字符串的拷贝,而memcpy不限制类型,所以函数参数都是void*类型的,便于接受任意类型指针,num也是需要拷贝的字节数,更灵活,不受类型限制。

memcpy的实现只需要将source中的内容一个字节一个字节的给到destination去,值得注意的是空指针类型不能直接进行加,减,解引用等操作,所以需要强制转换成char*,再进行应用。

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5 };
	my_memcpy(arr1, arr2, 20);
	printf("arr1= ");
	for (int i = 0;i < 5;i++)
	{
		printf("%d ", arr1[i]);
	}
	printf("\n");
	return 0;
}

运行结果为:

模拟成功!

2.1 memmove

可以看到,memmove函数与memcpy参数形式一模一样,其实两者的功能也很相似,不同的是memmove可以处理内存块有重叠的数据,例如将自己的一部分拷到自己的另一个位置上去

如:

此时若用memcpy来实现,则会得到

arr={1,2,3,1,2,3,1,2,9,10}的结果,因为经过的前面的拷贝之后,后面的数据会被覆盖掉(原来的4,5已经变成了1,2),此时source再从那里取数据,就会导致上面的结果。(不排除库里的memcpy函数在VS2022的环境下可以实现重叠内存的拷贝,但在其他的编译环境下就不一定了)这时我们就要用到memmove函数来实现重叠内容的拷贝啦

memmove函数如如何解决数据覆盖问题,从而实现重叠内容的拷贝呢?

试想:

当我们正常的按照从前往后的顺序去一一拷贝

那此时我们反过来,从后往前去拷贝

那是不是只要memmove中都使用从后往前的拷贝顺序就好了呢?再来看:

所以,讨论;

当source位于destination前面的时候,即source<destination,时,从前往后拷;

当source位于destination后面的时候,即source>destination,时,从后往前拷;

总结一下就是:

当重叠部分位于source前面时,从前往后拷;

当重叠部分位于source后面时,从后往前拷;

一句话:重叠部分要先拷!

2.2模拟实现memmove函数

接下来看模拟实现的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (src > dest)
	{   //前—>后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后——>前
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr+3, arr, 20);
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1, arr1 + 3, 20);
	for (int i = 0;i < 10;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
	for (int i = 0;i < 10;i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

运行结果:

3.1 memset

memset的功能是,将ptr中前num个字节设置成value的值。

例:

/* memset example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "almost every programmer should know memset!";
  memset (str,'-',6);
  puts (str);
  return 0;
}

结果:

注意:

该函数内是以字节为单位设置内存的,如果输入为

memset(str,1,6);

得到的就不是111111 every programmer should know memset!

而是十六进制中0x01010101对应的十进制数作为前六位,所以该函数的value值最好是char类型。

4.1 memcmp

 memcmp为内存比较函数,

当ptr1 > ptr2,retur一个>0的数;

当ptr1 = ptr2,retur一个=0的数;

当ptr1 < ptr2,retur一个<0的数;

/* memcmp example */
#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;
}

结果:

关于字符函数与内存相关函数就介绍这么多啦,c/c++查函数,上cplusplus网站,嘎嘎好用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值