Learning C++ 之 2.7 Chars

尽管char类型被当作是整型,也就遵循整型的所有规则,但是我们一般不会像使用整形那样使用char类型。一个char类型占用了1byte的数据位。然而与将char类型解释成整型不同,我们需要将其解释成ASCII类型。

ASCII的意思是美国标准信息交互组织,它定义了一种特殊的方式来展示英文字符,将其表示成0·127.比如a表示97,b表示98.char通常用单引号表示‘。

 

CodeSymbolCodeSymbolCodeSymbolCodeSymbol
0NUL (null)32(space)64@96`
1SOH (start of header)33!65A97a
2STX (start of text)3466B98b
3ETX (end of text)35#67C99c
4EOT (end of transmission)36$68D100d
5ENQ (enquiry)37%69E101e
6ACK (acknowledge)38&70F102f
7BEL (bell)3971G103g
8BS (backspace)40(72H104h
9HT (horizontal tab)41)73I105i
10LF (line feed/new line)42*74J106j
11VT (vertical tab)43+75K107k
12FF (form feed / new page)44,76L108l
13CR (carriage return)45-77M109m
14SO (shift out)46.78N110n
15SI (shift in)47/79O111o
16DLE (data link escape)48080P112p
17DC1 (data control 1)49181Q113q
18DC2 (data control 2)50282R114r
19DC3 (data control 3)51383S115s
20DC4 (data control 4)52484T116t
21NAK (negative acknowledge)53585U117u
22SYN (synchronous idle)54686V118v
23ETB (end of transmission block)55787W119w
24CAN (cancel)56888X120x
25EM (end of medium)57989Y121y
26SUB (substitute)58:90Z122z
27ESC (escape)59;91[123{
28FS (file separator)60<92\124|
29GS (group separator)61=93]125}
30RS (record separator)62>94^126~
31US (unit separator)63?95_127

DEL (delete)

 其中0~31表示不会被打印的字符,他们表示一种特殊的格式,其中现在大部分已经被废弃了。

31~127表示打印字符,表示一些符号,字母和标点符号等。

下面两种初始化方法都表示97:

char ch1(97); // initialize with integer 97
char ch2('a'); // initialize with code point for 'a' (97)

注意不要将字符数字与实际数字混淆,可以参照下面的例子:

char ch(5); // initialize with integer 5
char ch('5'); // initialize with code point for '5' (53)

打印字符:

当使用cout打印出字符的时候,实际输出的是字符,而不是其表示的具体数字:

#include <iostream>
 
int main()
{
    char ch(97); // even though we're initializing ch with an integer
    std::cout << ch; // cout prints a character
    return 0;
}

输出是:a

当然我们可以直接输出字符的字面值:

cout << 'b';

输出是:b

类型转换:

如果你想输出的值是数字,那么就需要通过类型转换来实现。如下面的例子:

#include <iostream>
 
int main()
{
    char ch(97);
    int i(ch); // assign the value of ch to an integer
    std::cout << i; // print the integer value
    return 0;
}

输出:97

但是这种使用方法不太好,一种比较好的方式是通过正规格式转换来实现:type cast。type cast可以把变量从一种类型转换成另外一种类型。在基本类型之间转换,我们可以使用static cast。

类型转换的语法有一点搞笑:

static_cast<new_type>(expression)

static_cast将expression中的值作为输入,然后转换成new_type。

下面的例子就是将字符型转换为整型:

#include <iostream>
 
int main()
{
    char ch(97);
    std::cout << ch << std::endl;
    std::cout << static_cast<int>(ch) << std::endl;
    std::cout << ch << std::endl;
    return 0;
}

代码输出依次为:  a     97     a

需要知道的是static_cast只是将值作为一个输入,然后将其转换成对应的新的类型,而对初始值是没有任何影响的。

static_cast没有做任何的类型安全检查,所以当你转换的类型字符数不够的时候,会发生溢出的错误。

后面我们还会讨论静态类型转换和不同类型的强制转换。

输入chars

下面的例子要求输入一个char类型,然后输出其ASCII码:

#include <iostream>
 
int main()
{
    std::cout << "Input a keyboard character: ";
 
    char ch;
    std::cin >> ch;
    std::cout << ch << " has ASCII code " << static_cast<int>(ch) << std::endl;
 
    return 0;
}

输出: q has ASCII code 113

尽管cin允许你输入多个字符,但是ch只会接受一个字符。因此只有一个字符会被收录,其他的会收录到cin的缓冲区中,等下一次调用。

可以参照下面的例子:

#include <iostream>
 
int main()
{
    std::cout << "Input a keyboard character: "; // assume the user enters "abcd" (without quotes)
 
    char ch;
    std::cin >> ch; // ch = 'a', "bcd" is left queued.
    std::cout << ch << " has ASCII code " << static_cast<int>(ch) << std::endl;
 
    // Note: The following cin doesn't ask the user for input, it grabs queued input!
    std::cin >> ch; // ch = 'b', "cd" is left queued.
    std::cout << ch << " has ASCII code " << static_cast<int>(ch) << std::endl;
    
    return 0;
}

输出:Input a keyboard character:abcd

          a has ASCII code 97

         b has ASCII code 98

char类型的size range 默认值

char类型在C++中都是一个byte的size。通常来说char可能是无符号的,也可能是有符号的定义,通常来说是signed。如果你用char类型来控制ASCII码值,你不需要特别强调sign,因为这个都是0~127的。

如果来保存小整型,那么一定要说明是否有符号。因为sign可定义为·128~127.unsigned则可以表示0~255.

转译符

C++中有很多特殊的符号有特殊的意义。这些符号叫做转译符,这些转译符通常以\开头,然后跟随一个字母。

最常见的转译符是\n,表示换行。

#include <iostream>
 
int main()
{
    std::cout << "First line\nSecond line" << std::endl;
    return 0;
}

输出为:First line

              Second line

另一个是\t表示tab。

#include <iostream>
 
int main()
{
    std::cout << "First part\tSecond part";
    return 0;
}

输出是First part    Second part

其他特殊的如下:

\'    输出  '

\"   输出  “

\\   输出 \

NameSymbolMeaning
Alert\aMakes an alert, such as a beep
Backspace\bMoves the cursor back one space
Formfeed\fMoves the cursor to next logical page
Newline\nMoves cursor to next line
Carriage return\rMoves cursor to beginning of line
Horizontal tab\tPrints a horizontal tab
Vertical tab\vPrints a vertical tab
Single quote\’Prints a single quote
Double quote\”Prints a double quote
Backslash\\Prints a backslash
Question mark\?Prints a question mark
Octal number\(number)Translates into char represented by octal

 

Hex number\x(number)Translates into char represented by hex number

 下面是一个例子:

#include <iostream>
 
int main()
{
    std::cout << "\"This is quoted text\"\n";
    std::cout << "This string contains a single backslash \\" << std::endl;
    std::cout << "6F in hex is char \'\x6F\'" << std::endl;
    return 0;
}

输出如下:

"This is quoted text"

This string contains a single backslash \

6F in hex is char 'o'

换行符应该用哪一个?\n  or std::endl

在最后一个例子中可以看到我们使用了\n来作为换行符,通常一般使用std::endl来实现该功能,这两种表示手法还是有一些不同的。

当使用std::cout的时候,输出是有缓存的,即std::cout并不会立即把输入给输出到屏幕上。相反,他会收集到一定量之后再来进行输出。这是为了性能考虑,有时大范围输入要比小范围输入性能要快一些。

\n和std::endl都会将光标移动到一行,但是std::endl会确保缓存完成之后再去还行。

所以这两种还行方式怎么用,简单总结如下:

  • 当你需要输入立即显示的时候,比如将记录写入文件,或者更新记录条,虽然这个会有性能问题,尤其是向设备写入速度较慢的情况下,会比较慢。
  • 其他情况用\n

双引号和单引号有什么区别

你之前学习到的char都是用单引号表示,一个单引号只能收集一个字符。下面的表示是非法的:

char ch('56'); // a char can only hold one symbol

使用双引号表示的是string类型,之前我们也接触过:

std::cout << "Hello, world!"; // "Hello, world!" is a string literal

string类型可以收集多个字符串,因为该类型比较复杂,后面还会深入讨论。

其他的char类型,wchar_t,char16_t,char32_t?

wchar_t 除了在windows中,其他场景都不要使用。它的大小是在执行的时候确定的,不可靠的,应该被丢弃。

就像ASCII将英文字符映射到整型上一样,其他国家的文字也需要映射到整型上。最知名的就是Unicode编码,需要映射110,000中整型来满足全球各种语言。因此就需要更多的位来保存,需要32位来保存,即UTF-32。然而,Unicode也可以用8位和16位的混合表示(分别叫UTF-8和UTF-16)。

所以char16_t  和 char32_t 新增到了C++中,用以表示16 bit和32 bit编码。

你一般不会需要使用到这两种类型,除非你想要做字符兼容。这两种类型并不在我们后续的教学计划中,因为只是在这里提一下。

当下,你应该使用ASCII字符集来工作,如果用其他的字符集,可能会使代码出现问题。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值