小心visual studio的“BUG”:变量的声明和使用
昨天一Q友找我帮忙写个C程序:其中函数fun要实现:求出2000到2500之内能被7或者17或者27整除,但是不能同时被7和17整除,也不能同时被17和27整除的整数。题目倒是不难,遂打开visual studio,默默地写出下面的程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <stdio.h>
void fun(int *a, int *n)
{
int i = 2000, sum = 0;
for(;i<2501;i++)
{
if( (i%7==0 || i%17==0 || i%27==0) && (!(i%7==0 && i%17==0)) && (!(i%17==0 && i%27==0)) )
{
*a++ = i;
sum++;
}
}
/* 返回符合要求元素的个数 */
*n = sum;
}
int main()
{
int a[120];
int k;
fun(a,&k);
/* 使指针pt指向数组a的起始地址 */
int *pt = a;
for(;pt<a+120;pt++)
{
printf("%d\n",*pt);
}
printf("%d\n",k);
return 0;
}
|
然后ctrl+F5执行,结果很意外的报错了:
1>------ 已启动生成: 项目: test, 配置: Debug Win32 ------
1>生成启动时间为 2014/3/18 16:30:15。
1>InitializeBuildStatus:
1> 正在创建“Debug\test.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1> 1.c
1>g:\vsprj\test\test\1.c(23): error C2143: 语法错误 : 缺少“;”(在“类型”的前面)
1>g:\vsprj\test\test\1.c(24): error C2065: “pt”: 未声明的标识符
1>g:\vsprj\test\test\1.c(24): warning C4047: “<”:“int”与“int *”的间接级别不同
1>g:\vsprj\test\test\1.c(24): error C2065: “pt”: 未声明的标识符
1>g:\vsprj\test\test\1.c(26): error C2065: “pt”: 未声明的标识符
1>g:\vsprj\test\test\1.c(26): error C2100: 非法的间接寻址
1>
1>生成失败。
1>
1>已用时间 00:00:00.65
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
无奈,只能根据上面的错误信息一个一个排查了。但很显然,第23行的int *pt = a;前面不缺分号,另外pt也声明为指针了,所以整个程序应该是没错的。检查了好几遍还是没看出问题,估计是vs编译出错了,于是决定用cygwin编译器重新编译一下。win+r打开cmd命令窗口,输入编译命令gcc G:\VSprj\test\test\1.c -o 1
,然后直接执行1.exe。见证奇迹的时刻,竟然输出了数据。
回头想想,记得以前网上看过一个帖子,说是visual c++和visual studio对变量的声明要求特别严格,局部/全局变量一定要先声明在函数的最前面。于是把main函数中的指针pt声明调整到在fun函数的前面,再编译就没报错了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /**
* 使用指针和数组求2000到2500之内能被7或者17或者27整除,但是不能同时被7和17整除也不能同时被17和27整除的整数
* @author: vfhky 20140318 16:52
*/
#include <stdio.h>
void fun(int *a, int *n)
{
int i = 2000, sum = 0;
for(;i<2501;i++)
{
if( (i%7==0 || i%17==0 || i%27==0) && (!(i%7==0 && i%17==0)) && (!(i%17==0 && i%27==0)) )
{
*a++ = i;
sum++;
}
}
/* 返回符合要求元素的个数 */
*n = sum;
}
int main()
{
/* 用于保存符合要求的元素 */
int a[120];
int k;
/* 先声明指针变量pt */
int *pt;
fun(a,&k);
/* 再使指针pt指向数组a的起始地址 */
pt = a;
for(;pt<a+120;pt++)
{
/* 循环输出符合要求的元素 */
printf("%d\n",*pt);
}
/* 输出总共符合要求的元素的个数 */
printf("%d\n",k);
return 0;
}
|
虽然说vs对变量的使用比较“苛刻”,造成类似上面的“bug”,提供的错误信息“误导”了开发人员。但是细想之下,又觉得vs这种做法很“规范”:任何变量在使用之前必须先声明!而为了增强程序的可读性,也应该把声明语句尽量放在最前面!
打赏支持
Comments »