[英]Can't understand small part of strcmp function
我正在用C讀一本書,看過這兩個strcmp
算法。
我已經學會了自我,usel for循環是如何工作的。
但是這兩個for循環對我來說是新的。 我不明白這些部分
for (i = 0; s[i] == t[i]; i++)
沒有長度,而是具有s[i] == t[i]
。
for ( ; *s == *t; s++, t++)
是什么意思;
。
我了解其他部分,我也知道這些函數返回的內容。
/* strcmp: return <0 if s<t, 0 if s==t, >0 if s>t */
int strcmp(char *s, char *t)
{
int i;
for (i = 0; s[i] == t[i]; i++)
if (s[i] == '\0')
return 0;
return s[i] - t[i];
}
int strcmp(char *s, char *t)
{
for ( ; *s == *t; s++, t++)
if (*s == '\0')
return 0;
return *s - *t;
}
首先,一些基本知識。
for
循環的語法是
for ( expr1opt ; expr2opt ; expr3opt ) statement
expr1
, expr2
和expr3
都是可選的。 該聲明
for ( ; ; ) { // do something }
將“永遠”循環,除非循環主體中某處有break
或return
語句。
expr1
(如果存在)在循環執行之前被精確評估一次-它用於建立某種初始狀態(例如將索引設置為0或分配指針值等)。
如果存在expr2
,則在循環主體的每次迭代之前對其進行評估。 這是繼續執行循環的測試條件。 如果表達式的計算結果為非零值,則執行循環體;否則,執行循環體。 否則,循環退出。 如果缺少expr2
,則假定其值為1( true
)。
如果存在expr3
,則在循環主體的每次迭代之后對其進行評估。 它通常會更新expr2
正在測試的內容。
for (i = 0; s[i] == t[i]; i++)
沒有長度,而是有s[i] == t[i]
只要s[i] == t[i]
,該循環就會執行; 當t[i]
不等於s[i]
,循環將退出。 就其本身而言,這意味着如果您具有相同的字符串,則循環將在字符串的末尾運行-如果s
和t
都包含"foo"
,則循環將以
s[0] == t[0] == 'f'
s[1] == t[1] == 'o'
s[2] == t[2] == 'o'
s[3] == t[3] == 0
s[4] == t[4] // danger, past the end of the string
因此,在循環體內,代碼還將檢查a[i]
是否為0-如果是,則意味着我們已經將所有內容匹配到0終止符,並且字符串是相同的。
所以基本上
s[0] == t[0] == 'f', s[0] != 0, keep going
s[1] == t[1] == 'o', s[1] != 0, keep going
s[2] == t[2] == 'o', s[2] != 0, keep going
s[3] == t[3] == 0, s[3] == 0, at end of s, strings match
for(; * s == * t; s ++,t ++)
的功能與第一個循環完全相同,但是它沒有使用[]
運算符來索引s
和t
,而是使用了指針。 由於無需初始化,因此第一個表達式為空。
在第一種情況下, for
語句之后的代碼將檢查是否已找到字符串結尾標記,如果是,則該函數返回0。
在第二種情況下for
說法,的初始化部分for
語句中不填寫,這樣的聲明開頭for( ;
這是完全合法的。
祝你好運。
For循環分為3部分-初始化,條件和循環表達式。 所有這些都是可選的。
所以這個循環
for (i = 0; s[i] == t[i]; i++)
一直運行到字符s[i]
等於t[i]
為止。 所以這是條件。 如果為假,則循環中斷。
條件不一定總是基於長度。
還有這個 -
for ( ; *s == *t; s++, t++)
正如我們在上面看到的, 初始化是可選的,在這里不存在,這是非常好的。 此循環中的條件也相同, 即循環直到字符相等。
for(i = 0; s [i] == t [i]; i ++)//沒有長度
實際上,此代碼有點危險,因為它假定傳遞的字符串以NULL終止(但稍后再讀)。 循環僅在字符串的左半部分相等時才繼續進行,因此,在循環內,當遇到NULL時,唯一可能返回的結果是0(等於)(for(;;)條件可確保兩個字符串都在同一位置具有NULL)。
關於長度,要計算長度,您還是應該掃描整個字符串……並兩次(因為有兩個字符串)。 相反,此循環將所有內容合而為一。 此外,C中的字符串必須以NULL終止。 絕對沒有其他方法可以進行此比較!
for(; * s == * t; s ++,t ++)//這是什么意思
這與前一個大約相同,但是它們不是使用索引來對s和t取消引用(並且無需觸摸它們),而是對其進行了修改以依次指向各個字符。 我相信這會更快,但要取決於編譯器。 此外,將s和t遞增會使您失去字符串的開頭。 但是使用此功能不是問題。
關於for(;;)
的語法,已經有注釋解釋了為什么這樣寫。 for()的最后一部分,位於分號和右括號之間,在每次迭代后執行。 在這種情況下,我們需要增加兩個變量,因此有兩個語句用逗號分隔。
沒有長度。 for
循環將一直運行直到條件為真,因此在這種情況下,它將一直運行直到s[i]
不等於t[i]
為止。
for ( ; *s == *t; s++, t++)
;
這意味着省略了for
循環的第一子句。 由於bot s
和t
在for
循環之外定義,因此無需在此處定義它們。
C標准允許:
for(第1條; expression-2; expression-3)語句
(......)
子句1和表達式3都可以省略。 省略的expression-2替換為非零常量。
當將已定義的變量放在第一個子句中時,某些編譯器(例如clang
產生警告。 例如此代碼:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i = 0;
for (i; i < 10; i++)
puts("Hi");
return EXIT_SUCCESS;
}
用clang
編譯會產生警告:
main.c:7:8: warning: expression result unused [-Wunused-value]
for (i; i < 10; i++)
^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.