C语言进阶3:字符串+内存函数
本章重点
-
求字符串长度
- strlen
-
长度不受限制的字符串函数
- strcpy
- strcat
- strcmp
-
长度受限制的字符串函数
- strncpy
- strncat
- strncmp
-
字符串查找
- strstr
- strtok
-
误信息报告
- strerror
-
字符操作
-
内存操作
- memcpy
- memmove
- memcmp
- memset
0.前言:
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中
字符串常量 适用于那些对他不做修改的字符串函数
1.求字符串长度
1.1 strlen
函数介绍:strlen(string length)
size_t strlen(const char* str);
头文件:string.h
函数名:strlen
函数参数:str,参数类型是const char* ,即需要进行求字符串长度的起始地址
函数返回类型: size_t,size_t是unsigned int的类型重定义,是无符号整型。库函数使用size_t类型可能考虑的是字符串的长度不可能是负数,所以用了无符号类型size_t。
函数功能:计算字符串的长度
重点内容
1.字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包 含 ‘\0’ )。
2.参数指向的字符串必须要以 ‘\0’ 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
4.学会strlen函数的模拟实现
strlen函数的模拟实现三种方法:
- 计数器方法
- 递归方法(不创建临时变量求字符串长度)
- 指针 - 指针方法
#include<stdio.h>
#include<assert.h>
//1.计数器实现求字符串长度函数
int my_strlen1(const char* str)//整个过程不改变指针指向内容,加上const
{
assert(str != NULL);//加上断言,防止接收空指针
int count = 0;
while (*str != '\0')//也可以直接用while(*str)
{
count++;
str++;
}
return count;
}
//2.递归实现求字符串长度,不用创建临时变量
int my_strlen2(const char* str)
{
assert(str != NULL);
if (*str != '\0')//也可以直接用if(*str)
{
return 1 + strlen(str + 1);//不能直接使用str++,可以使用++str,建议直接用str+1
}
else
return 0;
}
//3.指针-指针得到中间元素的个数,实现求字符串长度
int my_strlen3(const char* str)
{
assert(str != NULL);
const char* tmp = str;//创建临时指针变量保存str起始值
while (*str != '\0')
{
str++;
}
return str - tmp;
}
int main()
{
char arr[] = "abcdefgh";
int ret1 = my_strlen1(arr);//1.计数器方法
int ret2 = my_strlen2(arr);//2.递归方法
int ret3 = my_strlen3(arr);//3.指针 - 指针方法
printf("%d\n", ret1);
printf("%d\n", ret2);
printf("%d\n", ret3);
return 0;
}
使用注意事项
int main()
{
if (strlen("abc") - strlen("abcdef") > 0)
printf(">\n");
else
printf("<\n");
return 0;
}
//看完这段代码,我们回想到3-6=-3,应该打印:<,
//但运行结果是: >
原因:
strlen的返回类型是:size_t(右击点定义可找到),是typrdef unsigned int的重定义.
所以返回的是无符号数,则肯定是正数,是>0的
2.长度不受限制的字符串函数
2.1 strcpy
函数介绍:strcpy(string copy)
char* strcpy(char* destination,const char* source);
头文件:string.h
函数名:strcpy
函数参数:
-----参数1:destination, 类型:char* ,表示将字符串拷贝的目的地位置
-----参数2:source,类型:char* ,表示被拷贝字符串拷贝的源地址起始位置。函数返回类型: char*, 实际上就是返回destination(目的地)的起始位置
函数功能:字符串拷贝
重点内容
- Copies the C string pointed by source into the array pointed by
destination, including the terminating nulcharacter(and stopping at that point).- 源字符串必须以‘\0’结束。 (源字符串如果没有’\0’, 那么strcpy在拷贝的时候,不知道什么时候停止,可能会造成越界访问)
- 会将源字符串中的’ \0 ’拷贝到目标空间。(从起始地址到’\0’为止)
- 目标空间必须足够大,以确保能存放源字符串。 (目标空间不够大,也会导致越界访问)
- 目标空间必须可变(不能是常量字符串,比如:char* arr1 =“asdsffdf”)
(要将源字符串的内容拷贝到目标空间,目标空间当然要可以变化,才能接收拷贝过来的字符)- 学会模拟实现。
strcpy函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;//储存原字符串首字符地址
//拷贝src指向字符串的内容到dest指向的空间,包括'\0'
//方法一:常规思路版
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
//方法二:代码精简版
while (*dest++ = *src++)//遇到‘/0’为0,循坏停止
{
;
}
//返回目的空间起始位置
return ret;
}
int main()
{
char arr1[] = "abcdefghik";
char arr2[] = "hello";
my_strcpy(arr1, arr2);//模拟实现strcpy函数
printf("%s", arr1);
return 0;
}
2.2 strcat
函数介绍:strcat(string concatenate)
char* strcat(char* destination,const char* source);
头文件:string.h
函数名:strcat
函数参数:
-----参数1:destination, 类型:char* ,表示将字符串追加的目的地位置
-----参数2:source,类型:char* ,表示被追加字符串的源地址起始位置。函数返回类型: char,实际上就是返回destination(目的地)的起始位置*
函数功能:字符串追加
重点内容
- Appends a copy of the source string to the destination string.The
terminating null character in destination is overwritten by the first character of source, and a null - character is included at the end ofthe new string formed by the concatenation of both in destination.- 源字符串必须以‘\0’结束。目标空间也必须包含’\0’,以确定追加的起始位置
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串自己给自己追加,如何 ?
用strcat自己给自己追加会导致程序崩溃,无法实现自己追加自己!(从’\0’开始追加,自己追加自己的时候,’\0‘改成了被追加的首字符,再寻找追加字符串结束的’\0’时,找不到’\0’,会导致死循环)
strcat函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* dest_start = dest;
//1.找到目的空间中的'\0'
while (*dest != '\0')//跳过不是'\0'的字符
{
dest++;
}
//2.追加
while (*dest++ = *src++)
{
;
}
return dest_start;
}
int main()
{
char arr1[30] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);//模拟实现strcat
printf("%s", arr1);
return 0;
}
2.3 strcmp
函数介绍:strcmp (string compare)
int strcmp(const char* str1,const char* str2);
头文件:string.h
函数名:strcmp
函数参数:
-----参数1:str1, 类型:char* ,表示将进行比较的第一个字符串
-----参数2:参数2:str2, 类型:char* ,表示将进行比较的第二个字符串
函数返回类型: int, 返回两个字符串比较的结果函数功能:字符串比较
重点内容
- This function starts comparing the first character of each string.lf they are equal to each other, itcontinues with the following pairs until the characters differ or until a terminating null - character isreached.
- 标准规定︰
- 第一个字符串大于第二个字符串,则返回大于O的数字。
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
strcmp那么如何判断两个字符串? 逐个字符ASCLL码进行比较(不是长度)
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* p1, const char* p2)
{
assert(p1 && p2);
while (*p1 == *p2)
{
if (*p1 == '\0')
{
return 0;
}
p1++;
p2++;
}
//方法一:vs实现的方式
if (*p1 > *p2)
return 1;
else
return -1;
//方法二:linux下gcc实现方式
int my_strcmp(const char* p1, const char* p2)
{
return *p1 - *p2;
}
int main()
{
char* p1 = "abc";
char* p2 = "ab";
int ret = my_strcmp(p1, p2);
printf("ret = %d", ret);
return 0;
}
3.长度受限制的字符串函数(更安全)
3.1 strncpy
函数介绍: strncpy(string copy with specified number of characters)
char* strncpy(char* destination,const char* source,size_t num);
头文件:string.h
函数名:strncpy
函数参数:
-----参数1: destination,类型:char*,拷贝字符的目的地位置,即接收字符的起始位置
-----参数2: source,类型:char* ,拷贝字符的源地址,即拷贝字符串的开始位置。
-----参数3: num,类型size_t,拷贝字符的个数,用来控制拷贝字符的长度。函数返回类型:char* ,返回接收字符的起始位置。
函数功能:指定个数的字符串拷贝
重点内容
- Copies the first num characters of source to destination.lf the end of the source C string(which issignaled by a null - character) is found before num characters have been copied, destination is paddedwith zeros until a total of num characters have been written to it.
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。(源字符串有\0,后面将一直补\0,而不是字符)
- 如果拷贝的字符长度大于目的地空间的容量,则会破坏dest字符串后面的\0,要避免这种情况发生
strncpy函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
//模拟实现strncpy
//方法一
//char* my_strncpy(char* dest, const char* src, size_t n)
//{
// char* dest_start = dest;
// while ((n > 0) && (*src != '\0'))
// {
// *dest = *src;
// dest++;
// src++;
// n--;
// }
// while (n > 0)
// {
// *dest = '\0';
// dest++;
// n--;
// }
// return dest_start;
//}
//方法二
char* my_strncpy(char* dest, const char* src, size_t count)
//count比n更有实际意义
{
assert(dest != NULL);//引用断言
assert(src != NULL);
char* start = dest;
while (count && (*dest++ = *src++) != '\0')
{
count--;
}
if (count)
{
while (count--)
{
*dest++ = '\0';
}
}
return start;
}
int main()
{
char arr1[10] = "abcdefg";
char arr2[] = "1234";
size_t len = 0;
scanf("%d", &len);
my_strncpy(arr1, arr2, len);
printf("%s", arr1);
return 0;
}
3.2 strncat
函数介绍: strncat(string concatenate with specified number of characters)
char* strncat(char* destination,const char* source,size_t num);
头文件:string.h
函数名:strncat
函数参数:
-----参数1: destination,类型:char*,被追加字符的目的地位置,即接收追加字符的起始位置
-----参数2: source,类型:char* ,追加字符的源地址,即追加字符串的开始位置。
-----参数3: num,类型size_t,追加字符的个数,用来控制追加字符的长度。函数返回类型:char* ,返回接收字符的起始位置。
函数功能:指定个数的字符串追加
重点内容
- Appends the first num characters of source to destination, plus a terminating null - character.
- lf the length of the C string in source is less than num, only the content up to the terminating null - character is copied.
- 如果追加的字符长度大于目的地空间的剩余容量,则出现越界访问,要避免这种情况发生。
使用注意思事项
- strncat在追加字符串的时候,会自动在末尾处添加字符串结束标志’\0’。(这也是我们在追加的时候,不用关注原dest, src中’\0’,仅需关注追加字符的个数的原因)
strncat函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
//方法一
//char* my_strncat(char* dest, const char* src, size_t count)
//{
// char* start = dest;
// //dest找到\0的位置
// while (*dest!='\0')
// {
// dest++;
// }
// while (count)
// {
// //将src中的字符追加给dest
// *dest = *src;
// dest++;
// src++;
// //如果src以及指向\0的位置,提前结束循环
// if (*src == '\0')
// {
// break;
// }
// count--;
// }
// *dest = '\0';//字符个数追加完毕后,再单独追加'\0'
// return start;
//}
//方法二
char* my_strncat(char* dest, const char* src, size_t count)
{
assert(dest != NULL && src != NULL);
char* start = dest;
while (*dest++)
;
dest--;
while (count--)
if ((*dest++ = *src++) == '\0')
return start;
*dest = '\0';
return start;
}
int main()
{
char arr1[15] = "12345\0xxxxxxx";
char arr2[] = "abcd";
size_t count = 0;
scanf("%d", &count);
my_strncat(arr1, arr2, count);
printf("%s", arr1);
return 0;
}
3.3 strncmp
函数介绍: strncmp(string compare with specified number of characters)
int strncmp(const char* p1,const char* p2,size_t count);
头文件:string.h
函数名:strcmp
函数参数:
-----参数1: p1,char* 类型,表示用来比较的其中一个字符串。
-----参数2: p2,char* 类型,表示用来比较的另一个字符串。
-----参数3: count,size_t类型,表示参与比较的字符个数。函数返回类型:int类型,根据比较的具体结果返回相应的数值(>0;<0;=0)
4.字符串查找
4.1 strstr
函数介绍: strstr(string search)
char* strstr(const char* str1, const char* str2);
头文件:string.h
函数名:strstr
函数参数:
-----参数1: str1,char* ,用于查找字符串的母串。
-----参数2: str2,char*,待查找字符串的子串。函数返回类型:char* ,返回查找到的地址
函数功能:查找字符串 / 找子字符串>
使用方法
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abbbcdefbcd";
char arr2[] = "bcd";
char* ret = strstr(arr1, arr2);
if (ret == NULL)
{
printf("Can not find!\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
重点内容
- 如果在str1中查找了字串str2,则返回str1中字串str2的起始地址
- 如果查找不到,返回空指针NULL
- 如果str1中含有多个str2字串内容,返回的是第一个被查找到的str2起始地址
strstr函数的模拟实现方法:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <cassert>
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 != NULL); //断言
assert(p2 != NULL);
char* s1 = NULL;
char* s2 = NULL;
char* cur = p1;
if (*p2 == '\0') //如果p2中只放了'/0',返回一个字符串
{
return (char*)p1;
}
while (*cur != '\0')
{
s1 = cur;
s2 = p2;
while ((*s2 != '\0') && (*s1 != '\0') && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur; //找到字串的情况
}
cur++;
}
return NULL; //找不到字符的情况
}
int main()
{
char* str1 = "abbbchjdfdj";
char* str2 = "bbc";
char* ret = my_strstr(str1, str2);
if (ret == NULL)
{
printf("找不到\n");
}
else
{
printf("%s", ret);
}
return 0;
}
4.2 strtok
函数介绍: strtok(string tokenize)
char* strtok (char* str, const char* sep);
头文件:string.h
函数名:strtok
函数参数:
-----参数1: str,要被分割的字符串起始位置
-----参数2: sep,被用于分割的字符集合起始位置函数返回类型:char* ,标记的位置
函数功能:字符串分割
重点内容
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
- strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
- strtok函数的第一个参数不为(NULL),函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为(NULL),函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回NULL指针。
使用方法:
int main()
{
//192.168.31.121 网络ip地址 --点分十进制
//192 168 31 121 ---strtok .
//student_zhang@whu.edu 邮箱地址
//student_zhang whu edu --- @ .
char arr[] = "student_zhang@whu.edu";
char* p = "@."; //分割的字符集合
char buf[100] = { 0 };
char* ret = 0;//用于接收分割后标记的位置
strcpy(buf, arr);//分割字符串之前先进行临时拷贝
//分割buf中的字符串
//一次只能分割一次,三段分割一共要调用三次,太挫了这种写
ret = strtok(buf, p);
printf("%s\n", ret);
ret = strtok(NULL, p);
printf("%s\n", ret);
ret = strtok(NULL, p);
printf("%s\n", ret);
//一次性打印
for (ret = strtok(buf, p); ret != NULL; ret = strtok(NULL, p))
{
printf("%s\n", ret);
}
return 0;
}
5.误信息报告
5.1 strerror
函数介绍: strerror(string error message)
char* strerror(int errnum);
头文件:string.h , errno.h
函数名:strerror
函数参数:errnum, int类型,表示错误码编号
函数返回类型:char* ,返回错误码对应的错误信息
函数功能:Get a system error message(strerror) or prints a user - supplied error
message(_strerror). 返回系统的错误信息(就是程序出错时,用这个函数返回错误的原因信息)
实际在使用的时候,错误码并非由我们来控制的,而是接收系统返回的错误信息
printf("%s\n", strerror(errno));
//errno是一个全局的错误码的变量
//当C语言的库函数在执行的过程中发生了错误,就会把对应的错误码,赋值到errno中
//errno需要引用头文件 errno.h
使用方法:
打开文件
#include<stdio.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
//当前路径下是没有test.txt文件的,所以应该会打开文件失败,错误码会储存
if (pf == NULL) //fopen函数返回指针,打开文件失败返回空指针
{
printf("%s\n", strerror(errno));//打印储存错误码对应错误
}
else
{
printf("Open file success!\n");
}
return 0;
}
5.2 perror
函数介绍:perror(print error message)
void perror(const char *s);
头文件:<string.h>, <stdio.h>
函数名:perror
函数参数:s, const char * 类型,表示一个可选的错误前缀字符串
函数返回类型:void,不返回任何值
函数功能:Print a system error message on standard error output, prefixed by the string s (if s is not NULL), and the program’s error message.
使用方法:
perror括号中的东西也会被打印出来,并加上“: ”
perror函数依然打印的时errno变量中错误码所对应的信息。
6.字符操作
6.1 字符分类
如果是,返回非零 ; 不是,返回零
函数 | 如果其参数符合下列条件就返回真 |
---|---|
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 | 任何可打印字符,包括图形字符和空白字符 |
6.2 字符转换
int tolower ( int c );转化为小写字母
int toupper ( int c );转化为大写字母
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "I AM A STUDENT ";
while (str[i])
{
if (isupper(str[i])) //判断是否是大写
{
str[i] = tolower(str[i]);//转为小写
}
i++;
}
printf("%s\n", str);
return 0;
}
7.内存操作
7.1 memcpy
函数介绍:memcpy(memory copy)
void* memcpy(void* dest, const void* src, size_t count);
头文件:string.h
函数名:memcpy
函数参数:
-----参数1:destination, 类型:char* ,表示内存拷贝的目的位置
-----参数2:source,类型:char *,表示内存拷贝的起始位置
-----参数3:count,类型:size_t,表示拷贝内存字节的个数函数返回类型: void*, 实际上就是返回destination(目的地)的起始位置
函数功能:内存拷贝
重点内容
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到’\0’的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定
memcpy函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* my_memcpy(void* dest, const char* src, size_t num)
{ //void* 可接受所有类型指针,但不能解引用操作和运算,那肯定要使用强制类型转换
void* dest_start = dest; //存储地址
assert(dest && src);
while (num--)
{
//*(char*)dest = *(char*)src;
//++(char*)dest
//++(char*)src
*((char*)dest)++ = *((char*)src)++;
}
return dest_start;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 20);//20是字节,强制类型转换为char*步长为1
return 0;
}
使用方法
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr, 20);
//arr2拷贝参数,也就是目的地
//arr是源头
//拷贝5个字符,一个字符4个字节,也就是20个字节
return 0;
}
7.2 memmove
引入
假设我们有一个整型数组 1 2 3 4 5 6 7 8 9 10 ,如果我们想要将前5个数字拷贝到第3 - 8个位置上,也就是:
如果我们通过my_memcpy可以做到吗?试验以下就知道了:
得到的结果是: 1 2 1 2 1 2 1 8 9 10,
并不是想要的: 1 2 1 2 3 4 5 8 9 10
为什么呢?
从我们刚刚模拟实现memcpy中方法中,我们知道memcpy在进行拷贝的时候,是按照从前往后的方式进行的,如果这个地方按照从前往后的方式进行拷贝,那么拷贝一开始的时候,就会出现后面需要被拷贝的数据被覆盖掉,比如说3,一开始将1放到3这个位置,3就被覆盖掉了,后面如果要拷贝3,从这个位置取出数据的时候,实际上取出的是1。
既然从前往后的拷贝方式不行,那么从后往前拷贝呢?
分析后,可以发现从后向前的拷贝方式是可以的,不会出现后面需要被拷贝的数据提前被覆盖的情况。
但是,如果我们拷贝 3 4 5 6 7 到 1 2 3 4 5的位置上,那么从前往后的拷贝方式还行得通吗?
是不是发现从后向前拷贝会出现数据提前被覆盖的情况。所以这时候我们需要进行分情况讨论:
如下:
- 如果从低地址拷贝向高地址,需要从后往前(即示例)
- 如果从高地址拷贝向低地址,需要从前往后
函数介绍:memmove(memory move)
void* memmove(void* dest, const void* src, size_t count);
头文件:string.h
函数名:memmove
函数参数:
-----参数1:destination, 类型:char* ,表示内存移动的目的位置
-----参数2:source,类型:char* ,表示内存移动的起始位置
-----参数3:count,类型:size_t,表示移动内存字节的个数函数返回类型: void*, 实际上就是返回destination(目的地)的起始位置
函数功能:内存移动
重点内容
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
memmove函数的模拟实现方法:
#include<stdio.h>
#include<assert.h>
#include<string.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
void* dest_start = dest;
assert(dest && src);
if (dest < src)
{
//从前向后拷贝
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest; //dest = (char*)dest + 1;
++(char*)src; //src = (char*)src + 1;
}
}
else
{
//从后向前拷贝
while (num--)
{
*((char*)dest + num) = *((char*)src + num);//+num字节找到最后的字节就实现从后往前拷贝
}
}
return dest_start;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memmove(arr1 + 2, arr1, 20);
return 0;
}
7.3 memcmp(简单了解)
函数介绍与重点内容
int memcmp(const void* buf1, const void* buf2, size_t count);
- 比较从ptr1和ptr2指针开始的num个字节
- 返回值如下 :
使用方法
#include<stdio.h>
#include<string.h>
int main()
{
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");
}
return 0;
}
7.4 memset(简单了解)
函数介绍与重点内容
void* memset(void* dest, int c, size_t count);
- 用:Sets buffers to a specified character.(将缓冲区设置为指定的字符)
使用方法:以字节为单位设置内存
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdefg";
memset(arr, '*', 4);
printf("%s", arr);
return 0;
}
int main()
{
int arr[] = { 1,2,3,4 };
//原来的内存:
01 00 00 00
02 00 00 00
03 00 00 00
04 00 00 00
memset(arr, 1, 9);
//修改后的内存:
01 01 01 01
01 01 01 01
01 00 00 00
04 00 00 00
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}