簡體   English   中英

C strlen()實現在一行代碼中

[英]C strlen() implementation in one line of code

昨天我在面試時被要求在C中實現strlen()而不使用任何標准函數,所有這些都是手工完成的。 作為一個絕對的業余愛好者,我用while循環實現了原始版本。 看看這個,我的面試官說它可以只用一行代碼實現。 我當時無法使用該術語生成此代碼。 在采訪之后,我問了我的同事們,他們中最有經驗的人給了我這件真的很好的作品:

size_t str_len (const char *str)
{
    return (*str) ? str_len(++str) + 1 : 0;
}

所以有一個問題,是否可以不使用遞歸,如果是,如何? 條款:

  • 沒有任何匯編程序
  • 沒有任何C函數存在於庫中
  • 而不只是拼寫一些代碼串

請注意,這不是優化或實際使用的問題,只是完成任務的可能性。

類似於@ DanielKamilKozar的答案,但是使用for循環,你可以在沒有for循環體的情況下執行此操作,並且len在函數中正確初始化:

void my_strlen(const char *str, size_t *len)
{
    for (*len = 0; str[*len]; (*len)++);
}

我能想到的最好的是這個,但它不是標准的strlen因為函數本身有不同的原型。 此外,它假設*len在開始時為零。

void my_strlen(const char *str, size_t *len)
{
        while(*(str++)) (*len)++;
}

我很好奇標准strlen如何在“一行代碼”中實現,因為它需要一個return ,這是“一行代碼”,從你發布的內容來判斷。

也就是說,我同意評論說這是一個令人難以置信的愚蠢的面試問題。

size_t str_len (const char *str)
{
    for (size_t len = 0;;++len) if (str[len]==0) return len;
}

如果這不是一個函數,這個單行可能是計算任何以null結尾的數組長度的最簡單和最短的方法(不包括變量聲明和打印):

int main() {
    const char *s = "hello world";
    int n = 0;

    while (s[++n]);

    printf ("%i\n", n);
    return 0;
}

如果它必須是一個函數,那么你不能有一個精確的函數簽名strlen(),因為返回必須在單獨的行中。 否則你可以這樣做:

void my_strlen(int* n, const char* s) {
    while (s[++(*n)]);
}

int main() {
    const char *s = "hello world";
    int n = 0;

    my_strlen(&n, s);

    printf ("%i\n", n);
    return 0;
}

這似乎工作正常。

unsigned short strlen4(char *str)
{
    for (int i = 0; ; i++) if (str[i] == '\0') return i;
}

有什么想法嗎?

UPDATE!

這可能是實現strlen的最有效方法。 大多數編譯器使用以某種方式實現的編譯器。

這可能有點難以理解,特別是如果沒有學習指針。

size_t strlen(char *str)
{
    register const char *s;
    for (s = str; *s; ++s);
    return(s - str);
}

那個空的for循環怎么樣? 喜歡

int i=0;
for(; str[i]!=0; ++i);
size_t strlen (const char* str) {
    for (const char* s1 = str; ; s1++) if (!(*s1)) return s1 - str; 
}

與str [i]相比,增加指針的上述代碼將表現更好,因為索引str [i]將評估為:*(str + i)這是對每個循環完成的加法運算,而增量運算更快。

此外,與strlen(const char * str,size_t * len)相比,不需要調用者提供的額外參數。

最后,根據原始請求,它在一行上。

與其他人所說的相反,如果遵循一些合理的限制是不可能的 限制是:

  • 函數體中的一個非空語句聲明(具有非空體的復合語句總共至少有兩個語句)
  • 與真正的strlen相同的簽名
  • 沒有遞歸

具有strlen簽名的任何函數都必須具有return語句。 return語句由return關鍵字和表達式組成。 C語言沒有執行循環的表達式。 需要一個聲明,但這個位置是為return語句保留的。

如果放松這些限制(例如,更改簽名,或者不計算復合語句的返回語句和/或聲明和/或正文,只要它們是“簡單”,作為單獨的“行”),任務就變得可能,相當簡單,正如在這里和整個互聯網上的許多例子中都可以看到的那樣

本地代碼

unsigned int strlen(const char *s)
{
    int l;for(l=0;s[l]!='\0';l++);return l;
}

您可以將'\\ 0'替換為零,但我更喜歡它

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM