與字串相關的基本操作包括strlen, strcpy, strcat, strcmp, strchr, strspn, strcspn, strpbrk, strstr, strtok等。在有些平台上,strcpy等使用較多的操作可能直接使用彙編**編寫,本文採用c語言來編寫這些函式,然後說說與其相關的一些內容。
strlen這個函式用於計算c風格字串的長度,而c風格字串的結束標誌是乙個null字元,通過計算起始處到結束位置的字元數量即可求得長度。起初,我以為在這裡採用末尾指標與起始指標相減的方法來計算長度,而不使用計數會提高效率,因為可以避免在每次比較後訪問記憶體兩次。然而,在我寫了一段**進行測試驗證後,我發現我錯了。反彙編後發現,後一種方法的彙編指令更短一點,自然執行時間更短。雖然訪問一次記憶體需要的時間比執行一條指令要多,但是在有著多級快取的cpu上,難以確定一次訪問記憶體跟幾條指令相當,不通過實際比較難以確定那種效率更高。可以肯定的是,使用組合語言編寫優化過的肯定效率更高。
size_t strlen(const char * str)
這個函式是strlen的擴充套件,可以通過第二個引數指定字串的最大值,這樣就能避免由於錯誤引數引起的一系列問題(可能會引起程式崩潰)。
size_t strnlen(const char *str, size_t maxlen)
return (i - str);
}
字串拷貝是乙個使用很頻繁的函式,它可以使用rep movsb指令來實現,這裡還是使用c語言來實現。值得注意的問題是源位址空間和目的位址空間有可能重疊,這樣需要分情況進行出來。
char *strcpy(char *dst, const char *src)
else
return o;
}
strncpy就像strnlen一樣,通過額外的引數指定了字串的最大長度,可以避免一些通過strcpy實施的棧溢位攻擊。
char *strncpy(char *dst, const char *src, size_t n)
else
return o;
}
這個函式是在目的字串末尾追加字元,可以轉換為strcpy操作。
char *strcat(char *dst, const char *src)
strncat也可轉換為strncpy操作。
char *strncat(char *dst, const char *src, size_t n)
strcmp返回兩個字串比較的結果,返回值是首個不同字元的差值,相同則返回0。
int strcmp(const char *str1, const char *str2)
return 0;
}
有額外引數指定最大長度的比較也是有必要的。
int strncmp(const char *str1, const char *str2, size_t n)
return 0;
}
strchr用於查詢指定字元在字串中首次出現的位置。
char *strchr(const char *str, int value)
return 0;
}
strrchr用於反向查詢指定字元首次出現的位置。
char *strrchr(const char *str, int value)
return 0;
}
strspn用於計算指定字符集中字元出現的次數,這裡採用了位圖來標記,雖然使用了32個位元組的空間,但是時間複雜度下降到了o(n+m)。
size_t strspn(const char *str1, const char *str2)
count = 0;
while (*str1)
return count;
}
類似於strspn,strcspn用於獲得指定字符集中字元首次出現的偏移。
size_t strcspn(const char *str1, const char *str2)
while (*pstr)
pstr++;
} return pstr - str1;
}
strpbrk用於獲得指定字符集中字元首次出現的位址。
char *strpbrk(const char *str1, const char *str2)
while (*pstr)
pstr++;
} return 0;
}
匹配乙個模式串有很多中方法,包括樸素演算法,rk,kmp,bm/bmg,sunday,ac等方法。這裡採用了比較簡單的演算法,首先查詢模式串首字元出現的位置,然後比較模式串,最後通過一次或多次比較得到結果。
char *strstr(const char *str1, const char *str2)
return 0;
}
strtok用於截斷字串,由於使用了乙個靜態變數,所以這個函式不是可重入的。
char *strtok(char *str, const char *delimiters)
last = strpbrk(str, delimiters);
if (last)
*last++ = '\0';
return str;
}
memset用於填充一塊記憶體區域,將目標區域中的每乙個位元組填充為指定字元,一般用於清零。
void *memset(void *dst, int value, size_t n)
memcpy用於拷貝一塊記憶體區域,跟strcpy不同,memcpy不考慮源和目的重疊的問題。
void *memcpy(void *dst, const void *src, size_t n)
memmove類似於strcpy,它不保證不修改源位址空間的資料。
void *memmove(void *dst, const void *src, size_t n)
else
return dst;
}
類似於strcmp,用於比較兩塊記憶體區域。
int memcmp(const void *str1, const void *str2, size_t n)
return 0;
}
memchr類似於strchr。
void *memchr(const void *ptr, int value, size_t n)
return i;
}
C風格字串與C 風格字串
c風格字串 對字串進行操作的 c 函式定義在標頭檔案中 1.字串定義 char result 2.字串的最後乙個字元是null字元 0 可以通過這個字元確定字串的結尾。3.strlen 返回的是字串的大小 因此,分配空間的時候,需要比字串的實際空間大1.e.g.char copystring con...
C風格字串與C 風格字串
c風格字串 對字串進行操作的 c 函式定義在標頭檔案中 1.字串定義 char result 2.字串的最後乙個字元是null字元 0 可以通過這個字元確定字串的結尾。3.strlen 返回的是字串的大小 因此,分配空間的時候,需要比字串的實際空間大1.e.g.char copystring con...
c風格字串與c風格字串陣列
include includeusing namespace std int main 輸出結果 0034ff10 0034ff10 0034ff04 013bdc80 char str abcd 先在文字常量區為 abcd 常量分配5b,接著在棧裡為指標str分配4b,並接收 abcd 字串的首位...