【问题标题】:pointer with equality operator ( problem! )带有相等运算符的指针(问题!)
【发布时间】:2021-09-08 11:52:18
【问题描述】:

*为什么相等运算符与函数 char (checker) 上的指针对实际字符串没有影响

#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;
   
   }

** 我正在尝试用退格替换原始字符串中的制表符并返回修改后的字符串,但相等运算符对原始字符串没有影响。** 谁能帮我解决这个问题。

【问题讨论】:

  • 停止写*(cp+i)之类的东西。而是使用cp[i]。不要与语言抗争。
  • 问题是由于checker 使用了i 的全局变量,这太疯狂了。该全局变量具有在main 中写入的最后一个值(这也是疯狂地使用全局变量)。换句话说,它索引字符串末尾之后的字符。另外,您忘记了以空结尾的字符串。这里有很多错误。
  • 有什么理由定义一个 char 数组来保存制表符和另一个变量指向那里,然后取消引用它而不是只使用 '\t'?你可以简单地使用if(cp[i] == '\t')

标签: c pointers assignment-operator


【解决方案1】:

这部分是由于滥用全局变量造成的。

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

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

#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' 简单地写入strings 的末尾而不是动态地将零写入每个元素会更有效。通常,您希望避免对非静态数组使用初始化程序,因为它们很少需要并且会导致运行时开销。 C 最初甚至不允许它们。
  • @kshitizghimire 请注意,此解决方案做了一些它不应该做的事情,即它动态初始化一个自动数组作为将空字符写入末尾的惰性方式(它实际上将其写入 整个数组)。相反,您应该删除初始化程序,并在 main 中的 while 循环之后添加 string[i] = '\0';。这样你的评分者就不会因为不合适的数组初始化器而扣分。您还应该检查以确保您没有写入超出数组末尾的内容(两个版本都缺少该检查)。
  • @MM 我意识到较新版本的 C 已经被大量不必要的运行时开销来处理那些不能用像 C 这样的语言编写代码的人,而我强烈反对。 C 的全部意义在于它是超轻量级的,而且非常底层(基本上是一个便携式汇编程序)。如果您想要大量额外的运行时包袱,请使用 C++。
  • @M.M 你有权发表你的意见,但我不同意你的大部分技术观点。特别是:(1)我们都熟悉编程格言“过早的优化是万恶之源”。但是这句格言的意图是,除非确实需要这种效率,否则不应为了效率而过度复杂自己的代码。但这不适用于这里,因为在字符串末尾添加一个显式分配 \0 比依赖于初始化在设置字符串的代码上方几行。
  • @M.M 并且(2)这几乎不是“微微优化”。在实践中,对整个阵列进行零填充可能会花费大量时间。现在,当然,在这个例子中,数组很小,但更实际的大小应该是 1000 个字符,在这种情况下,消除将数组动态归零的代码可能很重要,尤其是在平均字符串大小很小的情况下。此外,它可以减少执行单个赋值的代码,而不是使用将所有元素归零的循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
相关资源
最近更新 更多