C语⾔字符型(char)及字符IO函数简介
⽬录
⼀、实验环境
Windows 10 系统
Visual Studio Community 2019
⼆、简介C语⾔字符
1、字符常量
“字符常量”通过在单引号 ('') 内包含单个字符来构成。例如:‘a’, ‘1’, ‘!’。字符可以是中的任何元素。
字符常量具有整数类型(integer type)。每个字符常量都被解释为其对应的ASCII码,如'a'在⼗进制和⼗六进制下分别为 97 和 61。常⽤的⼏个ASCII码:
字符值ASCII码 (⼗进制下 )
‘0’48
‘9’57
‘A’65
‘Z’90
‘a’97
‘z’122
2、字符变量
字符变量的类型说明符是char。每个字符变量占⽤⼀个字节的内存空间,存储字符常量的值(即ASCII码)。例如:
char ch ='a';//ch是字符变量,'a'是字符常量
char型和int型可以相互转换。当int型的变量转换成char型时,只取int型变量的低⼋位;当char型变量转换成int型时,以符号位的值补⾜成int型。
三、字符输⼊输出函数
1、使⽤scanf() 和 printf()
强⼤的格式化输⼊输出函数,可以⽤于字符的输⼊和输出。需要加⼊头⽂件#include<stdio.h>。
#define _CRT_SECURE_NO_WARNINGS//VS⾥不加这个会对scanf报错,说scanf涉及安全问题,我没有细看了
#include<stdio.h>
int main(void)
{
char ch;
scanf("%c",&ch);//⽤%c
printf("ch = '%c'",ch);//⽤%c
return0;
}
输出:
a //输⼊的字符
ch ='a'
2、使⽤getchar() 和 putchar()
作为知识补充,⾸先我们来看这样⼀个问题:c语言char的用法
C陷阱与缺陷 139页:
函数调⽤需要花费较长的程序执⾏时间,因此getchar经常被实现为宏。这个宏在stdio.h中定义,因此如果⼀个程序没有包含stdio头⽂件,编译器对getchar的定义⼀⽆所知。在这种情况下,编译器会假定getchar是⼀个返回类型为整型的函数。
实际上,很多C语⾔实现在库⽂件中都包括有getchar函数,忘记在程序中包含stdio头⽂件的效果就是在所有出现getchar宏的地⽅都⽤getchar函数调⽤来替换getchar宏。
总之我们需要知到:
1、getchar()和putchar() ⽐ scanf()和printf()函数实现简单,效率更⾼;
2、为了额外的效率提升,通常getchar()和putchar()都是作为宏来实现的。
当我们使⽤getchar()和putchar()的时候,通常需要包含头⽂件#include<stdio.h>。在stdio.h中有如下声明:
_Check_return_ _ACRTIMP int __cdecl getchar(void);
_Check_return_opt_ _ACRTIMP int __cdecl putchar(_In_ int _Character);
虽然看不懂,但还是能理解意思的,意思⼤概就是:
int getchar(void);
int putchar(int _Character);
1、getchar()
功能:从输⼊缓冲区读取⼀个字符,输⼊有回显。不需要提供参数,返回值是读取字符的ASCII码。
2、putchar()
功能:输出指定字符。需要提供⼀个参数,返回值是接收参数的ASCII码。
注意到这⾥putchar()接收参数的类型是int,⽽不是char,为什么呢?getchar()和putchar()返回值类型为什么是int⽽不是char呢?⽹上有说是为了兼容⽂件结束符EOF,有说是为了兼容ASCII码以外的字符,我就知到这么多了。
在平时的使⽤中,如果使⽤putchar()输出⼀个ASCII码编码的字符,那么给定参数可以是⼀个字符变量、字符常量(如’a’)、ASCII码值(0~127)。
#include<stdio.h>
int main(void)
{
char ch;
ch =getchar();//接收字符
putchar(ch);//字符变量
printf("\n");
putchar('b');//字符常量
printf("\n");
putchar(99);//ASCII码值
return0;
}
输出:
a //输⼊的字符,这⾥把输⼊的字符a显⽰出来,称为回显(敲击键盘上的字符a后,还要敲击Enter键)
a //字符变量
b //字符常量
c //ASCII码值(99)
3、使⽤getche()
功能:输⼊⼀个字符后会⽴即读取,不⽤等待⽤户按下回车键,输⼊有回显。
使⽤getche()需要加⼊头⽂件#include<conio.h>,在conio.h中有如下声明:
_Check_return_ _CRT_NONSTDC_DEPRECATE(_getche)
_DCRTIMP int __cdecl getche(void);
然⽽事情并⾮如同想象的⼀样顺利,在VS中,加⼊头⽂件conio.h后,getche()编译都过不去,代码如下:
#include<stdio.h>
#include<conio.h>
int main(void)
{
char ch;
ch =getche();
printf("\n");//⽤回车换⾏将回显和输出分开
putchar(ch);
return0;
}
报错如下:
error C4996:'getche': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _getche. See online help for details .
意思是getche()被弃⽤了,要使⽤C和C++⾥都⼀致的名字_getche()。
将上⾯代码中getche()改成_getche()就好了。(被弃⽤了怎么还有getche()的声明存在?原因我也没明⽩,下⾯将会更迷惑)
_getche()在头⽂件conio.h⾥的声明:
_Check_return_ _DCRTIMP int __cdecl _getche(void);
将上⾯代码getche()修改为_getche()后的输出:
a //输⼊回显
a //输出(当在键盘上敲击字符a后,⽴即输出)
让⼈更迷惑的是,不加头⽂件conio.h,使⽤getche()或者_getche()都可以过编译,也都可以正常运⾏。(上⾯不是说getche()被弃⽤了吗…)
#include<stdio.h>
//#include<conio.h>
int main(void)
{
char ch;
ch =getche();
//或者ch = _getche();
printf("\n");
putchar(ch);
return0;
}
编译器会给出warning:
'getche'未定义,假设外部返回int
运⾏正常(将getche()换成_getche()运⾏也⼀样):
a //输⼊回显
a //输出
我有限的知识与理解:C⾥⾯不声明函数的话,会有⼀个默认调⽤约定,返回值为int型的默认声明,
所以编译能过,但是有warning。在链接阶段,链接器默认链接libc,在libc⾥能到相应函数就能通过链接。如果不包含头⽂件conio.h,就没有getche()(或_getche())函数的声明。编译器会默认其有⼀个返回值为int的默认声明,在链接时,从libc中可以到函数getche()(或_getche()),故最终代码可以运⾏。
(为什么在加了头⽂件conio.h后,getche()反⽽不能⽤了?)
4、使⽤getch()和putch()
在头⽂件conio.h中声明。
1、getch()
声明:
_Check_return_ _CRT_NONSTDC_DEPRECATE(_getch)
_DCRTIMP int __cdecl getch(void);
功能:getch()与getche()功能相同,只是前者输⼊没有回显。
2、putch()
声明:
_Check_return_opt_ _CRT_NONSTDC_DEPRECATE(_putch)
_DCRTIMP int __cdecl putch(_In_ int _Ch);
功能:输出指定字符。需要提供⼀个参数,返回值是接收参数的ASCII码。
在上⾯的问题⼀样,当加⼊头⽂件conio.h时,编译器会报错提醒使⽤_getch()和_putch()。当不加⼊头⽂件conio.h时,编译器只会报warning,并且程序运⾏正常。
#include<stdio.h>
#include<conio.h>
int main(void)
{
char ch;
ch =_getch();
printf("\n");//⽤回车换⾏将回显和输出分开
_putch(ch);
return0;
输出:
//我敲击了字符a,但没有回显,这⾥是printf函数打印的\n
a //输出
四、总结
函数功能头⽂件平台getchar()有回显,输⼊需要敲击Enter键stdio.h可跨平台getche()有回显,输⼊⽆需敲击Enter键conio.h Windows getch()⽆回显,输⼊⽆需敲击Enter键conio.h Windows putchar()输出字符stdio.h可跨平台
putch()输出字符conio.h Windows putchar()和putch()的区别尚不清楚。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论