二. 数据类型
● 数据类型和sizeof关键字(也是一个操作符)
※ 在现代半导体存储器中, 例如在随机存取存储器或闪存中, 位(bit)的两个值可以由存储电容器的两个层级的电荷表示(In modern semiconductor memory, such as dynamic random access memory or flash memory, the two values of a bit may be represented by two levels of electric charge stored in a capacitor). 用高电压(比如3.3V)代表1, 低电压(比如0V)代表0. |
C++数据类型的两种划分法:
注意: ① 空类型(void)一般划到基本类型里, 它不占存储空间 数据(一般是1)当成true, 把0当成false。 ③ 类类型可归于派生类型(构造类型), 也可独立出来称为抽象数据类型; 个字节的整数, 通常用来存放字符的ASCII码. ⑤ 根据关键字修饰符(specifier)signed, unsigned, short和long, 整型分为: [signed] int 整型(即我们用得最多的int型) unsigned [int] 无符号整型 [signed] short [int] 有符号短整型 unsigned short [int] 无符号短整型 [signed] long [int] 有符号长整型 unsigned long [int] 无符号长整形 Note: ① 方括号中的signed和int关键字可以省略; 例如short、short int、signed short、signed short int都是有符号短整型 ② 字符型也有[signed] char和unsigned char的区别 |
#include <iostream> //头文件引用 using namespace std; //命名空间的引用 int main() { cout << sizeof (char) << endl; int a = sizeof (int); cout << a << endl; int b=1; cout<<"sizeof(b) is: "<<sizeof(b)<<endl; cout<<"sizeof(\"OK!OK!\") is: "<<sizeof("OK!OK!")<<endl; //注意转义符\" return 0; } |
● 各数据类型的相关说明(见附页)
注意:
- int长度(存储空间)随系统的不同而不同,在16位系统下如DOS,其长度与短整型相同,占有16bit; 在32位系统如Linux、Unix、Windows NT系统下,长度为32bit; 在64位系统下仍为32bit.
- 一般变量在X86和X64系统下长度没什么区别,只是指针从4字节变成了8字节,因为寻址范围从32位增加到了64位。
- %Lf和%lf是有区别的:
For printf(), the "%lf" is not valid -- it should be "%f".
For scanf(), it makes all the difference in the world -- use "%f" for float, "%lf" for double, and "%Lf" for long double.
- 精度(precision)包括整数与小数部分, 即数位(digits)。如3466.9778显示为3466.98(四舍五入).
⑤ 有的编译器如visual C++对long double采用8字节存储。
- 空值型void用于描述没有返回值的函数以及通用指针类型。
- printf输出float型时,会自动转化成double型
- C++中提供wchar_t类型,用于描述像汉字这样的大字符集。汉字字符集有简体字符集GB2312、繁体字符集Big5。在C++中,对于大字符集字符可用多个char类型的数据来实现,wchar_t类型主要用在国际化程序的实现中。
- 4294967295(四十多亿)是32位CPU寄存器以及VC6编译器所允许的最大正整数
- 格式占位符(%)是在C/C++语言中格式输入函数,如scanf、printf等函数中使用。其意义就是起到格式占位的意思,表示在该位置有输入或者输出。
● 变量和常量
变量: ① 整型变量; ② 实型变量; ③ 字符变量(注意: 没有字符串变量.) 常量: ① 整型常量; ② 实型常量; ③ 字符常量; ④ 字符串常量; ⑤其它常量, 包括:
布尔常量只有两个—true和false 2. 枚举常量; ,常量2,常量3,.......}; 例如定义一个星期的枚举类型:enum Week { SUN, MON, TUE, ..., SAT }; 这就定义了一个新的数据类型:Week。 Week数据类型来源于int类型。 种取值,它们是:SUN,MON,TUE, ..., SAT。如果没给各枚举常量指定值,其值依次默认为0、1、2、…; 个枚举值代表0,第2个枚举值代表1,这样依次递增1。 枚举值,我们也称其为枚举常量,因为它一经定义以后,就不可再改变. 3. 符号常量(宏定义常量): #define PI 3.14 //PI就是符号常量 ※ "字面常量"的概念: 字面常量 包括:整形常量,字符型常量,字符串常量。 注意: 不存在 数组常量、结构体常量等结构型的 字面常量 。但是存在 结构型的符号常量, 如: #define STU struct stu STU { int num; char name[20]; char sex; float score; }; STU boy1,boy2; |
● 数的进制 & 数的后缀
1. 数的进制: 二进制数,八进制数(0),十进制数,十六进制数(0x)。程序中十进制数和十六进制数最为常见,八进制数很少见. 混淆, 所以最好用大写字母. 例如: 74, 74L, 74LL, 74U, 74UL, 74ULL 3. 实现常量后缀:浮点常量包括小数形式(定点数)和科学计数形式(浮点数)。 ① 小数形式: C/C++没有双精度的后缀, 不带后缀的实型数默认为双精度类型. f或F(单精度浮点数)、l或L(长双精度浮点数)。(注:因浮点型常数总是有符号的,故没有u或U后缀). 例如: 1.23e5F; 1.23L; -123.45F。 ② 科学计数形式: 必须存在,可以是十进制浮点型常量, 或基本整形常量; 数值2也必须存在且必须为正整数或负整数. 例如: 1.23E+4(等价于1.23E+4), 1.23E-4, 123E+4, 123E-4 时, 该0可以省略, 例如:-0.007可以写为-.007, -0.7E3可以写成-.7E3, △但是1.E7是非法的, |
● C/C++中各种类型int、long、double、char取值范围
#include<iostream> #include<string> #include <limits> using namespace std; int main() { cout << "type: \t\t" << "************size**************"<< endl; cout << "bool: \t\t" << "所占字节数:" << sizeof(bool); cout << "\t最大值:" << (numeric_limits<bool>::max)(); cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl; cout << "char: \t\t" << "所占字节数:" << sizeof(char); cout << "\t最大值:" << (numeric_limits<char>::max)(); cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl; cout << "signed char: \t" << "所占字节数:" << sizeof(signed char); cout << "\t最大值:" << (numeric_limits<signed char>::max)(); cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl; cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char); cout << "\t最大值:" << (numeric_limits<unsigned char>::max)(); cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl; cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t); cout << "\t最大值:" << (numeric_limits<wchar_t>::max)(); cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl; cout << "short: \t\t" << "所占字节数:" << sizeof(short); cout << "\t最大值:" << (numeric_limits<short>::max)(); cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl; cout << "int: \t\t" << "所占字节数:" << sizeof(int); cout << "\t最大值:" << (numeric_limits<int>::max)(); cout << "\t最小值:" << (numeric_limits<int>::min)() << endl; cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned); cout << "\t最大值:" << (numeric_limits<unsigned>::max)(); cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl; cout << "long: \t\t" << "所占字节数:" << sizeof(long); cout << "\t最大值:" << (numeric_limits<long>::max)(); cout << "\t最小值:" << (numeric_limits<long>::min)() << endl; cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long); cout << "\t最大值:" << (numeric_limits<unsigned long>::max)(); cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl; cout << "double: \t" << "所占字节数:" << sizeof(double); cout << "\t最大值:" << (numeric_limits<double>::max)(); cout << "\t最小值:" << (numeric_limits<double>::min)() << endl; cout << "long double: \t" << "所占字节数:" << sizeof(long double); cout << "\t最大值:" << (numeric_limits<long double>::max)(); cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl; cout << "float: \t\t" << "所占字节数:" << sizeof(float); cout << "\t最大值:" << (numeric_limits<float>::max)(); cout << "\t最小值:" << (numeric_limits<float>::min)() << endl; cout << "size_t: \t" << "所占字节数:" << sizeof(size_t); cout << "\t最大值:" << (numeric_limits<size_t>::max)(); cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl; cout << "string: \t" << "所占字节数:" << sizeof(string) << endl; // << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl; cout << "type: \t\t" << "************size**************"<< endl; return 0; } |
● 字符型数据
字符数是用英文单引号括起来的一个字符。如:'a','A'等。 有些ASCII码字符如回车、退格等不能直接用在用单引号中。这些数据可用转义序列(escape sequence)来表示. :\字符助记符 character mnemonic [nɪˈmɒnɪk] :\字符的ASCII码值 ※ 反斜杠\ (backslash) ※ C/C++中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符. 因为后面的字符,都不是它本来的ASCII字符意思了, 所以我们才称\0,\t,\n为转义字符。 注意:
种形式的转义序列表示为'\t'; 用第2种形式的转义序列表示为\011(可以省略开头的0, 即\11)或\x09; 在\ooo中,ooo为不超过3位的八进制数字,可以不以0开头. 进制表示): ),换行符(0A),回车符(0D),空格(20),数字0(30),字母A(41),字母a(61)。 #include<stdio.h> main() { printf("%c%c\n", '\t', 'A'); printf("%c%c\n", '\011', 0101); //八进制的ASCII码 printf("%c%c\n", '\11', 0101); //八进制的ASCII码 printf("%c%c\n", '\x09', 0x41); //十六进制的ASCII码 printf("%c%c\n", '\x9', 0x41); //十六进制的ASCII码 //不能在\后接十进制 } 进制编码002 代表的ascii字符2的值,例如: #include <stdio.h> int main() { putchar('\2'); putchar('\n'); putchar('\002'); putchar('\n'); return 0; } 结果相同,即两个笑脸,它们是不可打印的字符,代表STX (start of text),正文开始。 ③ 字符型数据可以当作整型使用,其数值就是ASCII编码值, 例如: #include<stdio.h> main() { char c; c='A'+'6'-3; //字符'A'的ASCII码是65, 字符'6'的ASCII码是54, 3是普通数据 printf("%c\n", c); printf("%d\n", c); } ④ 非转义字符加"\"即原字符,如'\c'表示字符c; 转义符"\0"比较特殊,因为它对应的ASCII码也是0. 进制表示): ),换行符(0A),回车符(0D),空格(20),数字0(30),字母A(41),字母a(61)。 ) )注意:分别有如下三个字符'\'(\\)、'''(\')和','(\054). )
#include <iostream.h> int main() { cout<<"\x46\x09\x3b\x0d\x0a"; cout<<"\x46\x09\x3b\x0a"; cout<<"\xcd\xcd\xcd\xcd"<<endl; //\x46--F; \x09--水平制表符; \x3b--分号; \x0d--回车键; \x0a--换行 //在VC++ 6.0中, \x0d\x0a相当于\x0a, 但是不能单写\x0d表示换行 } ※ 有关屯屯屯, 烫烫烫, 铪铪铪, 锟斤拷 1. 在Debug 模式下,VC++会默认把未初始化的(uninitialized )栈内存按字节全部填成 0xcc,0xcc超过了ASCII码0-127这个范围,因此"0xcccc..."这个"字符串"会被系统当成宽字符组成的字符串,而gbk内码0xcccc对应汉字"烫", 因此"0xcccc..."会生成一系列"烫烫烫..."(一个汉字字符占两个字节). 这样填充是为了防止越界访问的问题, 因为0xcc是int 3断点的机器码, 当内存被访问就会断下来. 字节的空间,但是你由于某种原因写入了120字节,这就是内存访问越界。内存访问越界的后果是:你的写入破坏了本不属于你的空间。 2. 未初始化的堆内存会被全部填成 0xcd,而gbk内码0xcdcd对应汉字"屯". ※ 总之, 如果内存没初始化或者字符数组溢出就可能出现这种情况. 3. 内存被释放后free,操作系统(OS)会在被释放的内存中填入0xFEEEFEEEEEEFEEE..., 而gbk内码0xcdcd对应汉字"铪", 所以"0xFEEEFEEEEEEFEEE..."按字符串输出为"铪铪铪...". 个字节包括8个二进制位 进制位对应3个二进制位, 所以1个字节包括8/3个八进制位 进制位对应4个二进制位, 所以1个字节包括8/4=2个十六进制位 ※ 在 Release 模式下不会出现这些汉字,原来那块内存里是什么就输出什么. ※汇编语言中: 0xCC 是指令INT3断(断点的一种)的机器码, 用来初始化栈中未被初始化的内存(按字节) 0xCD是清初内存 (Clean Memory)的机器码, 这里的内存指用malloc或new等关键字分配但从未被使用的空间. 0xFEEEFEEE用来标识(mark)被释放的内, 表示它们已经被操作系统回收了, 可以被再次分配. 4. Unicode和老编码体系的转化过程中,肯定有一些字,用Unicode是没法表示的,Unicode官方用了一个占位符来表示这些文字,这就是:U+FFFD REPLACEMENT CHARACTER。 个字节,最终的结果就是:锟斤拷——锟(0xEFBF),斤(0xBDEF),拷(0xBFBD) 打油诗: 手持两把锟斤拷,口中疾呼烫烫烫。脚踏千朵屯屯屯,笑看万物锘锘锘。 |
所有的转义字符及其对应的意义:
转义字符 |
意义 |
ASCII码值(十进制) |
\a |
响铃(BEL) |
|
\b |
退格(BS) ,将当前位置移到前一列 |
|
\f |
换页(FF),将当前位置移到下页开头 |
|
\n |
换行(LF) ,将当前位置移到下一行开头 |
|
\r |
回车(CR) ,将当前位置移到本行开头 |
|
\t |
水平制表(HT) (跳到下一个TAB位置) |
|
\v |
垂直制表(VT) |
|
\\ |
代表一个反斜线字符''\' |
|
\' |
代表一个单引号(撇号)字符 |
|
\" |
代表一个双引号字符 |
|
\? |
代表一个问号 |
|
\0 |
空字符(NULL) |
|
\ddd |
1到3位八进制数所代表的任意字符 |
三位八进制 |
\xhh |
1到2位十六进制所代表的任意字符 |
二位十六进制 |