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,计算可以从中找到 ...
随机推荐
- Anacodna之conda与 virtualenv对比使用教程,创建虚拟环境
conda创建虚拟环境 1.查看包 conda list查看安装了哪些包 conda env list查看有哪些虚拟环境 conda -V查看conda的版本 2.创建虚拟环境,命名为myflaska ...
- linux与linux,linux与windows之间用SSH传输文件
linux与linux,linux与windows之间用SSH传输文件linux与linux之间传送文件:scp file username@hostIP:文件地址 例: scp abc.txt ...
- Windows下使用Git和GitHub.com
1.首先介绍一下什么是Git和GitHub Git是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大 ...
- 导入maven工程并配置maven环境
步骤一 : 选择 "Import"操作 有两个途径可以选择 "Import"操作; 1>"File"--> "Impo ...
- css中各种居中的奇技淫巧总结
css中各种居中的奇技淫巧总结 第一种,在固定布局中比较常用的技巧设置container的margin:0 auto: 第二种(从布局中入手) css .outer{ height:200 ...
- SQL、LINQ、Lambda 三种用法(转)
SQL.LINQ.Lambda 三种用法颜色注释: SQL LinqToSql Lambda QA1. 查询Student表中的所有记录的Sname.Ssex和Class列.select sname, ...
- SqlServer基础:Bit类型
SqlServer的bit类是只0或者1,默认不输入值时为null,但是如果输入的值不是0和1时,则默认填充的值为1
- [BS-05] init、initWithFrame和initWithCoder的区别
init.initWithFrame和initWithCoder的区别 1.Xib方式自定义UIView(指任意的UI控件) 使用Xib文件,就是我们所常用的“拖控件”的方式.如果我们使用了该方法创建 ...
- 第五篇 Integration Services:增量加载-Deleting Rows
本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...
- iOS 修改UITextField的placeholder属性的字体颜色(修改UITextField占位符字体的颜色)
只要把原来的placeholder属性改为attributedPlaceholder属性即可 具体代码如下图: