C++数据类型
一 基本类型
基本类型又分整型和浮点型
1. 整型
宽度用于描述存储整数时使用的内存量。使用内存越多,则越宽
C++的基本整型 char, short, int, long, 以及C++11新增的long long其中每种类型又有有符号和无符号之分,因此一共10种
(1) char, short, int, long, long long
计算机内存的基本单元是位(bit)
字节(byte)指的是描述计算机内存量的度量单位。
C++确保了最小长度
a.
short 至少16位
int 至少与short一样长
long至少32位,且至少与int一样长
long long 至少64位,且至少与long一样长
b. sizeof 运算符返回类型或者变量的长度,单位字节
头文件climits(老式实现中为limits.h)包含了整型限制的信息. INT_MAX为int的最大取值,CHAR_BIT为字节的位数。
#include <iostream>
#include<climits>
using namespace std;
int main()
{
std::cout << "Hello World!\n";
int nint = INT16_MAX; //2^16 /2
int nint32 = INT32_MAX; //2^32/2
int nint1 = INT_MAX; //2^32/2
short nshort = SHRT_MAX; //2^16 /2
long nlong = LONG_MAX; //2^32/2
long long nll = LLONG_MAX; //2^64/2
cout << "int is " << sizeof(int) << endl;
cout << "short is " << sizeof(short) << endl;
cout << "long is " << sizeof(long) << endl;
cout << "long long is " << sizeof(long long) << endl;
cout << "max value" << endl;
cout << "INT16_MAX is " << nint << endl;
cout << "INT32_MAX is " << nint32 << endl;
cout << "INT_MAX is " << nint1 << endl;
cout << "SHRT_MAX is " << nshort << endl;
cout << "LONG_MAX " << nlong << endl;
cout << "LLONG_MAX is " << nll<< endl;
}
climits中的符号常量
c. 无符号类型
short表示范围:—32768 到32767,无符号则0~65535
unsigned 本身是unsigned int 的缩写
超越整形限制的后果
#include <iostream>
#include<climits>
#define ZERO 0
using namespace std;
int main()
{
short sam = SHRT_MAX; // 32767
unsigned short sue = sam;
cout << "sam is :" << sam << endl; // 32767
cout << "sue is :" << sue << endl; // 32767
cout << "add 1 :" << endl;
sam += 1;
sue += 1;
cout << "sam is :" << sam << endl; // -32768
cout << "sue is :" << sue << endl;// 32768
sam = ZERO;
sue = ZERO;
cout << "add -1 :" << endl;
sam -= 1;
sue -= 1;
cout << "sam is :" << sam << endl; //-1
cout << "sue is :" << sue << endl; //65535
}
原因如下:
int 是计算机处理起来效率最高的长度。
通常仅当有大型整型数组,才使用short。(将程序从int16位的系统中移到int 32 的系统,则存储int的内存量将加倍)
cout<<hex 十六进制 oct八进制 dec十进制
C++一般将常量存为int除非特殊情况。
89ul 或者89uL表示无符号long
u表示无符号int
ull, ULL,uLL,Ull.
(2)char
char类型是专门存储字符(字母和数字)而设计的。
int main()
{
char ch;
cin >> ch;
cout << "input is " << ch << endl;
}
输入M,则cin将M转为77,输出时cout将77转为M
eg:
#include <iostream>
using namespace std;
int main()
{
char ch='M';
int i = ch;
cout << "the ascii code for " << ch <<" is "<<i<< endl;
cout << "add 1" << endl;
ch = ch + 1;
i = ch;
cout << "the ascii code for " << ch << " is " << i << endl;
cout.put('!');//该函数显示一个字符
}
char 字面值
‘A’ 65
C++转义序列编码
eg
#include <iostream>
using namespace std;
int main()
{
cout << "\aoperation \"Hyperype\" is now activated!\n";
cout << "Enter your agent code __________\b\b\b\b\b\b\b\b";
long code;
cin >> code;
cout << "\aYou entered" << code<< "...\n";
cout << "\acode verified! Proceed with Plan z3!\n";
return 0;
}
注意:char在默认情况下,既不是有符号,也不是无符号的。可根据需要显示设定signed char 或unsigned char
w_char
若程序需要处理的字符集无法用一个8位的字节表示,如日文汉字系统。C++处理方式有两种。
1.如果大型字符集是实现的基本字符集,则编译器厂商可以将char定义为一个16位的字节或更长的字节。
2.一种实现可以同时支持一个小型基本字符集和一个较大的扩展字符集。8位char表示基本字符集,另一种wchar_t表示扩展字符集。
cin和cout不能处理wchar_t
#include <iostream>
using namespace std;
int main()
{
wchar_t bob = L'w';
wcout << bob << endl;
wcout << L"tall" << endl;
return 0;
}
上述代码将每个字符存在一个两个字节的内存单元中。(Unicode使用)
C++11新增char16_t和char32_t前者是无符号的,长16位,后者无符号,长32位。
使用u表示char16_t
U表示char32_t
bool
布尔变量 可以为true 和false。(非零为true,0为false)
true 和false都可以提升为int。
另外任何指针值,数字值都可以隐式转为bool值
bool bint = -100; true;
bool ba = 0; // false.
2.浮点型
浮点型能表示带小数部分的数字。计算机将浮点数分为两部分存储,一部分表示值,另一部分用于对值进行放大缩小。(常见的是缩小放大10的倍数,C++的缩放因子是2的次幂,计算机以二进制存储)。浮点数能够表示小数值,非常大和非常小的值。
两种书写方式
(1)标准小数点
12.34
(2)E表示法(适合非常大和非常小的数)
2.5e6,e6指10的6次方,即1后面6个0。 6称为指数,3.45称为尾数。
注意:数字中不能有空格,6可正可负。
浮点类型:
C++有3种浮点型:float,double,long double 这些类型是按它们可以表示的有效数位和允许的指数的最小范围来描述的。有效位是数字中有意义的位。
14179 有效位 5
14.179 有效位 5
14000 有效位 2
C++和C对有效位数的要求,float至少32位,double 至少48位,且不少于float ,long double至少和double 一样多。这三种类型的有效位数可以一样多。然而通常 float 32位,double 64 位,long double 80,96,或者128位。另外这三种类型的指数范围至少-37~37.可以从cfloat或float.h中找到系统的限制。
#include <iostream>
using namespace std;
int main()
{
std::cout << "Hello World!\n";
cout.setf(ios_base::fixed, ios_base::floatfield); //以定点表示法显示,防止用e表示法
float tub = 10.0 / 3.0;
double mint = 10.0 / 3.0;
const float milion = 1.0e6;
cout << "tub = " << tub;
cout << " ,a million tub = " << milion * tub << endl;
cout << " and ten million tub = " << 10 * milion * tub << endl;
cout << "mint = " << mint;
cout << " ,a million mint = " << milion * mint << endl;
}
输出:
说明:通常cout会删除结尾的0,将3333.250000显示为3.25 。使用cout.setf()将覆盖这种行为。
float精度比double低,刚开始两者一样,但*1000000后,tub在7位有效位是精确的(该系统确保了float至少6个有效位)
double至少13位是精确的(系统确保15位)
浮点常量
默认情况下8.24或者2.4E8都为double
用f或F后缀,则float
l或L则long double
优缺点:1.可以表示整数值 2. 有缩放因子,可以表示的范围大。
缺点:浮点数的运算速度比整数运算慢,且精度将降低。
eg:
#include <iostream>
using namespace std;
int main()
{
float a = 23.4e22f;
float b = a + 1.0f;
cout << "a= " << a << endl;
cout << "b - a= " << b - a << endl;
}
输出:
a= 2.34e+23
b - a= 0
说明:23.4e22f小数点左边有23位有效数字,在第23位加1.由于float只能表示数字中的前6位或者前7位,因此修改第23位,对这个值不会有影响。
二 C++算术运算符
运算优先级和结合性
120/45 结果是150 还是6
/和同一优先级,/ * 均为从左到右结合,因此为150.仅当两个运算符被用于同一个操作数时,结合性才有效。
除法
类型转换
由于要处理11中整型,3种浮点型,计算机处理情况比较复杂,因此C++自动执行很多类型的转换。
(1)将一种算术类型的值,赋给另一种算术类型的变量时,C++将对值进行转换。
(2)表达式中包含不同的类型时,C++将对值进行转换。
(3)将参数参数传递给函数时,C++将对值进行转换。
-
初始化和赋值进行的转换
将一种类型的值赋给另一种类型的变量,值将被转为接收变量的类型。
short a = 2;
long solong = a; 将a扩展为32位,得到一个新值,新值被保存在solong中。
注意:小转大没问题,大转小有问题
-
以{}初始化时进行的转换(C++11)
初始化列表对类型转换的要求更严格。列表初始化不允许缩窄转换,即变量的类型可能无法表示赋给它的值。例如不允许将浮点型转换为整型。在不同整型之间转换或将整型转为浮点型可能被允许,条件是编译器知道目标变量能够正确的存储赋给他的值。
eg:
const int code = 66;
int x =66;
char c1 {31326}; // error
char c2{66};//ok
char c3{code}; //ok
char c4 = {x}; //error x不是不变的是一个变量,在编译器看来其值可能无限大
x = 35654;
char c5 = x;//可以,初始化,不是初始化列表。 -
表达式中的转换
当同一个表达式中包含两种不同的算术类型。C++将自动执行两种转换:1.一些类型在出现时就会自动转换;2.有些类型在与其他类型同时出现在表达式中时,将被转换。
自动转换:在计算表达式时,C++将bool,char ,unsigned char,siged char 和short 值转为int。true被转为1,false转为0,即整型提升。
short a = 1;
short b = 2;
short c = a + b; //程序获得a b的值,转为int ,在转为short赋给c。(因为int是计算机最自然的类型,运算速度可能最快)
其他的整型提升:如果short比int短,则unsigned short 类型将被转为int 。如果两种类型相同,则unsigned short 类型将转为unsigned int 。确保了在对unsigned short 进行提升时,不会损失数据。
同样wchar_t被提升为下列类型中第一个宽度足够存储wchar_t取值范围的类型。int ,unsigned int ,long 或unsigned long。
不同的类型进行算术运算也会进行转换,int 和float相加时,将会把int 转为float。
总之编译器通过校检表来确定在算术表达式中执行的转换。校验表如下:
-
传递参数时的转换
传递参数时的类型转换通常由C++函数原型控制 -
强制类型转换
int a = 5;
(long) a 或者long (a) 强制转换不会改变值本身,而是创建一个新的制定类型的 值。
static_cast a // 强转运算符
C++11中的auto声明
主要用于处理复杂类型,如标准模块库STL中的类型
C++98代码
std::vector scores;
std::vector::iterator pv = scores.begin();
C++11:
std::vector scores;
auto pv = scores.begin();