尽管char类型被当作是整型,也就遵循整型的所有规则,但是我们一般不会像使用整形那样使用char类型。一个char类型占用了1byte的数据位。然而与将char类型解释成整型不同,我们需要将其解释成ASCII类型。
ASCII的意思是美国标准信息交互组织,它定义了一种特殊的方式来展示英文字符,将其表示成0·127.比如a表示97,b表示98.char通常用单引号表示‘。
|
其中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
其他特殊的如下:
\' 输出 '
\" 输出 “
\\ 输出 \
Name | Symbol | Meaning |
---|---|---|
Alert | \a | Makes an alert, such as a beep |
Backspace | \b | Moves the cursor back one space |
Formfeed | \f | Moves the cursor to next logical page |
Newline | \n | Moves cursor to next line |
Carriage return | \r | Moves cursor to beginning of line |
Horizontal tab | \t | Prints a horizontal tab |
Vertical tab | \v | Prints 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字符集来工作,如果用其他的字符集,可能会使代码出现问题。