C语言初学者代码中的常见错误与瑕疵(1)
曾在豆瓣上看到过一个小朋友贴出他自己的代码(http://www.douban.com/group/topic/40293109/),当时随口指点了几句。难得这位小朋友虚心修正、从善如流,不断地改,又不断地贴,坚持了很久。到后来这位小朋友的代码已经大有长进。
这位小朋友犯过的很多错误都非常典型,在初学者中非常普遍,于是整理了一下,应该对其他初学者有借鉴意义。
问题
开灯问题
有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯编号。k≤n≤1000
代码:
#include <stdio.h>
#include <math.h> int main()
{
int a[],n,k,i,j; printf("请分别输入灯和人的数量\n");
scanf("%d%d",&n,&k); while() //检验是否超出
{
if(k>= && k<= && n>=k && n<=)
break;
else
{
printf("数值不符,请重新输入:\n");
scanf("%d%d",&n,&k);
}
} for(i=;i<=k;i++) //每操作一次第i*j个开关,a[i*j]加1
{
for(j=;i*j<=n;j++)
{
a[i*j]=a[i*j]+;
}
} for(i=;i<=n;i++) //若操作次数为偶数,表示该位置的灯亮着
{
if(a[i]%== && a[i]!=)
printf("%d\t",i);
} printf("\n");
return ;
}
测试:
“自己测了觉得没问题..在线系统结果是WrongAnswer ..未找出原因..”
评:
最明显的错误就是第26行
a[i*j]=a[i*j]+;
由于前面定义a数组为局部auto类别,在不进行初始化的情况下,a中的数据是垃圾值。换句话说,a中的数据是无意义的。因此a[i*j]+1这个表达式没有意义。
此外,第22行
for(i=;i<=k;i++) //每操作一次第i*j个开关,a[i*j]加1
在逻辑上也是错误的,缺乏“第1个人把所有灯打开”的步骤。
另外
printf("请分别输入灯和人的数量\n");
scanf("%d%d",&n,&k);
while() //检验是否超出
{
if(k>= && k<= && n>=k && n<=)
break;
else
{
printf("数值不符,请重新输入:\n");
scanf("%d%d",&n,&k);
}
}
这段写得很丑,属于典型的谭浩强风格,C语言应该这样写:
printf("请分别输入灯和人的数量\n");
while(scanf("%d%d",&n,&k) ,( k < || n<k || n>) )
{
printf("数值不符,请重新输入:\n");
}
代码中还有其他一些毛病,由于不是最主要的问题,这里就不再进一步指出了。
重构:
#include <stdio.h> #define MAXNUM 1000
#define ON 0
#define OFF 1 int main( void )
{
int light[MAXNUM] = { ON } ; //把所有灯打开
int n , k ;
int i ; printf( "请分别输入灯和人的数量\n" );
while ( scanf("%d%d", & n ,& k ) ,( k < || n < k || n > MAXNUM ) )
printf("数值不符,请重新输入:\n"); for ( i = - ; i < k ; i ++ ) //第2个人按下所有编号为2 的倍数的开关……
{
int j ;
for ( j = i ; j < n ; j += i + )
light[j] = ! light[j];
} for ( i = ; i < n ; i ++ )
if( light[i]==ON )
printf( "%d " , i + );
putchar('\n'); return ;
}
C语言初学者代码中的常见错误与瑕疵(1)的更多相关文章
- C语言初学者代码中的常见错误与瑕疵(23)
见:C语言初学者代码中的常见错误与瑕疵(23)
- 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)
问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...
- C语言初学者代码中的常见错误与瑕疵(5)
问题: 素数 在世博园某信息通信馆中,游客可利用手机等终端参与互动小游戏,与虚拟人物Kr. Kong 进行猜数比赛. 当屏幕出现一个整数X时,若你能比Kr. Kong更快的发出最接近它的素数答案,你将 ...
- C语言初学者代码中的常见错误与瑕疵(19)
见:C语言初学者代码中的常见错误与瑕疵(19)
- C语言初学者代码中的常见错误与瑕疵(14)
见:C语言初学者代码中的常见错误与瑕疵(14) 相关链接:http://www.anycodex.com/blog/?p=87
- 分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)
前文链接:分数的加减法——C语言初学者代码中的常见错误与瑕疵(11) 重构 题目的修正 我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要.只假设a, b ...
- C语言初学者代码中的常见错误与瑕疵(9)
题目 字母的个数 现在给你一个由小写字母组成字符串,要你找出字符串中出现次数最多的字母,如果出现次数最多字母有多个那么输出最小的那个. 输入:第一行输入一个正整数T(0<T<25) 随后T ...
- 要心中有“数”——C语言初学者代码中的常见错误与瑕疵(8)
在 C语言初学者代码中的常见错误与瑕疵(7) 中,我给出的重构代码中存在BUG.这个BUG是在飞鸟_Asuka网友指出“是不是时间复杂度比较大”,并说他“第一眼看到我就想把它当成一个数学问题来做”之后 ...
- C语言初学者代码中的常见错误与瑕疵(7)
问题: 矩形的个数 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3*1的矩形和1个3*2的矩形,总共18个矩形.给出A,B,计算可以从中找到 ...
随机推荐
- SQLSERER给表加自增列
alter table 表名 add 列名 int IDENTITY(1,1) NOT NULL
- MFC之目录结构及消息流转(一)
跟上时代,用vs2010, 新建一个MFC应用程序Helloworld. 目录结构: 所有文件分为6个部分:解决方案相关文件.工程相关文件.应用程序头文件和源文件.资源文件.预编译头文件和编译链接生成 ...
- python 内容查询小助手
点我,点我,python os.path 模块: 点我,点我,Python logging模块详解 点我,点我,python两个 list 获取交集,并集,差集的方法 点我,点我,python,my ...
- Tomcat Context配置(转)
<Context>元素的属性:path:指定访问该Web应用的URL入口.docBase:指定Web应用的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBas ...
- C# 英式日期插入Access数据库错误问题
插入数据库语句如下 string insertSql = string.Format("insert into info(MeasureIDID,Val,UpdateTime) select ...
- Cache封装类
代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...
- bootstrap学习之三—插件
一.模态框(modal)插件 1)为要触发模态框的组件添加data-toggle="modal",data-target="对应ID" 2)使用一个div实现m ...
- lua序列化(支持循环引用)
lua序列化 支持key类型为string, number 支持value类型为string, number, table, boolean 支持循环引用 支持加密序列化 支持loadstring反序 ...
- contenteditable
http://www.w3school.com.cn/tags/att_global_contenteditable.asp 做编辑器经常用这个属性 使得整个编辑区域所见所得 http://www.c ...
- devexpress13学习系列(一)PDFViewer(1)
使用这个组件,可以直接在winform里显示pdf文档,不需要另外装软件了. 有这么几个重要的属性: 1.DocumentFilePath:要读取的PDF的文件和路径. 2.CurrentPageNu ...