7

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

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

我想要的是,看看这个角色是不是我想要的。说得通俗一点,我想在 if 的行和 if 的主体中都使用 variable(char c) 不在if之外

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

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

3 回答 3

17

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

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

所以这c只会持续到到达块的末尾。

于 2013-07-11T02:42:23.253 回答
10

if在看到一些发布的解决方案之前,我不知道如何创建一个变量并用 an 测试它的值。但是,您可以使用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...
}
于 2013-07-11T02:40:40.523 回答
8

可以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 || ...or if (ch = 0 && ...,短路评估将使正确的操作数(您真正关心的部分)根本不被评估。

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

编辑:有人指出,由此产生的结果可能比一些人最初预期的更具误导性,因此我将尝试澄清这种情况。发生的是从输入中读取一个值。该值被分配给ch并与 进行比较0x1。到目前为止,一切都很好。之后,比较的结果(转换为整数,因此01)将被分配给ch。我相信它有足够的序列点,结果是定义的行为。但这可能不是你或任何人想要的——因此建议你可能不想使用它,并提到它可能会让大多数程序员摸不着头脑,想知道你在做什么。在与 0x1 比较的非常特殊的情况下,ch内部的值if声明将是1,但这或多或少是一个巧合。如果您与 0x2 进行比较,则ch内部的值if仍然是1,而不是2

于 2013-07-11T03:16:48.987 回答