我正在阅读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;
}
答案 0 :(得分:2)
首先,一些基础知识。
for
循环的语法是
for ( expr1opt ; expr2opt ; expr3opt ) statement
每个 expr1
, expr2
和 expr3
都是可选的。声明
for ( ; ; ) { // do something }
除非在循环体中某处有break
或return
语句,将永远循环播放#34;
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
,而是使用指针。由于没有什么可以初始化,所以第一个表达式只是留空。
答案 1 :(得分:1)
在第一种情况下,for
语句之后的代码检查是否找到了字符串结束标记,如果是,则该函数返回0.
在第二个for
语句的情况下,for
语句的初始化部分未填写,因此语句以for( ;
开头。这是完全合法的。
祝你好运。
答案 2 :(得分:1)
For循环有3个部分 - 初始化,条件和循环表达。所有这些都是可选的 所以这个循环 -
for (i = 0; s[i] == t[i]; i++)
直到字符s[i]
等于t[i]
为止。所以这是条件。如果是假循环中断。
条件不一定总是基于长度。
这一个 -
for ( ; *s == *t; s++, t++)
正如我们在上面看到的那样初始化是可选的,并且在这里不存在,这是完全正常的。该循环中的条件也是相同的即循环,直到字符相等。
答案 3 :(得分:1)
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()的最后一部分在每次迭代后执行。在这种情况下,我们需要增加两个变量,因此有两个语句用逗号分隔。
答案 4 :(得分:1)
它没有长度。 for
循环运行直到条件为真,因此在这种情况下,这意味着它将一直运行,直到s[i]
不等于t[i]
。
for ( ; *s == *t; s++, t++)
;
这里意味着省略了for
循环的第一个子句。如
僵尸s
和t
是在for
循环之外定义的,因此无需在此处定义它们。
C标准允许:
for(clause-1; expression-2; expression-3)statement
(...)
可以省略子句-1和表达式-3。省略的表达式-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++)
^