我最近一直在學習 C,我遇到了一個 strlen 的源代碼,這讓我很困惑,我不得不在其他地方查找它,但還不能真正理解它。
力量:
#include <stdio.h>
int strlen(const char *str)
{
const char* eos = str; // 1
while (*eos ); // 2
return (eos - str - 1); // 3
}
int main()
{
int len = strlen("Hello");
printf("Len: %d" , len);
return 0;
}
我不明白為什么我們使用區域變數 eos 以及為什么我們在一個空的 while 回圈中使用它然后從 strlen 函式回傳最后一行?
uj5u.com熱心網友回復:
為什么有一個空的 while 回圈? 回圈遞增,eos直到它指向空終止符之后的位置。該運算式*eos 是一種非常緊湊的方式,它告訴您的計算機獲取eos當前指向的字符值,然后遞增eos使其指向下一個字符。在這個 while 回圈中不需要主體。
為什么要使用區域變數? 由于我們遞增指標(即eos),我們還需要在最終的計算(即一個指向字串的開頭str),我們不能簡單地用str一切。我們至少需要一個其他變數來完成作業。
最后一行是如何作業的? 該運算式eos - str執行指標減法,因此它計算這兩個指標之間的距離并將其作為整數回傳。然后我們減去 1 使答案正確。
uj5u.com熱心網友回復:
指標eos用于沿字串前進。EOS 是字串結尾的縮寫。在while因為推進指標是所有需要的-因為不需要做任何事情回圈是空的。一旦eos指向空終止符,回圈就退出。函式的最后一行然后從開始指標中減去結束指標,給出eos移動過去的字符數。最后一個-1是為了糾正這一事實,多虧了后增量運算子,eos它總是比應有的多一個字符。
一個不那么令人困惑的實作是:
int strlen(const char *str)
{
const char* eos = str; // 1
while (*eos)eos ; // 2
return (eos - str); // 3
}
uj5u.com熱心網友回復:
對于初學者來說,函式回傳型別應該是size_t.
size_t strlen(const char *str);
如果兩個指標指向同一陣列的元素,則指向具有較高索引的元素的指標與指向具有較低索引的元素的指標之間的差異產生兩個索引之間的元素數。
例如,如果你有一個像
const char s[] = "12";
和兩個指標
const char *p1 = &s[0];
const char *p2 = &s[1];
那么區別
p2 - p1
產生值1。
原始函式中的 this 指標
const char* eos = str;
將在傳遞的字串中移動,直到找到終止的零字符。
while (*eos );
這個回圈可以像這樣重寫
while ( *eos != '\0' );
后綴運算式*esp 的值是指標遞增前所指字符的值。
因此,當找到終止零時,指標eos將指向終止零字符之后的記憶體,并且回圈停止其迭代。
因此,現在指標 str指向傳遞的字串的開頭,指標eos指向終止零字符之后的記憶體'\0'。
所以區別
(eos - str - 1)
給出傳遞的字串中終止零字符之前的字符數'\0'。
uj5u.com熱心網友回復:
中的字串是由所謂的空字符終止的字符陣列;還要記住,因為 C 中沒有顯式的字串型別,所以如果要對作為字串處理的字符陣列進行操作,則需要有一個指向第一個字符的指標。
話雖如此,eos變數被初始化為指向字串的開頭(通過將它等同于str- 請記住,它們都只是指向字符的指標,因此將它們等同意味著它們指向同一事物)。
現在,“空”while 回圈有副作用。因為 increment ( ) 運算子用于求值條件中,所以eos會遞增 - 并且因為它是一個指標,這意味著在回圈的每次迭代中,都eos指向連續的字符。它基本上是沿著字串“行走”。
這一直持續到回圈條件評估為false。而在 C 中,只有空字符的計算結果為假(對于所有可能的字符值;更一般地,零為假,非零為真)。所以基本上,eos 將在字串的末尾停止遞增。
現在到return宣告。此時我們有兩個變數 - 一個稱為str仍然指向字串開頭的變數,另一個稱為指向字串結尾的變數eos。嗯 - 實際上eos已經溢位,因為在回圈條件中完成了遞增。在這里準確地說,它指向字串末尾空字符后面的記憶體地址。
因此,多一點指標運算,如果我們減去str從eos再減去1的溢位......好吧,我們得在最后和第一字符,這是字串長度的地址的差異。
奇怪的是在回圈中使用了后增量運算子。如果它已被編碼為while (* eos);,即使用預增量運算子,那么增量將在評估之前發生,eos這意味著它不會溢位到字串的末尾之外,并且不需要減去額外的 1 in該return宣告。那好吧。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/357609.html
下一篇:計算范圍內的值時的舍入誤差
