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: 警告:添加显式大括号以避免悬挂 else
[-Wdangling-else]"
请帮帮我!谢谢!
代码在形式上没有任何问题,除非您希望 else
匹配外部 if
。一个常见的错误。
如果你到处都加上大括号,你的意图就很清楚了:
if(len>0)
{
if(s1[0]==s1[len])
{
len-=2;
isPalindromeIterative(s1+1);
}
else
{
return false;
}
}
这是一种风格警告,防止错误阅读 if 子句。
if(len>0) {
if(s1[0]==s1[len]){
len-=2;
isPalindromeIterative(s1+1);
}
} else {
return false;
}
好读少error-prone。
我们公司有类似的编码指南;对于具有方括号子句的 if
,所有 else
分支和最高阶 if
中的所有其他 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);
您原来的 post 标题提到了迭代,并且 'Iterative' 仍然是您的函数名称的一部分(即使它是递归的)。
您将此 post 标记为 c++,但未使用 类。
其他答案解决了您关于错误消息的具体问题。
为了您的考虑,并且因为您已经选择了递归答案,这里有一个可能的 C++ 迭代 解决方案 和 tail-recursive 使用 std::string&.
的解决方案
#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] 是可执行文件名称。
环境:
鲁本图 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)
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: 警告:添加显式大括号以避免悬挂 else [-Wdangling-else]"
请帮帮我!谢谢!
代码在形式上没有任何问题,除非您希望 else
匹配外部 if
。一个常见的错误。
如果你到处都加上大括号,你的意图就很清楚了:
if(len>0)
{
if(s1[0]==s1[len])
{
len-=2;
isPalindromeIterative(s1+1);
}
else
{
return false;
}
}
这是一种风格警告,防止错误阅读 if 子句。
if(len>0) {
if(s1[0]==s1[len]){
len-=2;
isPalindromeIterative(s1+1);
}
} else {
return false;
}
好读少error-prone。
我们公司有类似的编码指南;对于具有方括号子句的 if
,所有 else
分支和最高阶 if
中的所有其他 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);
您原来的 post 标题提到了迭代,并且 'Iterative' 仍然是您的函数名称的一部分(即使它是递归的)。
您将此 post 标记为 c++,但未使用 类。
其他答案解决了您关于错误消息的具体问题。
为了您的考虑,并且因为您已经选择了递归答案,这里有一个可能的 C++ 迭代 解决方案 和 tail-recursive 使用 std::string&.
的解决方案#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] 是可执行文件名称。
环境: 鲁本图 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)