本章目录
字符分类函数
项目 | Value |
---|---|
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 | 任何可打印字符,包含圆形字符和空白字符 |
字符转换函数
int tolower( int c ); 转小写字母
int toupper( int c ); 转大写字母
简单使用
//大写字母转小写
int i = 0;
char str[] = "Test string. \n";
char c;
while (str[i]) {
c = str[i];
//判断是否是大写
if (isupper(c)) {
//转小写字符
c = tolower(c);
}
putchar(c);
i++;
}
内存拷贝函数 memcpy
void* memcpy( void* destination, const void* source, size_t num);
内存拷贝函数,可以拷贝任意类型数据。
原理是,该函数拷贝数据的单位是字节。
函数memcpy从source位置开始向后复制num个字节的数据到destination内存位置。
这个函数遇到'\0'不会停下来。
如果source和destination有任何重叠,复制的结果都是未定义的。
简单使用
int arr1[] = { 0,1,2,3,4 };
int arr2[5] = { 0 };
int i = 0;
memcpy(arr2, arr1, sizeof(arr1));
for (i = 0; i < 5; i++) {
printf("%d\n", arr2[i]);
}
模拟实现
void* my_memcpy(void* dest, const void* src, size_t num) {
assert(dest && src);
void* tmp = dest;
while (num--) {
//强转成最小的char类型来进行内存交换
*(char*)dest = *(char*)src;
//交换后,dest和src指针向后移,指向下一个字节
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return tmp;
}
优化
void* my_memcpy(void* dest, const void* src, size_t num) {
assert(dest && src);
void* tmp = dest;
while (num--) {
*((char*)dest)++ = *((char*)src)++;
}
return tmp;
}
ps.
memcpy函数可以拷贝不重叠内存,也可以拷贝重叠内存。
但是拷贝重叠内存会出问题,比如自己拷贝自己,会丢失数据。
更加强大的内存拷贝函数 memmove
void* memmove( void* destination, const void* source, size_t num );
内存拷贝函数,可以拷贝任意类型数据。
原理是,该函数拷贝数据的单位是字节。
memmove也是内存处理函数,相比memcpy,前者处理的源内存块和目标内存块是可以重叠的。
简单使用
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
//从arr1数组第三位元素开始拷贝
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", arr1[i]);
}
模拟实现 memmove
void* my_memmove(void* dest, const void* src, size_t num) {
assert(dest && src);
void* tmp = dest;
if (dest < src) {
//从前向后拷贝,常规拷贝
while (num--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else {
//从后向前拷贝
while (num--) {
*((char*)dest + num) = *((char*)src + num);
}
}
return tmp;
}
int main() {
int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[10] = { 0 };
//从arr1中拷贝20个字节到arr1+2中
my_memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
内存数据比较函数 memcmp
int memcmp( const void* ptr1, const void* ptr2, size_t num );
比较ptr1和ptr2数据,比较个数是num个字节。
返回值:
<0 ptr1 less than ptr2
=0 ptr1 identical to ptr2
>0 ptr1 greater than ptr2
简单使用
int arr1[4] = { 1,2,3,5 };
int arr2[4] = { 1,2,3,4 };
int ret = memcmp(arr1, arr2, sizeof(arr1));
if (ret > 0) {
printf("arr1 > arr2");
}
else if (ret < 0) {
printf("arr1 < arr2");
}
else {
printf("arr1 = arr2");
}
以字节为单位设置内存 memset
void* memset( void* dest, int c, size_t count);
将缓冲区设置为指定的字符。
在dest指针开始的位置,向后count个字节,设置数据为c。
简单使用
char arr[] = "abcdefg";
memset(arr, '*', 4);
printf("%s\n", arr);