C 执行'时出现While循环错误;强度';
当我运行为“strlen”编写的程序时,我总是会出错。(当一个字符串出现在另一个字符串的末尾时,strlen返回1)。我猜是第一个while循环给出了错误,因为当我放入C 执行'时出现While循环错误;强度';,c,while-loop,C,While Loop,当我运行为“strlen”编写的程序时,我总是会出错。(当一个字符串出现在另一个字符串的末尾时,strlen返回1)。我猜是第一个while循环给出了错误,因为当我放入printf(“%c\n”,*s)时而不是空的,它只是工作正常。语法有问题吗 #include <stdio.h> int strend(char *s, char *t) { int len; int dummy; while ( *s++ ) ; // why error?
printf(“%c\n”,*s)时代码>而不是空的代码>,它只是工作正常。语法有问题吗
#include <stdio.h>
int strend(char *s, char *t)
{
int len;
int dummy;
while ( *s++ )
; // why error???
while ( *t++ )
len++;
for ( ; len>0 ; len--)
{
if ( *(s-len) != *(t-len) )
return 0;
}
return 1;
}
int main() {
char one[] = "I 0dont like youa";
char two[] = "ke youa";
printf("%d\n", strend(one, two));
}
#包括
强度(字符*s,字符*t)
{
内伦;
int假人;
而(*s++)
;//为什么会出错???
而(*t++)
len++;
对于(;len>0;len--)
{
如果(*(s-len)!=*(t-len))
返回0;
}
返回1;
}
int main(){
char one[]=“我不喜欢你”;
char two[]=“ke youa”;
printf(“%d\n”,强度(一,二));
}
首先,您忘记初始化len,应该用0初始化它
int len=0;
第二,使用这个:
while ( *s )
s++; // s should be incremented only if *s is not 0.
while ( *t )
{
t++; //Same issue here.
len++;
}
首先,您忘记初始化len,应该使用0初始化它
int len=0;
第二,使用这个:
while ( *s )
s++; // s should be incremented only if *s is not 0.
while ( *t )
{
t++; //Same issue here.
len++;
}
首先,局部变量len未初始化
int len;
因此,函数已经具有未定义的行为
循环之后的第二个
while ( *s++ );
while ( *t++ ) len++;
这两个指针都指向每个字符串的终止零之外。作为此比较的结果(以及for循环本身)
无效。
事实上,让我们假设我们有
char s[] = { 'a', '\0' };
char t[] = { 'a', '\0' };
在上述循环之后,len将等于1(前提是最初使用0初始化len)。同时,t和s将在结束零点后指向内存。因此*(s-len)
和*(t-len)
将表示元素'\0'
,您将只比较这些终止零,而不比较带有“a”的元素,因为for循环的条件是len>0
。这意味着,当len等于1时,循环只有一次迭代
正确的函数可以编写得更简单、更清晰
int strend( const char *s, const char *t )
{
const char *p = s;
const char *q = t;
while ( *s++ );
while ( *t++ );
while ( s != p && t != q && *( s - 1 ) == *( t - 1 ) ) --s, --t;
return t == q;
}
如果哪一个字符串出现在另一个字符串的末尾并不重要,那么只需替换此返回语句即可
return t == q;
下一个
return s == p || t == q;
在这种情况下,这个程序
//...
int main( void ) {
char one[] = "I 0dont like youa";
char two[] = "ke youa";
printf("%d\n", strend(one, two));
printf("%d\n", strend(two, one));
}
//...
int main( void ) {
char one[] = "I 0dont like youa";
char two[] = "ke youa";
printf("%d\n", strend(one, two));
printf("%d\n", strend(two, one));
}
将输出
1
1
1
0
而如果要使用第一个return语句returnt==q代码>然后是程序
将输出
1
1
1
0
首先,局部变量len未初始化
int len;
因此,函数已经具有未定义的行为
循环之后的第二个
while ( *s++ );
while ( *t++ ) len++;
这两个指针都指向每个字符串的终止零之外。作为此比较的结果(以及for循环本身)
无效。
事实上,让我们假设我们有
char s[] = { 'a', '\0' };
char t[] = { 'a', '\0' };
在上述循环之后,len将等于1(前提是最初使用0初始化len)。同时,t和s将在结束零点后指向内存。因此*(s-len)
和*(t-len)
将表示元素'\0'
,您将只比较这些终止零,而不比较带有“a”的元素,因为for循环的条件是len>0
。这意味着,当len等于1时,循环只有一次迭代
正确的函数可以编写得更简单、更清晰
int strend( const char *s, const char *t )
{
const char *p = s;
const char *q = t;
while ( *s++ );
while ( *t++ );
while ( s != p && t != q && *( s - 1 ) == *( t - 1 ) ) --s, --t;
return t == q;
}
如果哪一个字符串出现在另一个字符串的末尾并不重要,那么只需替换此返回语句即可
return t == q;
下一个
return s == p || t == q;
在这种情况下,这个程序
//...
int main( void ) {
char one[] = "I 0dont like youa";
char two[] = "ke youa";
printf("%d\n", strend(one, two));
printf("%d\n", strend(two, one));
}
//...
int main( void ) {
char one[] = "I 0dont like youa";
char two[] = "ke youa";
printf("%d\n", strend(one, two));
printf("%d\n", strend(two, one));
}
将输出
1
1
1
0
而如果要使用第一个return语句returnt==q代码>然后是程序
将输出
1
1
1
0
错误应该是因为缺少初始化int len=0代码>。我建议使用while
和像这样的拥抱while{/*你的代码*/}代码>
你的第一个while循环应该很好。我用两个分开的循环做了一些修改
#include <stdio.h>
int strend(char *s, char *t)
{
int len = 0; // init 0
int i = 0,
j = 0;
while (*s++) { i++; } // get both string lengths
while (*t++) { j++; }
if (i > j) // compare and use shorter one
len = j;
else
len = i;
len++; // offset: start from 1st character
// [fix-issue: 2015-06-28 12:41]
for ( ; len>0 ; len--)
{
//printf("%d: \"%c\" \"%c\"\n", len, *(s-len), *(t-len)); // test-out
if ( *(s-len) != *(t-len) )
return 0;
}
return 1;
}
int main()
{
char one[] = "ABCDE";
char two[] = "CDE";
printf("test case 1: [%s][%s] %d\n", one, two, strend(one, two));
two[1] = '_';
printf("test case 2: [%s][%s] %d\n", one, two, strend(one, two));
two[0] = '?';
two[1] = 'D';
printf("test case 3: [%s][%s] %d\n", one, two, strend(one, two));
two[0] = 'C';
two[2] = '#';
printf("test case 4: [%s][%s] %d\n", one, two, strend(one, two));
}
错误应该是因为缺少初始化int len=0代码>。我建议使用while
和像这样的拥抱while{/*你的代码*/}代码>
你的第一个while循环应该很好。我用两个分开的循环做了一些修改
#include <stdio.h>
int strend(char *s, char *t)
{
int len = 0; // init 0
int i = 0,
j = 0;
while (*s++) { i++; } // get both string lengths
while (*t++) { j++; }
if (i > j) // compare and use shorter one
len = j;
else
len = i;
len++; // offset: start from 1st character
// [fix-issue: 2015-06-28 12:41]
for ( ; len>0 ; len--)
{
//printf("%d: \"%c\" \"%c\"\n", len, *(s-len), *(t-len)); // test-out
if ( *(s-len) != *(t-len) )
return 0;
}
return 1;
}
int main()
{
char one[] = "ABCDE";
char two[] = "CDE";
printf("test case 1: [%s][%s] %d\n", one, two, strend(one, two));
two[1] = '_';
printf("test case 2: [%s][%s] %d\n", one, two, strend(one, two));
two[0] = '?';
two[1] = 'D';
printf("test case 3: [%s][%s] %d\n", one, two, strend(one, two));
two[0] = 'C';
two[2] = '#';
printf("test case 4: [%s][%s] %d\n", one, two, strend(one, two));
}
使用0
初始化len
。在(*s)++s时更改为;对于(len=0;*t;++t)++len代码>在64位上,如果有很长的“字符串”,代码将失败。使用size\u t
比使用int
更好。您还希望使函数int增强(const char*,const char*)
。使用0
初始化len
。更改为while(*s)+s;对于(len=0;*t;++t)++len代码>在64位上,如果有很长的“字符串”,代码将失败。最好使用size\u t
而不是int
。此外,您还希望增强函数int的强度(const char*,const char*)
。谢谢!但是我不明白“printf”在我的代码中有什么不同。它似乎能够自行找出未初始化的len,并正确运行代码。你知道原因吗???@deNsuh我很抱歉。我不明白你说的话。@deNsuh考虑到,因为len没有初始化,所以程序有未定义的行为。这意味着它可以给出预期的结果,也可以给出意外的结果。@deNsuh正如我在函数的实现中所示,没有必要引入变量len。这只会使代码变得复杂。thx太多了!但是我不明白“printf”在我的代码中有什么不同。它似乎能够自行找出未初始化的len,并正确运行代码。你知道原因吗???@deNsuh我很抱歉。我不明白你说的话。@deNsuh考虑到,因为len没有初始化,所以程序有未定义的行为。这意味着它可以给出预期的结果,也可以给出意外的结果。@deNsuh正如我在函数的实现中所示,没有必要引入变量len。这只会使代码变得复杂。