Что означает "локальные переменные в самой внешней области функции не могут использовать то же имя, что и любой параметр"?

Я читал c++ primer 5th edition. В третьем абзаце списка параметров функции главы 6.1 . Он пишет:"кроме того, локальные переменные в самой внешней области функции не могут использовать то же имя, что и любой параметр". Что это значит?

Я не носитель английского языка. Я не понимаю фактических значений "самого внешнего объема" функции.

5 ответов


самая внешняя область функции-это блок, который определяет тело функции. Вы можете поместить в него другие (внутренние) блоки и объявить переменные в тех, которые являются локальными для этого блока. Переменные во внутренних блоках могут иметь то же имя, что и во внешнем блоке, или параметры функции; они скрывают имена во внешней области. Переменные во внешнем блоке не могут иметь то же имя, что и параметр функции.

продемонстрировать:

void f(int a)           // function has a parameter
{                       // beginning of function scope
    int b;              // OK: local variable
    {                   // beginning of inner block
        int a;          // OK: hides parameter
        int b;          // OK: hides outer variable
    }                   // end of inner block
    int a;              // Error: can't have same name as parameter
}

Это означает, что вы не можете делать вещи, как это:

void foo (int x)
{
    int x = 4; //in the outermost scope, invalid
}

Вы можете, однако, сделать этого:

void foo (int x)
{
    { //this introduces a new scope
        int x = 4; //not in the outermost scope, valid
    }
}

Это означает, что это неверный:

void f(int p)
{
   int p = 3;
}

как это

void f(int p)
{
  {
    int p = 3;
  }
}

разрешено.


это правило действует не только для параметров функций определений функций, но и для итерационных и условных операторов, а также для обработчиков исключений

3.3.3 блок рамки

2 потенциальная область имени параметра функции (включая один появляется в лямбда-деклараторе) или функции-локальной предопределенной переменная в определении функции (8.4) начинается в точке декларация. Если функция имеет функцию-try-block потенциал область действия параметра или функции - локальная предопределенная переменная заканчивается в конце последнего связанного обработчика, в противном случае он заканчивается на конец внешнего блока определения функции. Параметр имя не должно быть повторно объявлено в самом внешнем блоке функции определение, ни в самом внешнем блоке все обработчики, связанные с функции блока try.

3 имя, объявленное в объявлении исключения, является локальным для обработчик и не будет redeclared в крайнем блоке обработчик.

4 имени, объявленные в инструкции for-init, объявлении for-range, и в состоянии if, while, for и Switch операторы являются локальный оператор if, while, for или switch (включая оператор контролируемое заявление), и не будет redeclared в последующем условии, что заявление ни в самом внешнем блоке (или, если оператор, любой из внешних блоков) контролируемого оператора; видеть 6.4.

например этот фрагмент кода является инвалидом

if( int x = SomeFunction() )
{
    int x; // invalid declaration
    //...
}

представьте, что у вас есть функция "foo", которая принимает целочисленный параметр "bar".

int foo (int bar)
{
    int bar = 0; // < illegal, this is the 'outermost' scope
    if (bar == 10) {
        int bar = 5; // legal (though unadvisable) this 'shadows' the passed-in 'bar'
        return bar;
    }
    return bar;
}

первое внутреннее объявление " bar " является незаконным, так как переданный параметр in также объявлен в том же контексте (хотя синтаксис не обязательно делает это ясным.)

Так же, как было бы неправильно писать:

int bar;
char bar[10];

поскольку эти две переменные имеют одинаковую область.

второе объявление бара (в функции foo выше) является законным (хотя обычно это плохая идея), поскольку он объявлен во внутренней области "если" и, следовательно, честной игры.

надеюсь, что это поможет.