(C/C++学习笔记) 二. 数据类型

二. 数据类型

● 数据类型和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)一般划到基本类型里, 它不占存储空间

② 逻辑型又叫布尔型; bool数据的取值只能是false()true(); 在逻辑运算式中则把非0数据(一般是1)当成true, 0当成false

③ 类类型可归于派生类型(构造类型), 也可独立出来称为抽象数据类型;

④ 字符型从本质上说也是整数类型, 它是长度为1个字节的整数, 通常用来存放字符的ASCII.

⑤ 根据关键字修饰符(specifier)signed, unsigned, shortlong, 整型分为:

[signed] int        整型(即我们用得最多的int)

unsigned [int]        无符号整型

[signed] short [int]    有符号短整型

unsigned short [int]    无符号短整型

[signed] long [int]    有符号长整型

unsigned long [int]    无符号长整形

Note: ① 方括号中的signedint关键字可以省略; 例如shortshort intsigned shortsigned short int都是有符号短整型

② 字符型也有[signed] charunsigned 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;

}

 

 

● 各数据类型的相关说明(见附页

注意:

  1. int长度(存储空间)随系统的不同而不同,在16位系统下如DOS,其长度与短整型相同,占有16bit; 32位系统如LinuxUnixWindows NT系统下,长度为32bit; 64位系统下仍为32bit.
  2. 一般变量在X86和X64系统下长度没什么区别,只是指针从4字节变成了8字节,因为寻址范围从32位增加到了64位。
  3. %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.

  1. 精度(precision)包括整数与小数部分, 即数位(digits)。如3466.9778显示为3466.98(四舍五入).

⑤ 有的编译器如visual C++long double采用8字节存储。

  1. 空值型void用于描述没有返回值的函数以及通用指针类型。
  2. printf输出float型时,会自动转化成double
  3. C++中提供wchar_t类型,用于描述像汉字这样的大字符集。汉字字符集有简体字符集GB2312、繁体字符集Big5。在C++中,对于大字符集字符可用多个char类型的数据来实现,wchar_t类型主要用在国际化程序的实现中。
  4. 4294967295(四十多亿)32CPU寄存器以及VC6编译器所允许的最大正整数
  5. 格式占位符(%)是在C/C++语言中格式输入函数,如scanfprintf等函数中使用。其意义就是起到格式占位的意思,表示在该位置有输入或者输出。

 

● 变量和常量

变量: ① 整型变量; ② 实型变量; ③ 字符变量(注意: 没有字符串变量.)

常量: ① 整型常量; ② 实型常量; ③ 字符常量; ④ 字符串常量; ⑤其它常量, 包括:

  1. 布尔常量:

布尔常量只有两个true和false

2. 枚举常量;

enum 枚举类型名{常量1,常量2,常量3.......}

例如定义一个星期的枚举类型:enum Week { SUN, MON, TUE, ..., SAT }

这就定义了一个新的数据类型:Week

Week数据类型来源于int类型。

Week类型的数据只能有7种取值,它们是:SUN,MON,TUE, ..., SAT。如果没给各枚举常量指定值,其值依次默认为012、…;

其中SUN= 0,MON = 1,..., SAT = 6。也就是说,第1个枚举值代表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. 整型常量可以用后缀字母L(l)表示长整型, 后缀字母U(u)表示短整型, 也可以同时用后缀LU(大小写无关). 因为字母l容易与数字1混淆, 所以最好用大写字母. 例如:

 

1. 数的进制: 二进制数,八进制数(0),十进制数,十六进制数(0x)。程序中十进制数和十六进制数最为常见,八进制数很少见.

 

2. 整型常量后缀: 整型常量可以用后缀字母L(l)表示长整型, 后缀字母U(u)表示短整型, 也可以同时用后缀LU(大小写无关). 因为字母l容易与数字1混淆, 所以最好用大写字母. 例如:

74, 74L, 74LL, 74U, 74UL, 74ULL

 

3. 实现常量后缀:浮点常量包括小数形式(定点数)和科学计数形式(浮点数)

① 小数形式:

C/C++没有双精度的后缀, 不带后缀的实型数默认为双精度类型.

f或F(单精度浮点数)、lL(长双精度浮点数)。(注:因浮点型常数总是有符号的,故没有uU后缀). 例如:

1.23e5F; 1.23L; -123.45F。

② 科学计数形式:

数值1,Ee, 数值2

条件: 数值1必须存在,可以是十进制浮点型常量, 或基本整形常量; 数值2也必须存在且必须为正整数或负整数. 例如:

1.23E+4(等价于1.23E+4), 1.23E-4, 123E+4, 123E-4

※ 浮点型常量的整数部分为0, 0可以省略, 例如:-0.007可以写为-.007, -0.7E3可以写成-.7E3, △但是1.E7是非法的,

 

C/C++中各种类型intlongdoublechar取值范围

#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)来表示.

转义符形式1\字符助记符 character mnemonic [nɪˈmɒnɪk]

转义符形式2\字符的ASCII码值

※ 反斜杠\ (backslash)

 

C/C++中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符.

因为后面的字符,都不是它本来的ASCII字符意思了, 所以我们才称\0,\t,\n为转义字符。

 

注意: 

  1. \字符的ASCII码值的形式只能为为\ooo\xhh, 其中\ooo表示3位八进制数,\xhh表示2位十六进制数, 不能用十进制.

例如, 制表符table用第1种形式的转义序列表示为'\t'; 用第2种形式的转义序列表示为\011(可以省略开头的0, \11)\x09; \ooo中,ooo为不超过3位的八进制数字,可以不以0开头.

※ 记住几个特殊的ASCII码(用16进制表示):

空字符(0),换行符(0A),回车符(0D),空格(20),数字030),字母A41),字母a61)。

