C语言--字符串和内存函数(二)

目录

 

一.字符分类函数

1.islower( )--判断小写字母a~z的函数

(1)参数和返回类型

(2)函数功能

(3)代码演示 

(4)拓展--其他字符分类函数

二. 字符转换函数

1.tolower( )--大写字母转小写字母函数 

(1)参数和返回类型 

(2)函数功能 

2.toupper( )--小写字母转大写字母的函数 

(1)参数和返回类型 

(2) 函数功能

(3)代码演示

(4)实际应用

三.内存相关的函数

1.memcpy( )--内存拷贝函数

(1)参数和相关类型

(2)函数功能

(3)模拟实现

①代码演示

②存在弊端 

(4)原函数的实际应用

 2.memmove( )--内存拷贝函数

(1)参数和返回类型 

(2)函数功能

(3)拷贝逻辑解析

(4)模拟实现

 3.memset( )--填充内存块的函数

(1)参数和返回类型 

(2)函数功能 

(3)代码演示 

 4.memcmp( )--内存比较函数

(1)参数和返回类型 

(2)函数功能 

(3) 代码演示


 

一.字符分类函数

1.islower( )--判断小写字母a~z的函数

(1)参数和返回类型

int islower (int c)
  • 头文件 

(2)函数功能

简要:检测字符 c 是否为小写字母。如果c是一个小写字符,返回一个非0的值;反之,返回0。

(3)代码演示 

判断一个字符是否为小写字母 

#include 
#include 
int main()
{
	char ch = 'w';
	if (islower(ch))
	{
		printf("小写\n");
	}
	else
	{
		printf("非小写\n");
	}
	return 0;
}

 结果:小写

(4)拓展--其他字符分类函数

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 任何可打印字符,包括图形字符和空白字符

 

二. 字符转换函数

1.tolower( )--大写字母转小写字母函数 

(1)参数和返回类型 

int tolower ( int c )
  •  头文件 

(2)函数功能 

 简要:将大写字母转换为小写字母,如果本身为小写字母,则不进行转换

 (3)代码展示

#include 
#include 
int main()
{
	int ret = tolower('a');
	printf("%c\n", ret);

	return 0;
}
结果:A

2.toupper( )--小写字母转大写字母的函数 

(1)参数和返回类型 

int toupper ( int c )
  • 头文件

(2) 函数功能

简要:将小写字母转换为大写字母,如果本身为大写字母,则不进行转换

(3)代码演示

#include 
#include 
int main()
{
	int ret = toupper('a');
	printf("%c\n", ret);

	return 0;
}

结果: A

 (4)实际应用

给定字符串"Test String.\n" ,将该字符串的内容全部转换为小写。

int main()
{
	char str[] = "Test String.\n";
	char* p = str;
	while (*p)
	{
		if (isupper(*p))
		{
			*p = tolower(*p);
		}
		p++;
	}
	printf("%s\n", str);
	return 0;
}

 结果:test string.

 

三.内存相关的函数

1.memcpy( )--内存拷贝函数

(1)参数和相关类型

void * memcpy ( void * destination, const void * source, size_t num )
  • 头文件 

(2)函数功能

简要:将num个字节的值从source指向的位置直接复制到destination指向的内存块,并返回目标空间destination的起始地址。

(3)模拟实现

①代码演示

#include 
#include 
#include 
void* my_memcpy(void* dest, void* src, size_t sz)
{
	assert(dest && src);//确保dest和src不会指向空指针
	while (sz--)
	{
		*(char*)dest = *(char*)src;
	//由于上方强制类型转换是临时的(只在上一行被强制转换),所以这不能写dest++来让指针后移
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5 };
	my_memcpy(arr1, arr2, 20);//前五个整型数据占20个字节的内存

	return 0;
}

结果:拷贝成功C语言--字符串和内存函数(二)_第1张图片 

  • 图示解析

C语言--字符串和内存函数(二)_第2张图片

②存在弊端 

