### 局部作用域

局部作用域描述的是函数体中变量、常量等对象的作用范围。每一个函数都有一个独立的局部作用域，在函数体中定义的变量、常量，对外部函数是不可见的，因为它处于函数的局部作用域中。对于函数体中出现的复合语句，也有其独立的局部作用域，在其中定义的对象，复合语句之外是不能访问的。例如：

int main(int argc, char* argv[])

{

printf("局部作用域\n"); //输出语句

{ //复合语句，有其自己的作用域

int ivar = 10; //定义一个局部变量，处于复合语句的作用域中

}

printf("%d",ivar); //访问 ivar 错误，ivar 超出了其作用范围，其作用范围是在复合语句中

return 0;

}

在上述代码中，变量 ivar 的作用范围处于复合语句的作用域中，因此语句“printf("%d",ivar);”访问变量 ivar 是非法的。

对于处于同一局部作用域的对象来说，对象是不允许重名的。例如：

int main(int argc, char* argv[])

{

int ivar = 5; //定义一个局部整形变量

char ivar; //错误的定义，定义一个字符变量

int argc; //错误的定义，与参数 argc 同名

{

int ivar = 10; //正确的定义，处于复合语句的局部作用域中

int argc = 20; //正确的定义，处于复合语句的局部作用域中

}

return 0;

}

在上述代码中，语句“char ivar;”定义的变量与整型变量 ivar 同名，并且处于同一局部作用域，因此出现编译错误。而语句“int argc;”与参数 arge 同名，并且处于同一局部作用域，因此同样出现编译错误。对于函数参数来说，其作用域为函数的局部作用域。复合语句部分定义的两个变量是合法的，它们虽然与变量 ivar 和函数参数同名，但是处于不同的局部作用域。

下面介绍一下编译器对局部作用域内变量命名解析的过程。当编译器在当前代码处发现变量名时，它将在当前的局部作用域内搜索变量的定义，如果没有发现变量的定义，则向外一层的局部作用域搜索变量的定义，知道搜索完全局作用域。如果还没有发现变量的定义，则会出现标识符没有定义的错误。如果在嵌套局部作用域的外层和内部作用域定义了同名的变量，对于内层的局部作用域变量来说，它将隐藏外部局部定义域中的变量。

例如，隐藏外部局部定义域中的变量。

int main(int argc, char* argv[])

{

int ivar = 5;

{ //复合语句，有其自己的作用域

int ivar = 10; //定义一个局部变量，处于复合语句的作用域中

printf("%d\n",ivar); //ivar 等于 10

}

printf("%d\n",ivar); //ivar 等于 5

return 0;

}

在上述代码中，复合语句中的 printf 函数输出的 ivar 值为 10，而外层的 printf 函数输出的 ivar 为 5。在复合语句中，定义的变量 ivar（值为 10）隐藏了外部作用域定义的变量 ivar（值为 5）。

下面对上述代码稍加修改，分析输出结果。

{

int ivar = 5;

{ //复合语句，有其自己的作用域

printf("%d\n",ivar); //ivar 等于 5

int ivar = 10; //定义一个局部变量，处于复合语句的作用域中

printf("%d\n",ivar); //ivar 等于 10

}

printf("%d\n",ivar); //ivar 等于 5

return 0;

}

在上面的复合语句中，两次调用了 printf 函数（黑体部分代码），第一次调用 printf 函数输出的 ivar 值为 5，因为当前复合语句的局部定义域没有发现变量 ivar 的定义，编译器在外层的局部作用域中发现了 ivar 的定义。而第 2 个 printf 函数输出的 ivar 值为 10，因为编译器在复合语句的局部作用域中直接发现了变量 ivar 的定义。