(原創) while(c = getch()) 为什么可以这样写? (C/C++) (C) (OS) (Linux)

凡是C语言的初学者,刚谈到简单的IO时,都会学到以下的程序,只要使用者输入什么,就印什么。

1 None.gif #include  < stdio.h >
2 None.gif
3 ExpandedBlockStart.gifContractedBlock.gif int  main()  dot.gif {
4InBlock.gif  char c;
5ExpandedSubBlockStart.gifContractedSubBlock.gif  while(c = getch()) dot.gif{
6InBlock.gif    printf("%c\n",c);
7ExpandedSubBlockEnd.gif  }

8ExpandedBlockEnd.gif}


当我第一次看到这种写法时,非常的震惊,马上改写成C#测试,当然连compile都不会过,为什么C语言可以这样写呢?若将以上程序改写一般语言的版本,就相当于如下的写法

 1 None.gif #include  < stdio.h >
 2 None.gif
 3 ExpandedBlockStart.gifContractedBlock.gif int  main()  dot.gif {
 4InBlock.gif  char c;
 5InBlock.gif
 6ExpandedSubBlockStart.gifContractedSubBlock.gif  while(1dot.gif{
 7InBlock.gif    c = getch();
 8InBlock.gif
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    if (c > 0dot.gif{
10InBlock.gif      printf("%c\n",c);
11ExpandedSubBlockEnd.gif    }

12ExpandedSubBlockStart.gifContractedSubBlock.gif    else dot.gif{
13InBlock.gif      break;
14ExpandedSubBlockEnd.gif    }

15ExpandedSubBlockEnd.gif  }

16ExpandedBlockEnd.gif}


如此就一目暸然了,可见C语言真的是语法很精简的语言,回到第一个程序,为什么while(c = getch())这种写法C语言接受呢?char c先得到getch()所传回的char型别,但在C语言,char型别和int是互通的,随即转为该字符所代表的ASCII值,任何一个字符的ASCII值均大于0,而在C语言『非0为true』的哲学下,即可进入while循环内,所以只要在键盘上敲入任何值,皆可随即印出来。在Visual C++,仍可接受『非0为true』的写法,但在g++,会出现warning: suggest parentheses around assignment used as truth value,也就是说,已经不建议『非0为true』的观念,而是要真的在while()中填入true或false,C#则是强烈要求如while(),if()在()中的判断式,必须一定要是true或false才行。不过C算是网开一面,只要加上()或手动将int转成bool即可,也就是改成while((c = getch()))或while((bool)(c = getch())) 即可,当加上()时, compiler还是会将()内的值依照『非0为true』转成ture或false。

完整的程序改法如下

1 None.gif #include  < stdio.h >
2 None.gif
3 ExpandedBlockStart.gifContractedBlock.gif int  main()  dot.gif {
4InBlock.gif  char c;
5InBlock.gif
6ExpandedSubBlockStart.gifContractedSubBlock.gif  while((c = getch())) dot.gif{
7InBlock.gif    printf("%c",c);
8ExpandedSubBlockEnd.gif  }

9ExpandedBlockEnd.gif}


以上的程序,无论拿到Visual C++或g++都无法compile,原因式getch()已经从<stdio.h>拔除了,只有在古老的compiler如Turbo C还能用,若在Visual C++,必须改成以下的写法。

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /* 
 2InBlock.gif(C) OOMusou 2006 http://oomusou.cnblogs.com
 3InBlock.gif
 4InBlock.gifFilename    : _getch.cpp
 5InBlock.gifCompiler    : Visual C++ 8.0
 6InBlock.gifDescription : Demo how to use _getch() & convert () to bool
 7InBlock.gifRelease     : 11/28/2006
 8ExpandedBlockEnd.gif*/

 9 None.gif
10 ExpandedBlockStart.gifContractedBlock.gif /**/ /* 
11InBlock.gif(C) OOMusou 2006 http://oomusou.cnblogs.com
12InBlock.gif
13InBlock.gifFilename    : conio__getch.cpp
14InBlock.gifCompiler    : Visual C++ 8.0
15InBlock.gifDescription : Demo how to use getch() in conio.h & convert 
16InBlock.gif
17InBlock.gif() to bool
18InBlock.gifRelease     : 11/28/2006
19ExpandedBlockEnd.gif*/

20 None.gif#include  < stdio.h >
21 None.gif#include  < conio.h >
22 None.gif
23 ExpandedBlockStart.gifContractedBlock.gif int  main()  dot.gif {
24InBlock.gif  char c;
25InBlock.gif
26ExpandedSubBlockStart.gifContractedSubBlock.gif  while((c = _getch())) dot.gif{
27InBlock.gif    printf("%c",c);
28ExpandedSubBlockEnd.gif  }

29ExpandedBlockEnd.gif}


直于g++,<stdio.h>也不提供getch()了,必须改用 <curses.h>。

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /* 
 2InBlock.gif(C) OOMusou 2006 http://oomusou.cnblogs.com
 3InBlock.gif
 4InBlock.gifFilename    : curses_getch.cpp
 5InBlock.gifCompiler    : gcc 4.1.0 on Fedora Core 5
 6InBlock.gifDescription  : Demo how to use getch() in curses & convert 
 7InBlock.gif
 8InBlock.gif() to bool
 9InBlock.gifRelease     : 11/28/2006
10ExpandedBlockEnd.gif*/

11 None.gif
12 None.gif#include  < curses.h >   //  use ncurses, initscr(), noecho(), getch(), 
13 None.gif
14 None.gifprintw(), endwin() 
15 None.gif#include  < stdlib.h >   //  exit(), EXIT_SUCCESS 
16 None.gif
17 ExpandedBlockStart.gifContractedBlock.gif int  main()  dot.gif {
18InBlock.gif  // Initialize curse scheme 
19InBlock.gif  initscr(); 
20InBlock.gif  // no echo in curse
21InBlock.gif  noecho(); 
22InBlock.gif
23InBlock.gif  char c; 
24ExpandedSubBlockStart.gifContractedSubBlock.gif  while(c = getch()) dot.gif
25InBlock.gif    printw("%c\n",c); 
26ExpandedSubBlockEnd.gif  }

27InBlock.gif
28InBlock.gif  // end curses scheme 
29InBlock.gif  endwin(); 
30InBlock.gif  exit(EXIT_SUCCESS); 
31ExpandedBlockEnd.gif}
 


curses的写法由于要想在Console提供图形接口,所以写法和一般传统的C语言有些差异。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值