目录
一、字符函数
字符函数为库函数,包含在头文件<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网站,嘎嘎好用!