变量作用域内的子作用域内被重新定义的思考
2011-12-31 10:01
253 查看
首先来看这样一个例子:
在VC6中:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//循环A
for ( int i=0; i<10; i++)
{
cout <<i <<"------" <<endl;
{
//循环B
for ( int i=0; i<5; i++)
{
cout <<i <<"######" <<endl;
}
//语句C
cout <<i <<"----------------" <<endl;
}
cout <<i <<"---------------------------------------------" <<endl;
}
return 0;
}
编译结果
--------------------Configuration: overi - Win32 Debug--------------------
Compiling...
StdAfx.cpp
Compiling...
overi.cpp
Linking...
overi.exe - 0 error(s), 0 warning(s)
输出结果:
![](http://hi.csdn.net/attachment/201112/31/0_1325297025oNZV.gif)
由于VC6对c++标准的支持较差,导致循环B处定义的i在的作用域延伸到语句C处,因些语句C输出为5----------------
再看VS2008:
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//循环A
for ( int i=0; i<10; i++)
{
wcout <<i <<"------" <<endl;
{
//循环B
for ( int i=0; i<5; i++)
{
wcout <<i <<"######" <<endl;
}
//语句C
wcout <<i <<"----------------" <<endl;
}
wcout <<i <<"---------------------------------------------" <<endl;
}
}
编译结果
1>------ 已启动全部重新生成: 项目: overi, 配置: Debug Win32 ------
1>正在删除项目“overi”(配置“Debug|Win32”)的中间文件和输出文件
1>正在编译...
1>stdafx.cpp
1>正在编译...
1>overi.cpp
1>f:\workspace\for_vs2008\overi\overi\overi.cpp(18) : warning C4258: “i”: 忽略 For 循环中的定义;使用封闭范围中的定义
1> f:\workspace\for_vs2008\overi\overi\overi.cpp(14) : 忽略“i”的定义
1> f:\workspace\for_vs2008\overi\overi\overi.cpp(10) : 使用“i”的定义
1>正在编译资源清单...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>正在链接...
1>LINK : 没有找到 F:\workspace\for_vs2008\overi\Debug\overi.exe 或上一个增量链接没有生成它;正在执行完全链接
1>正在嵌入清单...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>生成日志保存在“file://f:\workspace\for_vs2008\overi\overi\Debug\BuildLog.htm”
1>overi - 0 个错误,1 个警告
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========
输出结果:
![](http://hi.csdn.net/attachment/201112/31/0_13252969776v5e.gif)
由于VS2008显然对c++标准的支持好得多,循环B处定义的i在的作用域只在括号处便结束,因些语句C输出为4----------------
这表面上是小问题,可有时候会导致逻辑错误很难被查出。在嵌套循环时我们应该另外定义一个变量如:
for( int i=0; i<10; i++)
{
for( int k=0; k<10; k++)
{
.....
}
}
这样就不会有问题。
一个只有10行的代码,相信大家都不会写出上面的bug代码,但如果函数有3000行,那就不好说了,解决的办法是对代码不断重构,
写短小的函数,一个函数只做一个简单的功能,将大函数划分成小函数,减少重复代码,这样就能减少出错的概率。
另外,从编译的结果可以看出,vs2008立刻对代码提出了警告,而vc6表示一切正常. 好的工具也能减小错误的发生,我们有充分的理由抛弃VC6了
在VC6中:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//循环A
for ( int i=0; i<10; i++)
{
cout <<i <<"------" <<endl;
{
//循环B
for ( int i=0; i<5; i++)
{
cout <<i <<"######" <<endl;
}
//语句C
cout <<i <<"----------------" <<endl;
}
cout <<i <<"---------------------------------------------" <<endl;
}
return 0;
}
编译结果
--------------------Configuration: overi - Win32 Debug--------------------
Compiling...
StdAfx.cpp
Compiling...
overi.cpp
Linking...
overi.exe - 0 error(s), 0 warning(s)
输出结果:
![](http://hi.csdn.net/attachment/201112/31/0_1325297025oNZV.gif)
由于VC6对c++标准的支持较差,导致循环B处定义的i在的作用域延伸到语句C处,因些语句C输出为5----------------
再看VS2008:
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//循环A
for ( int i=0; i<10; i++)
{
wcout <<i <<"------" <<endl;
{
//循环B
for ( int i=0; i<5; i++)
{
wcout <<i <<"######" <<endl;
}
//语句C
wcout <<i <<"----------------" <<endl;
}
wcout <<i <<"---------------------------------------------" <<endl;
}
}
编译结果
1>------ 已启动全部重新生成: 项目: overi, 配置: Debug Win32 ------
1>正在删除项目“overi”(配置“Debug|Win32”)的中间文件和输出文件
1>正在编译...
1>stdafx.cpp
1>正在编译...
1>overi.cpp
1>f:\workspace\for_vs2008\overi\overi\overi.cpp(18) : warning C4258: “i”: 忽略 For 循环中的定义;使用封闭范围中的定义
1> f:\workspace\for_vs2008\overi\overi\overi.cpp(14) : 忽略“i”的定义
1> f:\workspace\for_vs2008\overi\overi\overi.cpp(10) : 使用“i”的定义
1>正在编译资源清单...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>正在链接...
1>LINK : 没有找到 F:\workspace\for_vs2008\overi\Debug\overi.exe 或上一个增量链接没有生成它;正在执行完全链接
1>正在嵌入清单...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>生成日志保存在“file://f:\workspace\for_vs2008\overi\overi\Debug\BuildLog.htm”
1>overi - 0 个错误,1 个警告
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========
输出结果:
![](http://hi.csdn.net/attachment/201112/31/0_13252969776v5e.gif)
由于VS2008显然对c++标准的支持好得多,循环B处定义的i在的作用域只在括号处便结束,因些语句C输出为4----------------
这表面上是小问题,可有时候会导致逻辑错误很难被查出。在嵌套循环时我们应该另外定义一个变量如:
for( int i=0; i<10; i++)
{
for( int k=0; k<10; k++)
{
.....
}
}
这样就不会有问题。
一个只有10行的代码,相信大家都不会写出上面的bug代码,但如果函数有3000行,那就不好说了,解决的办法是对代码不断重构,
写短小的函数,一个函数只做一个简单的功能,将大函数划分成小函数,减少重复代码,这样就能减少出错的概率。
另外,从编译的结果可以看出,vs2008立刻对代码提出了警告,而vc6表示一切正常. 好的工具也能减小错误的发生,我们有充分的理由抛弃VC6了
相关文章推荐
- 变量在函数体内和函数内嵌作用域内定义区别
- 疑问:问号在C#变量定义时的作用!
- linux c 一站式学习 extern关键词作用、变量的声明与定义以及extern与include的区别(都与extern有关)
- Shell脚本定义变量和重新赋值
- js特殊例子--方法内重新定义了变量在后面就会前面的为undifined,后面没有定义就用全局的--各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函
- 2.2变量(1)初始化,声明和定义,extern,静态类型,作用域
- 示例一个PLSQL完成功能来说明PLSQL的作用(定义变量+异常处理+抛异常)
- 重新学习C语言——变量定义l
- [学习笔记]变量的定义与作用范围(使用)
- 有权访问另一个函数作用域内变量的函数都是闭包。
- 循环体外和循环体内定义变量的一点思考
- PHP关键字global在定义变量中的作用
- 汇编语言中可以定义变量吗?怎么定义?有局部变量和全局变量之分吗?作用域是什么?
- js 定义变量的时候 var 和不带var的作用 具体代码演示
- 第一部分 基本语言 第二章 变量和基本类型(2.3.6名字的作用域)(2.3.7在变量的使用处定义变量)
- 生命周期,作用域的定义;说明全局变量、静态变量、局部变量、const变量的生命周期、作用域
- 生命周期,作用域的定义;说明全局变量、静态变量、局部变量、const变量的生命周期、作用域
- const、&在定义函数返回的作用及接收返回变量的类型
- “System.Data.DataSet”不包含“GetEnumerator”的公共定义,因此 foreach 语句不能作用于“System.Data.DataSet”类型的变量
- 【C++】关于变量在for循环内外定义的思考