论坛: 编程破解 标题: 关于程序运行效率的问题 复制本贴地址    
作者: ice [benbear]    论坛用户   登录
小弟刚开始学习C,在看一段代码的时候,考虑到运行效率发现有另外一种思路。特在此将代码贴出,请大家看看哪种比较好,谢谢。
原思路:
代码:
#include <stdio.h>
#include <string.h>

int main()
{
FILE *fp;
char ch;
if((fp=fopen("a.txt","a"))==NULL)
printf("Open file error!\n");
ch=getchar();
while(ch!='\n')
{
fputc(ch,fp);
ch=getchar();
}
fclose(fp);
return 0;
}




我的思路:

代码:
#include <stdio.h>
#include <string.h>
#define MAX 1024

int main()
{
FILE *fp;
char code[MAX];
int lenth,i;
if((fp=fopen("a.txt","a"))==NULL)
printf("Open file error!\n");
printf("Enter the code:\n");
scanf("%s",code);
lenth=strlen(code);
for(i=0;i<lenth;i++)
fputc(code[i],fp);
fclose(fp);

return 0;
}





[此贴被 ice(benbear) 在 09月28日19时53分 编辑过]


[此贴被 ice(benbear) 在 09月28日19时55分 编辑过]

地主 发表时间: 06-09-28 19:51

回复: xiaoshi [xiaoshi]   论坛用户   登录
好久不看了,也没实际运行,只草草看了几眼,妄言几句

第一个程序,
ch=getchar();
  当getchar获得一个字符后,如何作为结束标记呢,如果不结束,那后面的循环如何开始,
如果是回车符号,那是不是当字符串结束的时候要输入两次回车呢?

第二个程序
  lenth=strlen(code);
for(i=0;i<lenth;i++)
我比较懒,直接把他写成一句
      for(i=0; i<(strlen(code));i++)
呵呵.我觉得定义的常量MAX实在没有必要,还不如直接写char code[1024],我想一维数组还不
难理解吧.

最后这个return 0;我没明白什么意思,见笑了.

B1层 发表时间: 06-09-28 23:11

回复: ice [benbear]   论坛用户   登录
原程序是以回车也就是'\n'结束输入的,另外定义常量MAX是为了修改的时候方便。现在就要养成这个好习惯哦~第二个你不明白的return 0;啊,你可以把它去掉再编译,你就知道为什么要有它了。可以到底哪个程序好还是不知道啊


[此贴被 ice(benbear) 在 09月29日09时26分 编辑过]

B2层 发表时间: 06-09-29 09:20

回复: kert_t8 [kert_t8]   论坛用户   登录
to 楼主:
我喜欢用scanf,但是后来别人(在CU上)告诉我其实用getchar是更好的方法,ND/syshunter写这种程序也都是用getchar()用的多,具体原因我还在参透中,应该是出于安全和可靠等方面的因素考虑。
你的scanf()会溢出,但是如果使用%1024s的方式来保证不溢出那么又不能使用定义的MAX(定义MAX的确是个好习惯),所以如果写成getchar()的形式就便于控制读入字符串的长度。我是这么理解的。

另外,直接用do{}while();就不用再循环体外投还要写一个ch=getchar(); 我比较喜欢好看的代码/:p


to 零下一度:
楼主的帖子改过了,我不知道他之前怎么写的,但是你对getchar()的理解好像不对

中间的i<(strlen(code))会在每次循环都执行一次,所以应该把strlen放在循环体外面。具体编译器是否会优化还是怎么样我不知道,但是有一次面试的时候面试官跟我说让我把这个东西写在循环外头的,我本来跟你是一个习惯

用return 0是因为他的main是int的


楼主学的挺细的麻,我也在学习中,有空交流 :) 加我qq

B3层 发表时间: 06-09-29 10:58

回复: NetDemon [netdemon]   ADMIN   登录
很明显,第一个程序的效率高,它每次循环就往文件中写入一字符,当用户结束输入的时候,文件也就已经写完,立刻执行的是fclose(fp);然后返回。
而第二个程序是当用户结束输入的时候,再来个for,把用户的输入内容由头到脚写到文件中。

基本上可以这样看,第一个程序,当用户按下回车,程序就已经完成。而第二个程序,当用户按下回车,程序才开始运行。