#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

    //不能在\后接十进制

}

 

 

 

'\2'也是字符常量,一字节长度,但它不是转义字符,而是8进制编码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.

 

⑤ 记住几个特殊的ASCII码(用16进制表示):

空字符(0),换行符(0A),回车符(0D),空格(20),数字030),字母A41),字母a61)。

 

⑥ 例:计算字符串"abc"的长度。(3

例:计算字符串"\\\'\054"的长度。(3)注意:分别有如下三个字符'\'(\\)、'''(\')和','(\054).

例:计算字符串"12\c"的长度。(3

 

 

  1. 特殊案例:

#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 )栈内存按字节全部填成 0xcc0xcc超过了ASCII0-127这个范围,因此"0xcccc..."这个"字符串"会被系统当成宽字符组成的字符串,而gbk内码0xcccc对应汉字"烫", 因此"0xcccc..."会生成一系列"烫烫烫..."(一个汉字字符占两个字节). 这样填充是为了防止越界访问的问题, 因为0xccint 3断点的机器码, 当内存被访问就会断下来.

※ 越界: 使用的内存空间超过了被分配的内存空间, 例如, 你明明申请的是100字节的空间,但是你由于某种原因写入了120字节,这就是内存访问越界。内存访问越界的后果是:你的写入破坏了本不属于你的空间。

 

2. 未初始化的堆内存会被全部填成 0xcd,而gbk内码0xcdcd对应汉字"屯".

 

※ 总之, 如果内存没初始化或者字符数组溢出就可能出现这种情况.

 

3. 内存被释放后free,操作系统(OS)会在被释放的内存中填入0xFEEEFEEEEEEFEEE..., gbk内码0xcdcd对应汉字"铪", 所以"0xFEEEFEEEEEEFEEE..."按字符串输出为"铪铪铪...".

1个字节包括8个二进制位

1个8进制位对应3个二进制位, 所以1个字节包括8/3个八进制位

1个16进制位对应4个二进制位, 所以1个字节包括8/4=2个十六进制位

 

※ 在 Release 模式下不会出现这些汉字,原来那块内存里是什么就输出什么.

 

※汇编语言中:

0xCC 是指令INT3(断点的一种)的机器码, 用来初始化栈中未被初始化的内存(按字节)

0xCD是清初内存 (Clean Memory)的机器码, 这里的内存指用mallocnew等关键字分配但从未被使用的空间.

0xFEEEFEEE用来标识(mark)被释放的内, 表示它们已经被操作系统回收了, 可以被再次分配.

 

4. Unicode和老编码体系的转化过程中,肯定有一些字,用Unicode是没法表示的,Unicode官方用了一个占位符来表示这些文字,这就是:U+FFFD REPLACEMENT CHARACTER

那么U+FFFDUTF-8编码出来,恰好是 '\xef\xbf\xbd'。如果这个'\xef\xbf\xbd',重复多次,例如 '\xef\xbf\xbd\xef\xbf\xbd',然后放到GBK的环境中显示的话,一个汉字2个字节,最终的结果就是:锟斤拷——锟(0xEFBF),斤(0xBDEF),拷(0xBFBD

 

 

打油诗: 手持两把锟斤拷,口中疾呼烫烫烫。脚踏千朵屯屯屯,笑看万物锘锘锘。

 

所有的转义字符及其对应的意义:

转义字符

意义

ASCII码值(十进制)

\a

响铃(BEL)

007

\b

退格(BS) ,将当前位置移到前一列

008

\f

换页(FF),将当前位置移到下页开头

012

\n

换行(LF) ,将当前位置移到下一行开头

010

\r

回车(CR) ,将当前位置移到本行开头

013

\t

水平制表(HT) (跳到下一个TAB位置)

009

\v

垂直制表(VT)

011

\\

代表一个反斜线字符''\'

092

\'

代表一个单引号(撇号)字符

039

\"

代表一个双引号字符

034

\?

代表一个问号

063

\0

空字符(NULL)

000

\ddd

1到3位八进制数所代表的任意字符

三位八进制

\xhh

1到2位十六进制所代表的任意字符

二位十六进制

 

 

转载于:https://www.cnblogs.com/ArrozZhu/p/8377572.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值