凡是C语言的初学者,刚谈到简单的IO时,都会学到以下的程序,只要使用者输入什么,就印什么。
1
#include
<
stdio.h
>
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
int
main()
{
4
char c;
5![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while(c = getch())
{
6
printf("%c\n",c);
7
}
8
}
当我第一次看到这种写法时,非常的震惊,马上改写成C#测试,当然连compile都不会过,为什么C语言可以这样写呢?若将以上程序改写一般语言的版本,就相当于如下的写法
1
#include
<
stdio.h
>
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
int
main()
{
4
char c;
5![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while(1)
{
7
c = getch();
8![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (c > 0)
{
10
printf("%c\n",c);
11
}
12![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
13
break;
14
}
15
}
16
}
如此就一目暸然了,可见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
#include
<
stdio.h
>
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
int
main()
{
4
char c;
5![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while((c = getch()))
{
7
printf("%c",c);
8
}
9
}
以上的程序,无论拿到Visual C++或g++都无法compile,原因式getch()已经从<stdio.h>拔除了,只有在古老的compiler如Turbo C还能用,若在Visual C++,必须改成以下的写法。
1
/**/
/*
2
(C) OOMusou 2006 http://oomusou.cnblogs.com
3![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
Filename : _getch.cpp
5
Compiler : Visual C++ 8.0
6
Description : Demo how to use _getch() & convert () to bool
7
Release : 11/28/2006
8
*/
9
![None.gif](/Images/OutliningIndicators/None.gif)
10
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**/
/*
11
(C) OOMusou 2006 http://oomusou.cnblogs.com
12![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
Filename : conio__getch.cpp
14
Compiler : Visual C++ 8.0
15
Description : Demo how to use getch() in conio.h & convert
16![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
17
() to bool
18
Release : 11/28/2006
19
*/
20
#include
<
stdio.h
>
21
#include
<
conio.h
>
22
![None.gif](/Images/OutliningIndicators/None.gif)
23
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
int
main()
{
24
char c;
25![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
26![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while((c = _getch()))
{
27
printf("%c",c);
28
}
29
}
直于g++,<stdio.h>也不提供getch()了,必须改用 <curses.h>。
1
/**/
/*
2
(C) OOMusou 2006 http://oomusou.cnblogs.com
3![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
Filename : curses_getch.cpp
5
Compiler : gcc 4.1.0 on Fedora Core 5
6
Description : Demo how to use getch() in curses & convert
7![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
8
() to bool
9
Release : 11/28/2006
10
*/
11
![None.gif](/Images/OutliningIndicators/None.gif)
12
#include
<
curses.h
>
//
use ncurses, initscr(), noecho(), getch(),
13
14
printw(), endwin()
15
#include
<
stdlib.h
>
//
exit(), EXIT_SUCCESS
16
17
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
int
main()
{
18
// Initialize curse scheme
19
initscr();
20
// no echo in curse
21
noecho();
22![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
23
char c;
24![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while(c = getch())
{
25
printw("%c\n",c);
26
}
27![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
28
// end curses scheme
29
endwin();
30
exit(EXIT_SUCCESS);
31
}
curses的写法由于要想在Console提供图形接口,所以写法和一般传统的C语言有些差异。