B4层 发表时间: 06-09-29 18:24

回复: xiaoshi [xiaoshi]   论坛用户   登录
都成门外人了


B5层 发表时间: 06-09-29 20:49

回复: windflower [windflower]   论坛用户   登录
楼主的意思是
  我打个字,就去麻烦一下CPU
  不如我打完了,再一次性麻烦它
OH YE MY GOD 是不是这样你说它的效率高些呀?

B6层 发表时间: 06-09-29 23:52

回复: ice [benbear]   论坛用户   登录
  我对ND说的那个“它每次循环就往文件中写入一字符,当用户结束输入的时候,文件也就已经写完”有疑问。看程序确实如你所说的直接写进文件,但是实际运行中是等我敲如了ERTER的时候再一起把所有字符从缓冲区写进文件的。那么这样和用循环把数组写进文件的效率应该没什么区别了吧。
    为什么不是输入一下就直接写进文件的呢是因为ANSI C中使用缓冲文件系统的原因吗?
    我的编译和运行环境是:WINXP SP1+VC6.0


[此贴被 ice(benbear) 在 09月30日08时30分 编辑过]


[此贴被 ice(benbear) 在 09月30日08时34分 编辑过]

B7层 发表时间: 06-09-30 08:27

回复: kert_t8 [kert_t8]   论坛用户   登录
关键还是getchar()的特性

你敲回车才写文件的原因不是因为缓冲,而是因为敲回车才由终端把输入的字符送给程序

scanf本身也是一个一个的读入字符,只是你看不到

你用scanf就相当于先用一个getchar的循环把字符全都写到变量里,然后再用一个循环把变量的字符一个一个的写入文件

B8层 发表时间: 06-09-30 10:29

回复: ice [benbear]   论坛用户   登录
哇!从一个小问题中学到了不少,本人受益匪浅。还是多思考的好。谢谢大家

B9层 发表时间: 06-09-30 17:21

回复: sniper167 [sniper167]   论坛用户   登录

看了你们的帖
我感觉自己都快成垃圾代码生成器了


[此贴被 啥都不会(sniper167) 在 09月30日21时29分 编辑过]

B10层 发表时间: 06-09-30 21:22

回复: NetDemon [netdemon]   ADMIN   登录
我那么说,只是为了更简单的让你明白这个所谓的效率问题,如果要说的非常严谨的话,那就要扯出一大堆东西来才行,实际的情况确实就是月之御者 [kert_t8]说的那样。因为getchar和scanf都是带缓冲的。
你可以用下面的程序,做一个无缓冲版本的getchar来做试验。
代码:

#include "syscalls.h"
int my_getchar(void)
{
    char c;
    return (read(0, &c, 1) == 1) ? (unsigned char c) c:EOF;
}


这样你可以看到我说的当你回车,文件就写好的效果,当然,这是在UNIX上的,Windows下我不知道就算这样,它是不是也给你缓冲了。
就算这样效率最高吧,但是实际应用中,是不会有这样的程序的,谁在实际中写出这样的程序,那说明他不适合写程序更适合耕田,因为这样的程序是不检查用户的输入,直接就往文件里写,
除非是用户名或密码可以这样,其他的信息这样做完全就是一个愚蠢的行为,但是用户名或密码这么几个字节的东西,需要用最高效率的程序来实现么?其实现实的情况就是你的第二个程序那样的,把输入读入内存,进行判断、过滤等,然后才写到文件中的。

在输入是用户终端这样的程序上讨论效率问题完全就是吃饱没事干的,你手指再快也快不过一个8086的CPU,能够一次打入的数据再多也多不过一个5寸的软盘的容量。


[此贴被 NetDemon(netdemon) 在 10月01日04时58分 编辑过]

B11层 发表时间: 06-10-01 04:55

回复: SysHu0teR [syshunter]   版主   登录
从终端读入字符串:
考虑效率确实如ND所说,没实际意义。
考虑健壮性的话,如月之御者 [kert_t8]所说的,如果单纯的scanf("%s",buf);很容易得到一个segmentation fault.所以要么scanf("%1024",buf),要么for(int i=0;i<MAX&&(c=getchar())!='\n') ;++i) buf[i]=c;
也许我这是个笨办法。

B12层 发表时间: 06-10-01 17:50

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号