[英]C: Custom strlen() library function
我創建了我的strlen()
函數版本。
unsigned int my_strlen(char *p)
{
unsigned int i = 0;
while(*p!='\0')
{
i++;
p++;
}
return i;
}
每次運行時它都會給我正確的輸出。但是我的同事說這段代碼可能會導致字符長度大於1 byte
系統出現問題。 是這樣嗎??
所以他們修改了代碼如下:
unsigned int my_strlen(char *p)
{
unsigned int i = 0;
char *start = p;
while(*p!='\0')
{
i++;
p++;
}
return p - start;
}
我一直認為在 C 中一個字符是 1 個字節長。
前一個片段比后者好還是反之亦然??
在 C 中保證sizeof(char)
為 1,所以你是對的。
為了增加一些真實性,直接引用C11
,章節 §6.5.3.4, sizeof
和_Alignof
運算符
當
sizeof
應用於具有char
、unsigned char
或signed char
類型(或其限定版本)的操作數時,結果為 1。 [....]
也就是說,指針算術尊重數據類型,所以無論如何,第二種方法在預期做什么方面沒有任何意義。 在這兩種情況下,您都在p
操作,即char*
,因此效果是相同的。
當您使用p++
,您將指針增加sizeof(char)
。 因此,即使sizeof(char)
在不同機器之間是可變的,它也無關緊要。 你的同事錯了。
注意:如果你想計算字節數,而不是字符數,那么你的同事可能是正確的(如果不能保證 char 是 1 個字節,但它確實是)。 如果你要數字,那你的同事根本就錯了。
盡管其他人回答了您有關字符大小的問題,但您的版本仍然不正確。
當前的標准 (ISO/IEC 9899:2011) 在這里簡短而准確:
7.24.6.3
strlen
函數概要
#include <string.h>`<br> size_t strlen(const char *s);
說明
2
strlen
函數計算 s 指向的字符串的長度。退貨
3
strlen
函數返回終止空字符之前的字符數。
所以一個完全兼容的函數將是
size_t stringlength(const char *s){
size_t i = 0;
while(s && *s != '\0'){
s++;
i++;
}
return i;
}
主要區別在於它檢查輸入(可能是NULL
,但例如:glibc 的strlen
segfaults。如果您希望它進行 segfault,請在循環中去除s == NULL
的測試。Segfaulting 可能是更好的選擇,否則您會得到那種我們喜歡稱之為“Heisenbugs”的錯誤。當你查看它們並且它們的波形崩潰時往往會消失的錯誤)並使用size_t
作為輸出。
Glibc 版本在可能的情況下一次處理多個字節——不知道這樣的優化是否有用。
如果你想要等效的wsclen()
你可以做這樣的事情:
#include <wchar.h>
size_t wstringlength(const wchar_t *s){
size_t i = 0;
while(s[i] != L'\0'){
i++;
}
return i;
}
計算多字節字符( mbrlen()
檢查一個字符,但您可以使用mbrtowc()
)非常復雜,超出了這篇短文的范圍。
OP 發布了“字符長度大於 1 個字節”,而不是char
。 當將字符限制為僅char
、 signed char
、 unsigned char
時,OP 是正確的。 這 3 個總是大小為 1。
OP 的同事可能並非都以這種限制性的方式思考。 C 規范有許多字符類型:單字節字符、多字節字符、擴展字符、寬字符,並非都是 1 字節。
修改后的代碼有弱點。 它與“字符長度大於 1 個字節”無關。 另外, i++;
毫無意義。 unsigned
的返回類型可能不夠。 將size_t
用於既不太寬也不太窄的無符號類型。
// simplify
size_t my_strlen2(const char *p) {
const char *start = p;
while(*p) p++;
return (size_t) (p - start);
}
前一個片段比后者好還是反之亦然??
兩者都不返回不會溢出的類型。
使用for
strlen
函數:
size_t my_strlen(const char *s) {
size_t n;
for (n = 0; *s; s++)
n++;
return n;
}
或者:
size_t n;
for (n = 0; *s != '\0'; s++)
n++;
return n;
或者:
size_t n;
for (n = 0; *(s++); )
n++;
return n;
或者:
size_t n;
for (n = 0; *s; n++)
s++;
return n;
或者:
size_t n = 0;
int i;
for (i = 0; s[i]; i++)
n++;
return n;
在指針算術方面,只要您處理指針和指針算術始終堅持數據類型,它就不會在具有 char 為 2 個字節的平台上給您不同的結果。 這是另一種查找字符串 len 的方法,它不使用指針 airthmetic-
int len = -1;
while(p[++len] != '\0');
return len;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.