目录
预备知识
在关于本文章开始之间我们要先了解一下什么是assert和const以及size_t 另外,本文章介绍的函数都要用到<string.h>
assert:
在C语言中,assert(断言)是一个宏,用于检查特定的条件是否为真。如果条件不为真,则会触发一个断言失败的错误,程序将停止运行。assert的原型为:
void assert(int expression);
其中,expression是一个需要检查的条件表达式,通常为布尔类型的表达式。如果expression为真,assert什么也不做,程序继续执行;如果expression为假,则会输出一条错误信息,并停止程序执行。
举个例子,下面的代码使用assert来确保一个函数参数不为空指针:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void foo(int* ptr){
assert(ptr != NULL);
// do something with ptr
}
int main(){
int* ptr = NULL;
foo(ptr);
return 0;
}
在这个例子中,当指针ptr为NULL时,assert会检查到它的值为假,程序将会输出错误信息并停止执行。
const:
const是C语言中的关键字,用来定义一个常量。它可以用在变量或函数返回值类型前,表示该变量或函数返回值是一个常量。这意味着变量值不能被修改,函数返回值不能被修改。一旦定义为常量,变量的值就不能再被修改,这有助于程序的可维护性和可读性。
例如,以下代码定义了一个整数常量:
const int a = 10;
这意味着a的值不能被修改。如果尝试修改它的值,编译器将会报错。
const也可以用于函数参数,表示该参数是一个常量,其值不能被修改。例如:
void printNum(const int num) {
//...
}
这个函数接受一个整数参数num,但由于num是一个常量,函数内部不能修改它的值。
总之,const是C语言中用于定义常量的关键字,可以应用于变量、函数和函数参数等地方。
size_t:
size_t是C语言中的一种数据类型,它被定义为unsigned int或unsigned long
从vs编译器中转到定义就可以看到
长度不受限制的字符串函数
strcpy
strcpy的介绍以及使用
strcpy的介绍
将source指向的 C 字符串复制到destination指向的数组中,包括终止 null 字符'\0'(并在该点处停止)。
为避免溢出,目标指向的数组的大小应足够长,以包含与source相同的 C 字符串(包括终止 null 字符),并且不应在内存中与source重叠。
返回值是destination所指向的首元素地址。
strcpy的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "what";
char arr2[20] = "hello world!";
printf("使用strcpy前%s\n",arr2);
strcpy(arr2, arr1); //将arr1拷贝到arr2
printf("使用strcpy后%s", arr2);
return 0;
}
实现效果
监视窗口情况
使用strcpy前
使用strcpy后
图解
strcpy的模拟
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest,const char* str) //用const 保护 str所指向的对象不被修改
{
char* ret = dest; //先获取dest所指向的首元素地址,用于后面的返回值
assert(dest && str); //断言,当dest或str是空指针时发出错误
while (*str != '\0')
{
*dest = *str;
dest++;
str++;
}
*dest = *str; //将最后的str所指向的'\0'赋值给*dest
return ret;
}
int main()
{
char arr1[20] = "what";
char arr2[20] = "hello world!";
printf("使用strcpy前%s\n",arr2);
my_strcpy(arr2, arr1); //将arr2拷贝到arr1
printf("使用strcpy后%s", arr2);
return 0;
}
strcat
strcat的介绍以及使用
strcat的介绍
将source字符串的副本追加到destination字符串。destination 中的终止 null 字符('\0')被 source 的第一个字符覆盖,并且 null 字符('\0')包含在由 destination 中两者的串联形成的新字符串的末尾。
destination 和 source 的来源不能重叠
返回值是destination所指向的首元素地址。
strcat的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello ";
char arr2[20] = "world!";
printf("连接前%s\n", arr1);
strcat(arr1, arr2); //连接两个字符串
printf("连接后%s", arr1);
return 0;
}
实现效果
如果要实现相同的效果也可以这样写
这样写不用多定义一个字符数组arr2
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello ";
printf("连接前%s\n", arr1);
strcat(arr1, "world!"); //连接两个字符串
printf("连接后%s", arr1);
return 0;
}
监视窗口情况
图解
strcat的模拟
由strcat的介绍可知,strcat的返回值是destination所指向的首元素地址。
所以返回类型是char*
#include<assert.h>
#include<stdio.h>
char* my_strcat(char* dest, const char* str)
{
assert(dest && str); //断言,当dest或str是空指针时发出错误
char* ret = dest; //获取dest所指向的首元素地址,此地址为函数返回的地址
while (*dest != '\0') //使dest指针变量指向'\0'
{
dest++;
}
while (*str != '\0') //这部分与strcpy类似
{
*dest = *str;
dest++;
str++;
}
*dest = *str;
return ret;
}
int main()
{
char arr1[20] = "hello ";
char arr2[20] = "world!";
my_strcat(arr1, arr2);
printf("%s", arr1);
return 0;
}
strcmp
strcmp的介绍以及使用
strcmp的介绍
将指针str1所指向的字符串与str2所指向的字符串进行比较 (比较的是两个字符的ASCII码值)
从第一个字符开始比较,如果比较的两个字符ASCII码值相等则比较接下来的两个字符的ASCII码值,直到两个字符的ASCII码值不同或者其中一个指针指向了'\0'
strcmp的返回值
如果str1指针变量指向字符的ASCII码值小于str2指针变量指向字符的ASCII码值,返回小于0的数
如果两个字符串的内容相等,返回0
如果str1指针变量指向字符的ASCII码值大于str2指针变量指向字符的ASCII码值,返回大于0的数
strcmp的使用
#include<string.h>
#include<stdio.h>
int main()
{
char arr1[20] = "hello world";
char arr2[20] = "no";
int ret = strcmp(arr1, arr2); 用ret 接收strcmp的返回值
if (ret > 0)
{
printf(">");
}
else if (ret == 0)
{
printf("==");
}
else
{
printf("<");
}
return 0;
}
运行结果
图文解析
很显然指针变量str1与指针变量str2指向字符的ASCII码值不相等,而且str2指针变量指向'n'的
ASCII码值大于str1指针变量指向'h'的ASCII码值,所以函数返回小于0的值
strcmp的模拟
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2) //用const保护*str1和*str2的值
{
assert(str1 && str2); //断言,如果str1或str2是空指针就会报错
while ((*str1 == *str2) && (*str1 != '\0'))
{
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[20] = "hello world";
char arr2[20] = "no";
int ret = strcmp(arr1, arr2);
if (ret > 0)
{
printf(">");
}
else if (ret == 0)
{
printf("==");
}
else
{
printf("<");
}
return 0;
}
长度受限制的字符串函数
strncpy
strncpy的介绍以及使用
strncpy的介绍
将source的前 num 个字符复制到destination。
返回值是字符串起始位置的地址
图文解析:如果在复制 num个字符之前找到source C 字符串的末尾(由 null 字符('\0')表示),则
字符串长度之后的字符填充用'\0',直到总共有 num 个字符被写入它。
strncpy的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[40] = "xxxxxxxxxxxxxxxxxxxxxxx";
char arr2[40] = "hello world!";
printf("使用前%s\n", arr1);
strncpy(arr1, arr2, 16);
printf("使用后%s", arr1);
return 0;
}
运行结果如下
监视窗口情况
strncpy的模拟
#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest,const char* str, size_t num) //用const保护str指针变量指向的字符
{
char* ret = dest; //用ret指针变量记录目标字符串起始位置
assert(dest && str); //断言,如果dest或str是空指针就会报错
while (num && *str != '\0')
{
*dest = *str;
dest++;
str++;
num--;
}
if (num) //当num大于字符串的长度就会出现这种情况
{
while (num)
{
*dest = '\0';
dest++;
num--;
}
}
return ret;
}
int main()
{
char arr1[40] = "xxxxxxxxxxxxxxxxxxxxxxx";
char arr2[40] = "hello world!";
printf("使用前%s\n", arr1);
my_strncpy(arr1, arr2, 16);
printf("使用后%s", arr2);
return 0;
}
strncat
strncat的介绍以及使用
strncat的介绍
附加字符串数组到目标字符串,但加以限制
每次附加字符串的时候都会往结尾加个\0
如果num的长度大于source指针变量所指向字符串的长度,在最后的字符串末尾还是会只加一个\0
返回值是字符串起始位置的地址
strncat的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[40] = "hello ";
char arr2[40] = "world!";
printf("使用前%s\n", arr1);
strncat(arr1, arr2,3);
printf("使用后%s", arr1);
return 0;
}
运行结果如下
监视窗口情况
图解
strncat的模拟
#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest,const char* str,size_t num) //用const保护str指针变量指向的字符
{
char* ret = dest; //用ret指针变量记录目标字符串起始位置
assert(dest && str); //断言,如果dest或str是空指针就会报错
while (*dest != '\0') //使dest指针变量指向'\0'
{
dest++;
}
while (num && *str != '\0')
{
*dest = *str;
dest++;
str++;
num--;
}
*dest = '\0'; //当num为0后或者str指针变量指向的字符为'\0'停止后加上\0
return ret;
}
int main()
{
char arr1[40] = "hello ";
char arr2[40] = "world!";
printf("使用前%s\n", arr1);
my_strncat(arr1, arr2,3);
printf("使用后%s", arr1);
return 0;
}
strncmp
strncmp的介绍以及使用
strncmp的介绍
将str1指针变量所指向的字符与str2指针变量所指向的字符的ASCII码值进行比较,具体原理与strcmp一样,只是在strcmp的基础上加上了num来限制
返回值 int类型
strncmp的使用
#include<string.h>
#include<stdio.h>
int main()
{
char arr1[40] = "xxllo ";
char arr2[40] = "xxxld!";
int ret = strncmp(arr1, arr2, 2); //此时num为2
printf("%d", ret);
return 0;
}
在vs中的运行结果为
如果将num的2改为3
int ret = strncmp(arr1, arr2, 2) ---> int ret = strncmp(arr1, arr2, 3);
在vs中的运行结果就会变为
接下来看看监视是怎样的情况
显然字符'x'的ASCII码值会大于'l',所以最后返回值为小于0的值
strncmp的模拟
#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* str1,const char* str2, size_t num)
//用const保护str1指针变量和str2指针变量所指向的字符
{
assert(str1 && str2); //断言,如果dest或str是空指针就会报错
if (num == 0)
{
return 0;
}
while (--num && *str1 == *str2 && *str1 != '\0')
{
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[40] = "xxllo ";
char arr2[40] = "xxxld!";
int ret = my_strncmp(arr1, arr2,3 );
printf("%d", ret);
return 0;
}
最后
本文的此截图来自cplusplus.com