本章内容包括:
- C++内置基本类型:整数和浮点数
- 使用变量标识存储的数据
- char类型和ASCII码
- 浮点数及精度降低
- C++算数运算
- C++类型转换:自动和强制
整型
//程序清单3.1
//整型极限
#include <iostream>
#include <climits>
int main(void)
{
using namesoace std;
int n_int = INT_MAX; //初始化n_int为int最大值
short n_short = SHRT_MAX; //XX_MAX为climits文件中定义的符号
long n_long = LONG_MAX; //初始化将赋值和声明合并
long long n_llong = LLONG_MAX;
//sizeof运算符生成类型或变量的大小
cout << "int is " << sizeof(int) << " bytes." << endl;
cout << "short is " << sizeof n_short << " bytes." << endl;
cout << "long is " << sizeof n_long << " bytes." << endl;
cout << "long long is " << sizeof n_llong << " bytes." << endl;
cout << endl;
cout << "Maximum Values:" << endl;
cout << "int: " << n_int << endl;
cout << "short: " << n_short << endl;
cout << "long: " << n_long << endl;
cout << "long long: " << n_llong << endl << endl;
cout << "Minimum int value = " << INT_MIN << endl;
cout << "Bits per byte = " << CHAR_BIT << endl;
return 0;
}
- 计算机内存的基本单元是位(bit)。字节(byte)通常指8位的内存单元
- sizeof返回类型或变量的长度,单位为字节(byte)
- sizeof不是函数只是运算符,后跟数据类型+括号,或变量名+括号可选
- 头文件climits包含关于整型限制的信息,定义了各种限制的符号名称
- C语言初始化:int owls = 101;C++还有一种初始化:int wrens(432);
- 还有一种初始化,适用于数组和结构:int hamburgers = {24};int hamburgers {24};
- 将变量声明和赋值分开,可能会带来瞬间悬而未决的问题
//程序清单3.2
//超出整数极限
#include <iostream>
#define ZERO 0 //ZERO代表0
#include <climits>
int main(void)
{
using namespace std;
short sam = SHRT_MAX; //32767
unsigned short sue = sam; //32767
cout << "Sam has " << sam << " dollars and Sue has " << sue
<< " dollars deposited.\n";
cout << "Add $1 to each account." << endl << "Now ";
sam = sam + 1; //-32768
sue += 1; //32768
cout << "Sam has " << sam << " dollars and Sue has " << sue
<< " dollars deposited.\nPoor Sam!" << endl;
sam = sue = ZERO; //0
cout << "Sam has " << sam << " dollars and Sue has " << sue
<< " dollars deposited.\n";
cout << "Take $1 from each account." << endl << "Now ";
sam = sam - 1; //-1
sue -= 1; //65535
cout << "Sam has " << sam << " dollars and Sue has " << sue
<< " dollars deposited." << endl << "Lucky Sue!" << endl;
return 0;
}
- short sam = SHRT_MAX; sam = sam + 1; 整型上溢
- sam = sue = ZERO; sue -= 1; 整型下溢
- int 被设置为计算机处理最自然的长度(效率最高)
- sam = sam + 1; 和sue += 1;作用一样
//程序清单3.3
//显示16进制和8进制
#include <iostream>
int main(void)
{
using namespace std;
int chest = 42; //10进制整型字面值
int waist = 0x42; //16进制整型字面值
int inseam = 042; //8进制整型字面值
cout << "chest = " << chest << " (42 in decimal)\n"; //42
cout << "waist = " << waist << " (0x42 in hex)\n"; //66
cout << "inseam = " << inseam << " (042 in octal)\n"; //34
return 0;
}
- 不管是几进制,在计算机中以二进制存储
- cout 默认显示10进制,若要修改:
//程序清单3.4
//显示16进制和8进制
#include <iostream>
int main(void)
{
using namespace std;
int chest = 42; //10进制整型字面值
int waist = 42; //16进制整型字面值
int inseam = 42; //8进制整型字面值
cout << "chest = " << chest << " (decimal for 42)\n"; //42
cout << hex;
cout << "waist = " << waist << " (hexadecimal for 42)\n"; //2a
cout << oct;
cout << "inseam = " << inseam << " (octal for 42)\n"; //52
return 0;
}
- cout << hex;控制符hex修改cout显示整数的方式
char类型
//程序清单3.6
//char类型和int类型对比
#int main(void)
{
using namespace std;
char ch = 'M'; //将M的ASCII码分配给ch
int i = ch; //在int中存储相同的代码,没有类型不匹配,77
cout << "The ASCII code for " << ch << " is" << i << endl;
cout << "Add one to the character code:" << endl;
ch += 1; //N
i = ch; //78
cout << "The ASCII code for " << ch << " is" << i << endl;
//使用cout.put()打印字母
cout.put(ch); //N
return 0;
}
- char类型专门存储字符(如字母和数字)
- 二进制存储数字;数值编码存储字母
- C++对字符用单引号;字符串用双引号
- ‘M’表示M的数值编码,char变量ch初始化为’M’,ASCII码为77
- cout.put()表示通过类对象cout使用函数put()
浮点数
//程序清单3.8
//浮点类型
#include <iostream>
int main(void)
{
using namespace std;
//setf()成员运算符迫使输出使用定点表示法,显示小数点后6位
cout.setf(ios_base::fixed, ios_base::floatfield);
float tub = 10.0 / 3.0;0
double mint = 10.0 / 3.0;
const float million = 1.0e6;
cout << "tub = " << tub << endl; //3.333333
cout << "a million tubs = " << million * tub << endl; //3333333.250000
cout << "ten million tubs = " << 10 * million * tub << endl; //33333332.000000
cout << "mint = " << mint << endl; //3.333333
cout << "a million mints = " << million * mint << endl; //3333333.333333
return 0;
}
- const限定符定义常量,不可修改;首字母大写或全大写;声明同时初始化
- 通常cout会删除结尾的0,调用cout.setf显示小数点后六位。所以tub和mint都是精确的,但是系统确保float至少有6位有效位,double至少有15位有效位,当各乘上.一百万后,tub在第7个3后有了误差;double并没有出现误差,这指出float超出精度限制
- 和整数相比,浮点数表示范围更大,但浮点数运算速度慢,且精度降低,如程序清单3.9
//程序清单3.9
//浮点数精确度问题
#include <iostream>
int main(void)
{
using namespace std;
float a = 2.34E+22f;
float b = a + 1.0f;
cout << "a = " << a << endl; //a = 2.34e+22
cout << "b -a =" << b -a << endl; //0
return 0;
}
- b-a应该等于1,但程序输出却是0,原因在于2.34E+22是小数点左边有23位的数字,但float类型只能显示前6或7位,所以更改第23位对这个值没有任何影响
-
浮点数在内存中如何存储?为什么精度降低?为什么double比float精度高?
-
算数运算符
//程序清单3.10
//一些C++算数运算符
#include <iostream>
int main(void)
{
using namespace std;
folat hats,heads;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "Enter a number: ";
cin >> hats; //50.25
cout << "Enter another number: ";
cin >> heads; //11.17
cout << "hats = " << hats << "; heads = " << heads << endl; //50.250000;11.170000
cout << "hats + heads = " << hats + heads << endl; //61.419998
cout << "hats - heads = " << hats - heads << endl; //39.080002
cout << "hats * heads = " << hats * heads << endl; //561.292480
cout << "hats / heads = " << hats / heads << endl; //4.498657
- 11.17 + 50.25应该等于61.42,但输出却是61.419998,看过“浮点数在内存中如何存储?为什么精度降低?为什么double比float精度高?”应该懂了
- 算数运算符遵循通常代数优先级:先乘除,后加减;先算括号内,后算括号外;优先级相同,从左到右
//程序清单3.11
//整型和浮点型除法
#include <iostream>
int main(void)
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << "Integer division: 9/5 = " << 9 / 5 << endl; //1
cout << "Floating-point division: 9.0/5.0 = " << 9.0 / 5.0 << endl;//1.800000
cout << "Mixed division: 9.0/5 = " << 9.0 / 5 << end; //1.800000
cout << "double constants: 1e7/9.0 = " << 1e7 / 9.0 << endl; //1111111.111111
cout << "float constants: 1e7f/9.0f = " << 1e7f / 9.0f << endl; //1111111.125000
return 0;
}
- 除法运算符(/)的行为取决于操作数类型。都为整数,则丢弃小数;有一个浮点数,则保留小数
- 不同类型运算,C++自动类型转换,将较低类型提升为较高类型
初始化和赋值进行的转换
- 假设so_long的类型为long,thirty的类型为short
so_long = thirty;
- 进行赋值时,程序将thirty的值(通常16位)扩展为long值(通常32位)。
- 扩展得到的新值存储在so_long中,而thirty的内容不变
- 将一个值赋值给更大范围的类型不会出问题,反之则不一定
以{ }方式初始化进行的转换
- 称为列表初始化
- 列表初始化不允许缩窄
const int code = 66;
int x = 66;
char c1 {31325}; //不允许缩窄
char c2 = {66};
char c3 {code};
char c4 = {x}; //x不是常量
x = 31325;
char c5 = x;
表达式中的转换(类型提升)
short chickens = 20;
short ducks = 35;
short fowl = chickens + ducks;
- 执行第三行语句时,C++取得chickens和ducks的值,将它们转换为int类型,进行运算,然后将结果转换为short类型。这些转换称为整型提升。
强制类型转换
//通用格式
(typename) value
typename (value)
//程序清单3.14
//强制类型转换
#include <iostream>
int main(void)
{
using namespace std;
int auks, bats, coots;
auks = 19.99 + 11.99; //转换成double传递给int
bats = (int)19.99 + (int)11.99; //C
coots = int(19.99) + int(11.99); //C++
//auks = 31, bats = 30, coots = 30
cout << "auks = " << auks << ", bats = " << bats << ", coots = " << coots << endl;
char ch = 'Z';
//The code for Z is 90
cout << "The code for " << ch << " is " << int(ch) << endl;
return 0;
}
- 19.99和11.99相加,结果为31.98
- 将这个值赋给int变量auks时,截短为31
- 进行强制类型转换时,这两个值被截短为19和11再相加,因此bats和coots的值都为30
版权声明:本文为Flying_Dutchman_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。