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,计算可以从中找到 ...
随机推荐
- Ubuntu-1404 GDB 调试C++报错
问题 Ubuntu1404下,当用GDB调试C++程序时,报错ImportError: No module named 'libstdcxx' 解决办法 vim ~/.gdbinit #~/.gdbi ...
- 【Algorithm】堆排,C++实现
对一个数组中的元素按照顺序构建二叉树,就形成了一个(二叉)堆.(二叉树是虚拟的,并不是真的建立二叉树) 表示堆的数组A有两个重要属性:A.heapSize,表示堆里面有多少元素,数组里有多少元素在堆里 ...
- CXF入门例子
1. WebService实现类:@WebService注解表示这个类发布为一个WebService服务. package com.coshaho.learn.cxf; import javax.jw ...
- http://blog.csdn.net/rongyongfeikai2/article/details/41659353
http://blog.csdn.net/rongyongfeikai2/article/details/41659353
- thinkphp文章列表及删除文章
出师不利,数据一次删完了... 教程:http://www.thinkphp.cn/topic/9757.html 首先要构造mysql数据库 模板代码 </head> <body& ...
- java中清空session
session.removeAttribute("sessionname")是清除SESSION里的某个属性. session.invalidate()是让SESSION失 ...
- MVC 读书笔记
一.路由 1.HttpApplication中的ASP.NET MVC .Net 3.5 引入了System.Web.Routing程序集,通过Url Routing的机制,可以实现将一个虚拟路径的请 ...
- iOS 归档
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...
- nodejs weixin 笔记
http://www.oschina.net/code/snippet_218887_25870 好文章: http://codelife.me/blog/2013/04/23/developing- ...
- ios-消息弹框之UIAlertView, UIActionSheet以及UIAlertController小结
首先storyboard中创建对应按钮并拖线,来演示不同的效果 首先点击了actionSheet按钮效果如图 实现弹框需要遵守设置代理,遵守协议. 效果就是从底部向上弹起来的框框. 通过对按钮的点击输 ...