strerror
char* strerror (int errnum)
作用:用于把错误码转换成错误信息,返回错误信息的起始地址。
错误码:当c语言在运行时,若发生错误,会讲错误码存在一个变量中,这个变量是errno
错误码是一些数字:1,2,3,4,5......
如下
int main()
{
printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
printf("%s\n", strerror(4));
printf("%s\n", strerror(5));
printf("%s\n", strerror(6));
return 0;
}
//把错误码翻译成错误信息
结果如下,每一份错误码对应一个错误
前面说过,这些错误码会存在变量errno里,这个变量也是个全局变量
所以一般用
printf("%s\n",strerror(errno))
要引用string.h和errno.h两个头文件
另一个报错函数是perror
perror
void* perror (const char* str)
相当于printf+strerror,会直接打印出错误信息,且在打印错误信息之前,会先打印自定义信息
perror("错误是:")
//结果是:错误是:ERROR.....
内存相关函数
memcpy
void* memcpy(void*des,const void*src,size_t num)
作用:拷贝。
返回类型是目标空间地址(首地址)
字符串的拷贝用strcpy,其他类型用memcpy
---------------------------------------------------------------------------------------------------------------------------
用void*来接收参数,是因为不知道接受的指针是什么类型,而void*类型可以接收所有类型指针。
void*,表示指向一个void类型的指针,所以指针变量所占的空间字节与指针指向的变量没关系,也就是上面说的,什么类型的变量,void*类型的指针都能接收。只不过void*类型指针在+-数时,要先进行强制类型转换才行。
----------------------------------------------------------------------------------------------------------------------------
des是开始放置的地址,src是开始拷贝内容的地址,num是拷贝的字节个数。
前面的strncpy是拷贝的字符个数,这里num是字节个数。
memcpy模拟再现
void* my_memcpy(void* dest, const void* src, size_t num)
//void*,能返回地址,只是类型要自己强制类型转换
{
void* ret = dest;
assert(dest && src);
while (num--)
{
*(char*)dest = *(char*)src;
//一个字节一个字节拷贝,所以强制类型转化为char*,正好能一个字节一个字节的看.
//强制类型转换(char*)是暂时的
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
memmove
作用:移动内存内容
memmove和memcpy的使用方法完全一样,包括返回类型,参数类型,参数含义.
memmove要强于memcpy,在某些情况下memcpy会出错,而memmove不会,比如自己拷贝给自己,memcpy可能会因为源空间被目标空间所覆盖导致出错。(有些编译器不会出现这个问题)
模拟再现
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)
{
//从前向后(和memcpy一样的)
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//从后向前
while (num--)
{
*((char*)dest+num) = *((char*)src + num);//源头的第20个字节
}
}
return ret;
}
memcmp
int memcmp(const void*ptrl,const void* ptr2,size_t num)
作用:比较两内容
num是比较的字节个数,按位比较,注意大小端。
ptr1>ptr2,返回>0的数
ptr1<ptr2,返回<0的数
ptr1=ptr2,返回0
int main()
{
int arr1[] = { 1,2,3 };//01 00 00 00 02 00 00 00 03 00 00 00
int arr2[] = { 1,2,4 };//01 00 00 00 02 00 00 00 04 00 00 00
int ret = memcmp(arr1, arr2, 9);
printf("%d\n", ret);
return 0;
}
小端 ,所以9个字节正好到最后够一个数进行比较(正常使用不推荐这样)
比较得,ret<0
memset
void* memset(void*ptr,int value,size_t num)
作用:以内存为单位来设置内存中的数据。
prt:被设置的位置,开始设置的起点。
value:要设置的值
num:要改动几个字节
int main()
{
char arr[] = "hello world";
//把hello全部改成x
memset(arr, 'x', 5);
printf("%s", arr);
memset(arr + 6, 'y', 5);
printf("%s", arr);
return 0;
}
因为是以字节为单位改的,改数字会行不通,因为一个数(int)是4字节,一次只能改一个字节为value。除了改成0.