将数组arr1[ ]={1,2,3,4,5,6,7,8,10}的从1开始的前5个整型数据放入从元素3开始的后5个元素的位置中 。

void* my_memcpy(void* dest, void* src, size_t sz)
{
    assert(dest && src);
    void*ret=dest;
	while (sz--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
    return ret;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memcpy(arr1+2, arr1, 20);

	return 0;
}

 结果:拷贝失败

C语言--字符串和内存函数(二)_第3张图片

  •  原因分析 

存在元素覆盖问题

C语言--字符串和内存函数(二)_第4张图片

注:这里虽然模拟实现的memcpy函数不能实现重叠内存拷贝的功能,但是在VS2022环境中memcpy却可以实现重叠内存的拷贝

(4)原函数的实际应用

将数组arr2中的前5个整数数据,拷贝放在arr1中。

#include 
#include 
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5,6,7 };
	memcpy(arr1, arr2, 20);//前五个整型数据占20个字节的内存

	return 0;
}

结果:拷贝成功C语言--字符串和内存函数(二)_第5张图片

 

 将数组arr1[ ]={1,2,3,4,5,6,7,8,10}的从1开始的前5个整型数据放入从元素3开始的后5个元素的位置中 。

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
    memcpy(arr1+2, arr1, 20);

	return 0;
}

 结果:拷贝成功(不同编译器可能产生不同的结果,不推荐使用)

C语言--字符串和内存函数(二)_第6张图片

 2.memmove( )--内存拷贝函数

(1)参数和返回类型 

void * memmove ( void * destination, const void * source, size_t num )

(2)函数功能

简要:用于拷贝字节,如果目标区域(destination所指)和源区域(source所指)有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。当目标区域与源区域没有重叠则和memcpy函数功能相同。 

(3)拷贝逻辑解析

  • 图示解析

C语言--字符串和内存函数(二)_第7张图片

  • 模板总结 

C语言--字符串和内存函数(二)_第8张图片

(4)模拟实现

#include 
#include 
#include 
void* my_memmove(void* dest, const void* src, size_t sz)
{
	assert(dest && src);
	void* ret = dest;//保存dest最初的地址
	if (dest < src)
	{
		//前->后
		int i = 0;
		while (i < sz)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
			i++;
		}
	}
	else
	{
		//后->前
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)src + sz);//sz已执行完--操作,用来拿到dest和src所指向空间的最后一个字节
		}
	}
	return ret;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr, arr + 2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结果:
 8eb924d6d75c4ef29387cc09973c8994.png

 3.memset( )--填充内存块的函数

(1)参数和返回类型 

void * memset ( void * ptr, int value, size_t num )
  •  头文件

(2)函数功能 

 简要:将ptr指向的内存块的前num个字节设置为指定值value(解释为无符号字符)。

(3)代码演示 

#include 
#include 
//memset 是以字节为单位设置内存的
int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'x', 3);
	printf("%s\n", arr);
	return 0;
}

 结果:

a7e35b32a73943a7b2dce7b8bc244b51.png

 4.memcmp( )--内存比较函数

(1)参数和返回类型 

int memcmp ( const void * ptr1, const void * ptr2, size_t num )
  •  头文件

(2)函数功能 

简要: 比较ptr1和ptr2所指向的内存空间的前num个字节的内容。如果ptr1指向内容小于ptr2指向内容,返回小于0的数;如果ptr1指向内容大于ptr2指向内容,返回大于0的数;如果ptr1指向内容等于ptr2指向内容,返回0

注意,与strcmp不同,该函数在找到空字符后不会停止比较。

(3) 代码演示

#include 
#include 
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };
//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
	int arr2[] = { 1,2,3,0x11223344 };
//01 00 00 00 02 00 00 00 03 00 00 00 44 33 22 11 //小端存储
	int ret = memcmp(arr1, arr2, 13);
	printf("%d\n", ret);
	return 0;
}

 结果:-1

 原因:arr1的第13个字节04小于arr2的第13个字节44

 

 

 

 

 

你可能感兴趣的:(c语言,算法,开发语言)