本文僅在部落格園釋出,認準原文地址: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;
}