2

我正在尝试从我的代码中删除重复的行。目前,它看起来像这样:

if (FALSE == DoFoo(strFile1, strData1))
{
    return (FALSE);
}
if (FALSE == DoFoo(strFile2, strData1))
{
    return (FALSE);
}
if (FALSE == DoFoo(strFile3, strData1))
{
    return (FALSE);
}
if (FALSE == DoBar(strData1))
{
    return (FALSE);
}
if (FALSE == DoFoo(strFile4, strData2))
{
    return (FALSE);
}
if (FALSE == DoFoo(strFile5, strData2))
{
    return (FALSE);
}
if (FALSE == DoFoo(strData1, strData2))
{
    return (FALSE);
}
if (FALSE == DoBar(strData2))
{
    return (FALSE);
}
return (TRUE);

我已将其更改为如下所示:

if (DoFoo(strFile1, strData1))
{
    if (DoFoo(strFile2, strData1))
    {
        if (DoFoo(strFile3, strData1))
        {
            if (DoBar(strData1))
            {
                if (DoFoo(strFile4, strData2))
                {
                    if (DoFoo(strFile5, strData2))
                    {
                        if (DoFoo(strData1, strData2))
                        {
                            if (DoBar(strData2))
                            {
                                return (TRUE);
                            }
                        }
                    }
                }
            }
        }
    }
}
return (FALSE);

是否有嵌套 if 的标准?是否有普遍认可的限制?通常,它可能会与这么多嵌套混淆,但由于没有发生任何复杂的事情,也没有额外的代码行,所以看起来仍然很清楚。哪种方式更好?还是有另一种方法可以比其中任何一种更整洁和/或更短?

4

4 回答 4

3

我将按如下方式实现它:

bool func() {
  return DoFoo(strFile1, strData1)
     &&  DoFoo(strFile2, strData1)
     &&  DoFoo(strFile3, strData1)
     &&  DoBar(strData1)
     &&  DoFoo(strFile4, strData2)
     &&  DoFoo(strFile5, strData2)
     &&  DoFoo(strData1, strData2)
     &&  DoBar(strData2);
 }
于 2013-11-06T19:47:35.573 回答
2

这没有标准。你可以自由地做任何你想做的事,直到你单独处理代码。

但是大多数人建议避免它(将自己限制为 1-2 嵌套级别),因为这样的代码很难阅读。实践表明,在大多数情况下这是可能的。

例如,在您的情况下,您可以使用 && 运算符:

if ( DoFoo(strFile1, strData1) &&
     DoFoo(strFile2, strData1) &&
     DoFoo(strFile3, strData1) &&
     DoBar(strData1) &&
     DoFoo(strFile4, strData2) &&
     DoFoo(strFile5, strData2) &&
     DoFoo(strData1, strData2) &&
     DoBar(strData2)
   ) {
  return FALSE;
}

看?这使代码更容易。

在其他情况下,您可以使用

  1. switch(...) 运算符。
  2. 否则,如果组成:

    if (A) {
    
    } else if (B) {
    
    } else if (C) {
    ...
    
  3. 函数调用:

    void CheckCoor( ... ) {
      if ( coor >= ... ) {
         CheckAngle(...);
      else {
         CheckPosibilityToChangeCoor(...);
      }
    }
    

通常这 4 个选项足以避免多个嵌套级别。

于 2013-11-06T20:40:24.080 回答
1

也许像下面这样的东西是摆脱嵌套 if 语句的另一种可能性。

有一个丑陋的 C 类强制转换来使表格正确,我们假设有额外的、未使用的参数不会成为问题。

当在调试器中运行时,它编译并似乎可以与 Microsoft Visual Studio 2005 作为 Windows 控制台应用程序一起使用。当然,在这个例子中,DoFoo ()DoBar()函数都是存根,假设的 char 指针不指向任何东西,但结构在那里。

bool DoFoo (char *s1, char *s2)
{
    return true;
}
bool DoBar (char *s1)
{
    return true;
}

char *strData1;
char *strData2;
char *strFile1;
char *strFile2;
char *strFile3;
char *strFile4;
char *strFile5;

typedef bool (*xFunc)(char *s1, char *s2);

typedef struct {
    xFunc  pF;
    char  *s1;
    char  *s2;
} TableItem;

bool myFunc(void)
{
TableItem fArray[] = {
    { DoFoo, strFile1, strData1},
    { DoFoo, strFile2, strData1},
    { DoFoo, strFile3, strData1},
    { (xFunc)DoBar, strData1, NULL},
    { DoFoo, strFile4, strData2},
    { DoFoo, strFile5, strData2},
    { DoFoo, strData1, strData2},
    { (xFunc)DoBar, strData2, NULL}
};

bool bRet = true;
int i = 0;
for (i = 0; bRet && i < sizeof(fArray)/sizeof(fArray[0]); i++) {
  bRet = fArray[i].pF(fArray[i].s1, fArray[i].s2) && bRet;
}

return bRet;
}

int _tmain(int argc, _TCHAR* argv[])
{
    myFunc();
    return 0;
}

编辑 - 另一种可能性

另一种方法如下。这不需要 C 风格的演员表。

bool DoFoo (char *s1, char *s2)
{
    return true;
}
bool DoBar (char *s1)
{
    return true;
}

char *strData1;
char *strData2;
char *strFile1;
char *strFile2;
char *strFile3;
char *strFile4;
char *strFile5;

typedef enum {funcType1 = 1, funcType2} funcType;

typedef struct {
    funcType fType;
    char     *s1;
    char     *s2;
} TableItem;

bool myFunc(void)
{
TableItem fArray[] = {
    { funcType1, strFile1, strData1},
    { funcType1, strFile2, strData1},
    { funcType1, strFile3, strData1},
    { funcType2, strData1, NULL},
    { funcType1, strFile4, strData2},
    { funcType1, strFile5, strData2},
    { funcType1, strData1, strData2},
    { funcType2, strData2, NULL}
};

bool bRet = true;
int i = 0;
for (i = 0; bRet && i < sizeof(fArray)/sizeof(fArray[0]); i++) {
    switch (fArray[i].fType) {
        case funcType1:
            bRet = DoFoo (fArray[i].s1, fArray[i].s2);
            break;
        case funcType2:
            bRet = DoBar (fArray[i].s1);
            break;
        default:
            break;
    }
}

return bRet;
}

int _tmain(int argc, _TCHAR* argv[])
{
    myFunc();
    return 0;
}

编辑 - 还有另一种可能性

另一种方法如下。这是非常直接的 C++。

    bool DoFoo (char *s1, char *s2)
    {
        return true;
    }
    bool DoBar (char *s1)
    {
        return true;
    }

    char *strData1;
    char *strData2;
    char *strFile1;
    char *strFile2;
    char *strFile3;
    char *strFile4;
    char *strFile5;

class funcObj {
public:
    funcObj (bool (*pf) (char *s1, char *s2), char *s1, char *s2);
    funcObj (bool (*pf) (char *s1), char *s1);
    funcObj ();
    ~funcObj() {}
    bool eval ();
private:
    bool (*m_dofoo) (char *s1, char *s2);
    bool (*m_dobar) (char *s1);
    char  *m_s1;
    char  *m_s2;
};

funcObj::funcObj (bool (*pf) (char *s1, char *s2), char *s1, char *s2)
{
    m_dofoo = pf;
    m_dobar = 0;
    m_s1 = s1;
    m_s2 = s2;
}
funcObj::funcObj (bool (*pf) (char *s1), char *s1)
{
    m_dofoo = 0;
    m_dobar = pf;
    m_s1 = s1;
    m_s2 = 0;
}

funcObj::funcObj ()
{
    m_dofoo = 0;
    m_dobar = 0;
    m_s1 = 0;
    m_s2 = 0;
}

bool funcObj::eval ()
{
    bool bRet = false;

    if (m_dofoo)
        bRet = m_dofoo(m_s1, m_s2);
    else if (m_dobar)
        bRet = m_dobar (m_s1);
    return bRet;
}

typedef struct {
    funcObj  fObj;
} TableItem;

bool myFunc(void)
{
    funcObj fArray[] = {
        funcObj(DoFoo, strFile1, strData1),
        funcObj(DoFoo, strFile2, strData1),
        funcObj(DoFoo, strFile3, strData1),
        funcObj(DoBar, strData1),
        funcObj(DoFoo, strFile4, strData2),
        funcObj(DoFoo, strFile5, strData2),
        funcObj(DoFoo, strData1, strData2),
        funcObj(DoBar, strData2)
    };

    bool bRet = true;
    int i = 0;
    for (i = 0; bRet && i < sizeof(fArray)/sizeof(fArray[0]); i++) {
        bRet = fArray[i].eval();
    }

    return bRet;
}
    int _tmain(int argc, _TCHAR* argv[])
    {
        myFunc();
        return 0;
    }
于 2013-11-06T20:28:15.963 回答
1

有一个更好的方法:

if(DoFoo(strFile1, strData1) && DoFoo(strFile2, strData1) && //etc...
    return true;

或者:

if(!DoFoo(strFile1, strData1) || !DoFoo(strFile2, strData1) || //etc...
    return false;
于 2013-11-06T19:44:17.273 回答