本文仅在博客园发布,认准原文地址:https://www.cnblogs.com/jisuanjizhishizatan/p/15577754.html
目录前言
很多时候,指针对我们写代码会有很大的帮助。例如,下面是一个函数:
#ifdef DEBUG
#define DEBUG_PRINT(arg) debug_print(arg)
#else
#define DEBUG_PRINT(arg)
#endif
void debug_print(int a[]){
for(int i=0;i<sizeof(a)/sizeof(int);i++){
cout<<a[i]<<" ";
}
}
这个函数目的是要调试输出数组a的内容,然而,这个程序一定无法正常运行,原因之前讲过,是指针参数的问题。这里也请大家自己思考一下。如果还想不出为什么来,那么就好好复习之前的内容吧。
练习
这些是对于之前指针主题的练习。如果这几道题都不会的话,就先好好复习我写的前几篇文章吧,这一章是肯定看不懂的。
1.自己编写memcpy函数,参数如下:
void memcpy(void *dest,void *src,int length);
以字节为单位,把src中的内容拷贝到dest,长度为length。
2.自己编写memcmp函数,参数如下:
void memcmp(void *ptr1,void *ptr2,int length);
以字节为单位,比较内存ptr1与ptr2的数据,长度为length。
返回值与strcmp的返回值类似。
由于指针运算的灵活性,函数的实现可以有很多种方式。本次的教程中会给出这里的一种解法,如果有更多或者更好的解法也可以在评论区指出。
strncmp函数
作用
strncmp(cmdline,"type ",5);
strncmp函数,类似于strcmp函数,用于比较字符串。但是,多了一个参数,也就是最后一个参数n,表示只比较n个字符,即使后面的字符不相同,返回值也会相同。例如:
(代码摘自《30天自制操作系统》:)
} else if (strcmp(cmdline, "cls") == 0) {
} else if (strcmp(cmdline, "dir") == 0) {
} else if (strncmp(cmdline, "type ", 5) == 0) {
for (y = 0; y < 11; y++) {
s[y] = ' ';
}
}
中间代码很长,我省略掉了。这是该书中,命令行指令的实现代码的一部分。其中的type指令,由于写法是这样的:
type 文件名
因此,只要前面5个字符"type "相同,就一定是执行type指令。
作用
上面已经举了30天自制操作系统的例子,就不多说了。
实现
strncmp函数和memcmp函数类似,都是指定长度进行内存的比较。这里就把memcmp的例子写上去吧。
int _memcmp(char *ptr1,char *ptr2,int n){
for(int i=0;i<n;i++){
if(ptr1[i]!=ptr2[i])return ptr1[i]-ptr2[i];
}
return 0;
}
strncpy函数
作用
strncpy(str1,"hello world",5);
表示只拷贝第二个参数的前5个字符,多余的字符将会被忽略。
特性
如果长度不够,将会出现一些问题。我们来做个试验:
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char s[5];
s[5]=100;
strncpy(s,"hello",5);
for(int i=0;i<6;i++){
printf("%d ",s[i]);
}
}
在一开始,我们把超出字符串长度的部分s[5]设置为100,最终我们输出字符串的每一个数值的时候,发现最终没有字符串结束符,s[5]仍然为100.这就是strncpy的特性——超出指定的长度时候,不会自动添加字符串结束符!
因此,strncpy是一个有风险的函数。
自制strncpy
strncpy函数既然有风险,那么我们也来自己实现一个strncpy函数,并且在最后自动加上'\0'结束符。
void _strncpy(char *s1,char *s2,int n){
int i=0;
for(i=0;i<n;i++){
if(s2[i]==0)return;
s1[i]=s2[i];
}
s1[i]=0;
}