如何在if语句的方括号中声明变量



我想在if语句的方括号中声明一个局部变量。例如

if((char c = getc(stdin)) == 0x01)//This is not OK with g++.
{
    ungetc(c, stdin);
}

我想要的是,看看这个角色是否就是我想要的那个。一般来说,我想在if的行和ifbody中使用变量(charc),但不在if之外。

但是g++(GCC 4.8.1)表示在'char'之前需要主表达式。我想知道是否有办法做到这一点,因为我不想要像这样的东西

char c = getc(stdin);
if(c == 0x01)
{
    bla...
}

如果您担心的是命名空间污染,那么您可以始终在块中定义if语句:

{
    char c = getc(stdin);
    if(c == 0x01)
    {
        // ...
    }
}

使得CCD_ 2将仅持续到到达块的末尾。

直到看到一些发布的解决方案后,我才知道如何创建变量并用if测试其值。但是,您可以使用switch。这将允许您对附加值(可能是EOF)做出反应:

switch (int c = getc(stdin)) {
case 0x01: ungetc(c, stdin); break;
case EOF:  // ...handle EOF
default:   break;
}

您可以始终将if语句放在内联函数中,这样代码看起来会更干净一些。如果您真的希望源代码就在那个位置,但没有在带有新变量的if周围创建新的作用域,那么lambda可能是您可以接受的。

[](int c){ if (c == 0x01) ungetc(c, stdin); }(getc(stdin));

由于你只与一个值进行比较,你的特定问题根本不需要变量,所以你可以简单地做:

if (getc(stdin) == 0x01) {
    char c = 0x01;
    ungetc(c, stdin); //or bla...
}

如果您想与一组值进行比较,那么switch建议是更好的选择。

Jerry Coffin的解决方案看起来很有吸引力,但实际上可以归结为:

if (int c = (getc(stdin) == 0x01)) //...

这可能不是您真正想要的,因为如果您想与不同于0x01的值进行比较,它不会很好地概括。

Potatoswatter的解决方案似乎更接近你想要的,但也许把类型拉到一个独立的类中会更好:

template <typename T>
class SetAndTest {
    const T test_;
    T set_;
public:
    SetAndTest (T s = T(), T t = T()) : set_(s), test_(t) {}
    operator bool () { return set_ == test_; }
    operator bool () const { return set_ == test_; }
    operator T & () { return set_; }
    operator T () const { return set_; }
};
//...
if (auto c = SetAndTest<int>(getc(stdin), 0x01)) {
    ungetc(c, stdin); //or bla...
}

可以if语句中定义变量。例如,这应该编译:

if (int ch = getchar())
    ;

问题是类型(例如int)必须紧跟在左括号后的后面。额外的括号是导致编译失败的原因。所以,如果你真的想这样做,你需要变得聪明一点,并使用这样的东西:

if (char ch = 0 || ((ch = getchar()) == 0x1))

这使您可以完成ch的创建和初始化,然后在表达式的该部分完成后,将其放在ch=getchar()周围的括号中,以覆盖赋值与比较的优先级。

请注意,&&||会进行短路评估,因此您需要小心初始化。您可以使用以下任一项:

if (char ch = 0 || ...

或:

if (char ch = 1 && ...

但是,如果您尝试使用if (ch = 1 || ...if (ch = 0 && ...,短路求值将完全阻止对正确的操作数(您真正关心的部分)进行求值。

现在需要注意的是:虽然我有理由确信这段代码符合标准的要求,而且大多数(所有?)当前的编译器都会接受它,但这可能会让大多数阅读代码的程序员感到头疼,弄清楚你做了什么,以及为什么。对于在实际代码中使用这种"技术",我会非常犹豫(充其量)。

编辑:有人指出,这一结果可能比一些人最初预期的更具误导性,所以我会努力澄清情况。实际情况是从输入中读取一个值。该值被分配给ch并与0x1进行比较。到目前为止还不错。之后,比较结果(转换为整数,因此c0或1)将被分配给ch。我相信它有足够的序列点,结果就是定义的行为。但这可能不是你或任何人想要的——因此,你可能不想使用它的建议,以及提到它可能会让大多数程序员挠头,想知道你想做什么。在与0x1进行比较的特定情况下,if语句中ch的值将是1,但这或多或少是巧合。如果将其与0x2进行比较,则if中的ch的值仍然是1,而不是2

最新更新