繁体   English   中英

C ++“添加大括号以避免其他晃动”

[英]C++ “add explicit braces to avoid dangling else”

bool isPalindromeIterative(const char *s1){

int len=strlen(s1)-1;

if(len>0)
    if(s1[0]==s1[len]){
        len-=2;
        isPalindromeIterative(s1+1);
    }
    else

        return false;

return true;
}

我在写关于回文报。 当我运行它时,它会显示如下警告:

“ :: 79:13:警告:请添加大括号,以免晃晃其他[-Wdangling-else]”

请帮我 ! 谢谢!

该代码在形式上没有任何问题,除非您希望else与外部if匹配。 一个常见的错误。

如果到处都添加大括号,将很清楚您的意图:

if(len>0)
{
    if(s1[0]==s1[len])
    {
        len-=2;
        isPalindromeIterative(s1+1);
    }
    else
    {
        return false;
    }
}

当你写的时候

if(len>0)
    if(s1[0]==s1[len]){

        // This has no effect on the recursive call.
        len-=2;

        // You missed the return in your post.
        return isPalindromeIterative(s1+1);
    }
    else
        return false;

您最有可能打算将else与第二个if关联。

if(len>0)
{
    if(s1[0]==s1[len])
    {
        return isPalindromeIterative(s1+1);
    }
    else
        return false;
}

但是,编译器不使用缩进来解决这一问题。 从编译器作者的角度来看,您可能打算将else与第一个if关联:

if(len>0)
{
    if(s1[0]==s1[len])
    {
        return isPalindromeIterative(s1+1);
    }
}
else
{
   return false;
}

由于这是开发人员经常犯的错误,因此编译器会警告您,并希望您更新代码,以免它变成运行时错误。


我想指出的是,用于检测字符串是否为回文的递归逻辑是错误的。

假设您的字符串是“ abxba”。

在第一次迭代中,您将'a''a'进行比较。
在下一次迭代中,将'b''a'进行比较,这是不正确的。 您最终得到错误的答案。

您必须稍微改变策略。 采用:

bool isPalindromeIterative(const char *s1, int start, int end)
{
   if ( start >= end )
   {
      return true;
   }

   if ( s1[start] == s1[end] )
   {
      return isPalindromeIterative(s1, start+1, end-1)
   }

   return false;
}

迭代调用的开始必须为:

isPalindromeIterative(s1, 0, strlen(s1)-1);

这是一种样式警告,请注意不要误读if子句。

if(len>0) {
    if(s1[0]==s1[len]){
        len-=2;
        isPalindromeIterative(s1+1);
    }
} else {
        return false;
}

更好地阅读并且不易出错。 我们公司有类似的编码准则; 对于具有方括号从句的if ,所有else分支以及if最高顺序中的所有其他if都必须具有方括号。

否则,您的示例很容易被误解为例如

if(len>0)
    if(s1[0]==s1[len]){
        len-=2;
        isPalindromeIterative(s1+1);
    }
else
    return false;

您最初的帖子标题提到了迭代,“迭代”仍然是函数名的一部分(即使它是递归的)。

您将此帖子标记为c ++,但未使用类。

其他答案回答了您有关错误消息的特定问题。


为了您的考虑,并且由于您已经选择了递归答案,这里提供了一种可能的使用std :: string&的 C ++ 迭代解决方案和尾递归解决方案。

#include <iostream>
#include <string>


class T589_t
{
public:

   int exec(int argc, char* argv[])
      {
         if (argc < 2)
         {
            std::cerr << "\n  please provide one or more string(s) to test" 
                      << std::endl;
            return -1;
         }

         for (int i = 0; i < argc; ++i)
         {
            std::string s = argv[i];
            {
               std::string yesno = (isPalindromeIterative(s) ? " is" : " is not");
               std::cout << "\n  '" << s << "'" << yesno << " a palindrome (iterative)" << std::flush;
            }
            std::cout << std::endl;
            {
               std::string yesno = (isPalindromeRecursive(s) ? " is" : " is not");
               std::cout << "  '" << s << "'" << yesno << " a palindrome (recursive)" << std::endl;
            }
         } // for 0..argc

         return 0;
      }

private: // methods


   bool isPalindromeIterative(const std::string& s1)
      {  //         ^^^^^^^^^
         bool retVal = false;                           // guess s1 is not palindrome
         int   left  = 0;                               // index of left most char
         int   right = static_cast<int>(s1.size()) - 1; // index of right most char

         do { // iterative loop

            if (s1[left] != s1[right]) break; // when not equal, is not palindrome

            left += 1;  right -= 1;  // iterate!

            if (left >= right)  // all chars tested?
            {
               retVal = true;   // confirm palindrome
               break;           // exit
            }

         } while (true); 

         return retVal;
      }

   // Notes    './dumy589'  // odd length 9
   //           ^-------^   [0] vs [8]
   //            ^-----^    [1] vs [7]
   //             ^---^     [2] vs [6]
   //              ^-^      [3] vs [5]
   //               ^       [4] == [4]  // left >= right, break

   // Notes     'abccba'    // even length 6
   //            ^----^     [0] vs [5]
   //             ^--^      [1] vs [4]
   //              ^^       [2] vs [3]
   //                       [3] vs [2]  // left >= right, break

   // Notes     'abcba'     // odd length 5
   //            ^---^      [0] vs [4]
   //             ^-^       [1] vs [3]
   //              ^        [2] vs [2]  // left >= right, break


   // and bonus: tail recursion based on above iterative     
   //               vvvvvvvvv
   bool isPalindromeRecursive(const std::string& s1)
      {
         // index of left most char
         int   left  = 0;          
         // index of right most char
         int   right = static_cast<int>(s1.size()) - 1; 

         return (isPalindromeRecursive(s1, left, right));
      }

   bool isPalindromeRecursive(const std::string& s1, int left, int right)
      {
         if (s1[left] != s1[right]) return false;
         left += 1;   right -= 1;
         if (   left  >=    right ) return true;
         return (isPalindromeRecursive(s1, left, right));
      }
}; // class T589_t


int main(int argc, char* argv[])
{
   T589_t  t589;
   return  t589.exec(argc, argv);
}

在Linux上,argv [0]是可执行文件的名称。

环境:Lubuntu 17.10,g ++(Ubuntu 7.2.0-8ubuntu3.2)7.2.0

调用时:

./dumy589 aba abccba tx s

此代码报告:

  './dumy589' is not a palindrome (iterative)
  './dumy589' is not a palindrome (recursive)

  'aba' is a palindrome (iterative)
  'aba' is a palindrome (recursive)

  'abccba' is a palindrome (iterative)
  'abccba' is a palindrome (recursive)

  'tx' is not a palindrome (iterative)
  'tx' is not a palindrome (recursive)

  's' is a palindrome (iterative)
  's' is a palindrome (recursive)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM