簡體   English   中英

無法理解strcmp函數的一小部分

[英]Can't understand small part of strcmp function

我正在用C讀一本書,看過這兩個strcmp算法。

我已經學會了自我,usel for循環是如何工作的。

但是這兩個for循環對我來說是新的。 我不明白這些部分

  1. for (i = 0; s[i] == t[i]; i++)沒有長度,而是具有s[i] == t[i]

  2. 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

expr1expr2expr3都是可選的。 該聲明

for ( ; ; ) { // do something }

將“永遠”循環,除非循環主體中某處有breakreturn語句。

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] ,循環將退出。 就其本身而言,這意味着如果您具有相同的字符串,則循環將在字符串的末尾運行-如果st都包含"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 ++)

的功能與第一個循環完全相同,但是它沒有使用[]運算符來索引st ,而是使用了指針。 由於無需初始化,因此第一個表達式為空。

在第一種情況下, 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()的最后一部分,位於分號和右括號之間,在每次迭代后執行。 在這種情況下,我們需要增加兩個變量,因此有兩個語句用逗號分隔。

  1. 沒有長度。 for循環將一直運行直到條件為真,因此在這種情況下,它將一直運行直到s[i]不等於t[i]為止。

  2. for ( ; *s == *t; s++, t++)

; 這意味着省略了for循環的第一子句。 由於bot stfor循環之外定義,因此無需在此處定義它們。

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.

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