带有相等运算符的指针 ( 问题!

pointer with equality operator ( problem! )

提问人:kshitiz ghimire 提问时间:6/25/2021 更新时间:6/25/2021 访问量:80

问:

*为什么在函数 char 上使用指针的相等运算符(检查器)对实际字符串没有影响

#define MAXLINE 20
   char strings[MAXLINE];
   char nl[]= "\n";
   char space[]= " ";
   char tab[]= "\t";
   char *tab_p=tab;
   
   int i=0,j=0,c;
   char *s;
   //char* t;
   
   char *checker(char *cp);//function checks for \n,\s,\t
   
   int main()
   {
       while ( (c=getchar() )!= EOF )
           strings[i++]=c;
   
       s=checker(strings);//s gets address return value
   
       while(*(s+j) != '\0'){
           printf("%c",*(s+j));
           j++;
       }
   }
   
   char *checker( char *cp)
   {
       while( *(cp+i) != '\0'){
           if(*(cp+i) == *tab_p) /* this condition is not applied why?*/
               *(cp+i)= '\b';
           i++;
       }
   
       return cp;
   
   }

** 我正在尝试用退格键替换原始字符串中的制表符并返回修改后的字符串,但相等运算符对原始字符串没有影响。

C 指针 赋值运算符

评论

2赞 Tom Karzes 6/25/2021
别再写类似的东西了。请改用 .不要与语言作斗争。*(cp+i)cp[i]
1赞 Tom Karzes 6/25/2021
问题是由于使用了 的全局变量,这太疯狂了。该全局变量具有写入它的最后一个值(该值也疯狂地使用全局变量)。换句话说,它索引字符串末尾的字符。另外,您忘记为空终止字符串。这里有很多错误。checkerimain
0赞 Gerhardh 6/25/2021
为什么你定义一个 char 数组来保存一个制表符和另一个变量来指向那里,然后取消引用它而不是仅仅使用?您可以简单地使用'\t'if(cp[i] == '\t')

答:

0赞 dbush 6/25/2021 #1

这在一定程度上是由于滥用全局变量造成的。

输入 时,全局的值已设置为字符串的长度。所以没有进入循环。checkeriwhile

将所有全局变量移动到需要它们的函数中。具体来说,将它们全部移动到 ,并添加到 。mainichecker

#define MAXLINE 20
char *checker(char *cp);

int main()
{
   char strings[MAXLINE] = {0};

   int i=0,j=0,c;
   char *s;

   while ( (c=getchar() )!= EOF )
       strings[i++]=c;

   s=checker(strings);

   while(*(s+j) != '\0'){
       printf("%c",*(s+j));
       j++;
   }
}

char *checker( char *cp)
{
   char tab = '\t';
   int i=0;

   while( *(cp+i) != '\0'){
       if(*(cp+i) == tab)
           *(cp+i)= '\b';
       i++;
   }

   return cp;
}

评论

0赞 Tom Karzes 6/25/2021
简单地将 a 写到末尾比动态地将 0 写给每个元素会更有效。通常,您希望避免对非静态数组使用初始值设定项,因为很少需要初始值设定项,并且会导致运行时开销。C 最初甚至不允许他们。'\0'strings
0赞 Tom Karzes 6/25/2021
@kshitizghimire 请注意,此解决方案执行了不应执行的操作,即它动态初始化自动数组,作为将 null 字符写入末尾的一种懒惰方式(它实际上将其写入整个数组)。相反,您应该删除初始值设定项,并在 main 中的循环之后添加。这样,您的评分器就不会因不合适的数组初始值设定项而扣分。您还应该检查以确保您没有写过数组的末尾(两个版本都缺少该检查)。string[i] = '\0';while
1赞 Tom Karzes 6/25/2021
@M.M 我意识到新版本的 C 已经被大量不必要的运行时开销所淹没,以处理那些无法用 C 等语言编码的人,我强烈反对它。C 的全部意义在于它是超轻量级的,而且非常低级(基本上是一个便携式汇编器)。如果您想要大量额外的运行时包袱,请使用 C++。
1赞 Tom Karzes 6/25/2021
@M.M:你有权发表你的意见,但我不同意你的大多数技术观点。特别是:(1)我们都熟悉编程格言“过早优化是万恶之源”。但是这句格言的意图是,除非确实需要效率,否则不应该为了效率而使代码过于复杂。但这在这里并不适用,因为在字符串末尾添加显式赋值 of 比依赖于设置字符串的代码上方几行的初始化更清晰更不容易出错\0
1赞 Tom Karzes 6/25/2021
@M.M (2)这几乎不是一个“微微优化”。在实践中,对整个阵列进行零填充可能需要大量时间。现在,当然,在这个例子中,数组很小,但更现实的大小应该是 1000 个字符,在这种情况下,消除代码以动态归零数组可能很重要,尤其是在平均字符串大小很小的情况下。此外,它导致更少的代码来执行单个赋值,而不是有一个将所有元素归零的循环。