C風格字串基本操作

2021-06-17 20:28:37 字數 3697 閱讀 2171

與字串相關的基本操作包括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 字串的首位...