C语言字符型(char)及字符I/O函数简介

一、实验环境

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
	
	return 0;
}

输出:

a	//输入的字符
ch = 'a'

2、使用getchar() 和 putchar()

作为知识补充,首先我们来看这样一个问题:getchar() 和 putchar()是宏还是函数?

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码值
    
    return 0;
}

输出:

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);

    return 0;
}

报错如下:

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);

    return 0;
}

编译器会给出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);

    return 0;

输出:

	//我敲击了字符a,但没有回显,这里是printf函数打印的\n
a	//输出

四、总结

函数功能头文件平台
getchar()有回显,输入需要敲击Enter键stdio.h可跨平台
getche()有回显,输入无需敲击Enter键conio.hWindows
getch()无回显,输入无需敲击Enter键conio.hWindows
putchar()输出字符stdio.h可跨平台
putch()输出字符conio.hWindows

putchar()和putch()的区别尚不清楚。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值