当前位置:网站首页>C语言:字符串函数与内存函数
C语言:字符串函数与内存函数
2022-07-27 14:27:00 【发发是只呆头鹅】
一、字符串函数
1.strlen
该函数用于求字符串长度,有人会问了,一个简简单单的求字符串长度的函数也需要讲吗?我们先来看一个普通的求字符串长度的例子:
int main() {
char str[] = "abcd";
printf("%d\n", strlen(str));
return 0;
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvHeRx00-1631778222741)(C:\Users\10371\Desktop\QQ截图20210916145831.png)]](/img/7a/b34681242700cf12bc97dd28f661de.png)
如我们所愿,结果为4.我们再看下面这个例子:
int main() {
char str1[] = "abcdef";
char str2[] = "sss";
if (strlen(str2) - strlen(str1) > 0) {
//strlen的返回值是 size_t类型的
printf("str2 > str1\n");
} else {
printf("str1 > str2\n");
} return 0;
}

结果居然是 str2>str1,这是怎么回事呢?我们去查一下该函数就有了新发现,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ilMwMRsV-1631778222745)(C:\Users\10371\AppData\Roaming\Typora\typora-user-images\image-20210916150235949.png)]](/img/4c/23476cc0718de3e7c9e552356be045.png)
函数返回值类型是size_t,是一个无符号整型,其实这也很符合逻辑,因为字符串长度不会出现负数的,但是如果将两个字符串长度进行相减时可能会出现负数,负数转换成无符号类型就会是一个很大的正数,所以这里的结果就是str2>str1,这段代码告诉了我们在使用库函数时,一定要注意函数的返回值类型,要不然很可能就会出错,并且还很难发现。
2.strcpy
该函数用于字符串的拷贝,将源字符串拷贝到目的字符串,该函数的使用应该注意以下几点:
- 源字符串必须以 ‘\0’ 结束。
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
我们来尝试自己模拟实现strcpy函数,代码如下:
char* my_strcpy(char* str1,const char* str2) {
assert(str1 && str2);
char* ret = str1;
while (*str1++ = *str2++) {
;
}
return ret;
}
int main() {
char str1[] = "********";
char str2[] = "abc";
my_strcpy(str1, str2);
printf("%s\n", str1);
return 0;
}
其实就是一个按序拷贝的过程,要注意其返回类型为char*。
3.strcat
该函数为字符串追加函数,即在一个字符串后面追加另外一个字符串,使用该函数前同样要注意以下几点:![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2zHNNL5x-1631778222748)(C:\Users\10371\AppData\Roaming\Typora\typora-user-images\image-20210916153207820.png)]](/img/85/5c4c1a7893faa3572a37e2c7b959e4.png)
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
我们来尝试自己模拟实现strcat函数,代码如下:
char* my_strcat(char* str1,const char* str2) {
assert(str1 && str2);
char* ret = str1;
while (*str1) {
str1++;
}
while (*str1++ = *str2++) {
;
}
return ret;
}
int main() {
char str1[20] = "abc";
char str2[] = "def";
my_strcat(str1, str2);
printf("%s\n", str1);
return 0;
}
实现思路就是先找到一个串的‘\0’处,然后从这里开始拷贝另外一个串。对于源字符串必须以‘\0’结尾这一点,如果我们不已’\0’结尾会怎么样呢?
char str2[] = {'d','e','f'};
若将str2改成这样的话,,结果如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33T0tj7H-1631778222749)(C:\Users\10371\AppData\Roaming\Typora\typora-user-images\image-20210916152447333.png)]](/img/1a/fbf122a3f35368f114a7d1ffa50ddc.png)
显然会发生错误,因为改成这样后不知道何时能找到’\0’,于是就会一直拷贝,也可能会出现溢出的现象,所以我们在使用这些函数之前,一定要合理。
字符串函数还有很多,例如:strcmp、strstr等等,还有长度受限制的字符串函数,大家感兴趣的可以自己去研究。
二、内存操作函数
1.memcpy
该函数为内存拷贝函数,上面提到的strcat,strcpy都是争对字符串的,如果我们想拷贝其他类型的数据时,就可以用到memcpy这个函数了。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HbiJj5is-1631778222749)(C:\Users\10371\AppData\Roaming\Typora\typora-user-images\image-20210916153424991.png)]](/img/e7/b177da7ac31170933ac7bbd5168c5d.png)
该函数的模拟实现如下:
void* my_memcpy(void* arr1,const void* arr2,size_t count) {
assert(arr1 && arr2);
void* ret = arr1;
while (count--) {
*(char*)arr1 = *(char*)arr2;
arr1 = (char*)arr1 + 1;
arr2 = (char*)arr2 + 1;
}
return ret;
}
int main() {
int arr1[10] = { 0 };
int arr2[5] = { 1,2,3,4,5 };
my_memcpy(arr1, arr2, sizeof(arr2[0]) * 5);
for (int i = 0; i < 5; i++)
printf("%d ", arr1[i]);
return 0;
}
该函数不能实现重叠拷贝,什么意思呢?例如在一个数组中,存放1到10这10个数字,如果我们想把1,2,3,4,5从第三个元素开始一次向后拷贝,即最终结果应该为1,2,1,2,3,4,5,8,9,10,但是上面的模拟函数并并不能实现该功能,因为会出现覆盖的现象,对于这种覆盖的现象我们该怎么解决呢?
就拿这个例子来说,如果我们从后向前拷贝是不是就不会出现重叠的现象,经过分析我们会发现,当目的地址在源地址前面时,我们可以从前向后拷贝,当目的地址在源地址后面时,我们需要从后向前拷贝。
C语言中自带的memmove函数正好能满足该功能,它是升级版的memcpy,当需要重叠拷贝时,它也能很好的胜任,其模拟实现如下:
void* my_memmove(void* dest,const void* src, size_t count) {
assert(dest && src);
void* ret = dest;
if (dest < src) {
while (count--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else {
while (count--) {
*((char*)dest + count) = *((char*)src + count);
}
}
return dest;
}
int main() {
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+2, arr1, sizeof(int)*5);
for (int i = 0; i < 10; i++)
printf("%d ", arr1[i]);
return 0;
}
我们一定要分情况进行讨论,要不然可能就会出错,从前向后拷贝和从后向前拷贝我们都应该考虑到。
边栏推荐
- 修改 Spark 支持远程访问OSS文件
- Method of removing top navigation bar in Huawei Hongmeng simulator
- Sword finger offer merges two sorted linked lists
- Spark TroubleShooting整理
- $router.back(-1)
- QT (XIII) qchart drawing line chart
- Leetcode 74. search two-dimensional matrix bisection /medium
- Network equipment hard core technology insider router Chapter 10 Cisco asr9900 disassembly (III)
- Huayun data creates a perfect information technology and innovation talent training system to help the high-quality development of information technology and innovation industry
- Network equipment hard core technology insider router Chapter 4 Jia Baoyu sleepwalking in Taixu Fantasy (Part 2)
猜你喜欢

STL value string learning

Unity performance optimization ----- occlusion culling of rendering optimization (GPU)

Spark 3.0 DPP实现逻辑

How to take satisfactory photos / videos from hololens

QT (five) meta object properties

Record record record

With just two modifications, apple gave styleganv2 3D generation capabilities

Dan bin Investment Summit: on the importance of asset management!

Singles cup, web:web check in

MLX90640 红外热成像仪测温传感器模块开发笔记(七)
随机推荐
Transactions_ Basic demonstrations and transactions_ Default auto submit & manual submit
Huayun data creates a perfect information technology and innovation talent training system to help the high-quality development of information technology and innovation industry
Deveco studio2.1 operation item error
C language: factorial recursive implementation of numbers
Network equipment hard core technology insider router Chapter 5 tompkinson roaming the network world (Part 1)
【剑指offer】面试题49:丑数
Google team launches new transformer to optimize panoramic segmentation scheme CVPR 2022
【剑指offer】面试题51:数组中的逆序对——归并排序
Adaptation verification new occupation is coming! Huayun data participated in the preparation of the national vocational skill standard for information system adaptation verifiers
Some binary bit operations
js使用for in和for of来简化普通for循环
Unity3d learning note 10 - texture array
Leetcode 74. search two-dimensional matrix bisection /medium
使用Lombok导致打印的tostring中缺少父类的属性
MLX90640 红外热成像仪测温传感器模块开发笔记(七)
Hyperlink parsing in MD: parsing `this$ Set() `, ` $` should be preceded by a space or escape character`\`
[0 basic operations research] [super detail] column generation
【剑指offer】面试题41:数据流中的中位数——大、小堆实现
Spark 3.0 Adaptive Execution 代码实现及数据倾斜优化
STL value string learning