文章目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200114124626454.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2NjA3ODk0,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020011412473693.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200114125049130.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200115151726888.png)
#include<iostream>
#include<climits>
int main()
{
using namespace std;
short n_short = SHRT_MAX;
int n_int = INT_MAX;
long n_long = LONG_MAX;
long long n_llong = LONG_LONG_MAX;
cout << "length in Bytes: \n";
cout << "short: " << sizeof(n_short) << endl;
cout << "int: " << sizeof(n_int) << endl;
cout << "long: " << sizeof(n_long) << endl;
cout << "long long: " << sizeof(n_llong) << endl;
cout << endl << "Maximum values: \n";
cout << "short: " << n_short << endl;
cout << "int: " << n_int << endl;
cout << "long: " << n_long << endl;
cout << "long long:" << n_llong << endl;
cout << endl << "Minimum values: \n";
cout << "short: " << SHRT_MIN << endl;
cout << "int: " << INT_MIN << endl;
cout << "long: " << LONG_MIN << endl;
cout << "long long:" << LONG_LONG_MIN << endl;
cout << endl << "bits per bytes: " << CHAR_BIT << endl;
return 0;
}
length in Bytes:
short: 2
int: 4
long: 4
long long: 8
Maximum values:
short: 32767
int: 2147483647
long: 2147483647
long long:9223372036854775807
Minimum values:
short: -32768
int: -2147483648
long: -2147483648
long long:-9223372036854775808
bits per bytes: 8
原来#define并不是很受欢迎
大括号初始化器
可以用大括号初始化数组和结构,也可以用于初始化单值变量,这时候可以不加等号。虽然看起来很奇怪,但是这种大括号初始化是c++11新增的,可以用于初始化任何类型,而在此之前,c++ 中的不同类型要用不同方法初始化,非常麻烦
#include<iostream>
#include<climits>
int main()
{
using namespace std;
int num1 = {2};
cout << num1 << endl;
int num2{3};
cout << num2 << endl;
int num3{};
cout << num3 << endl;
int num4 = {};
cout << num4 << endl;
return 0;
}
2
3
0
0
整型表示范围(上溢,下溢)
这图不错,编程语言的类型的表示范围只是一个圈,一个闭环,不是一个数轴,所以你如果在重置点加1减1,得到的会是错误结果,其他地方都不会错
示例1
#include<iostream>
#include<climits>
#define ZERO 0
int main()
{
using namespace std;
short ss = SHRT_MAX;
unsigned short mm = ss;
cout << "ss has " << ss << " dollars. \n";
cout << "mm has " << mm << " dollars. \n";
cout << "Add $1 to each account. \n";
ss++ ;
mm++;
cout << "Now ss has " << ss << " dollars. \n";
cout << "Now mm has " << mm << " dollars. \n";
cout << "poor ss!\n";
cout << endl;
ss = ZERO;
mm = ss;
cout << "ss has " << ss << " dollars. \n";
cout << "mm has " << mm << " dollars. \n";
cout << "Take $1 from each account. \n";
ss-- ;
mm--;
cout << "Now ss has " << ss << " dollars. \n";
cout << "Now mm has " << mm << " dollars. \n";
cout << "lucky mm!";
}
ss has 32767 dollars.
mm has 32767 dollars.
Add $1 to each account.
Now ss has -32768 dollars.
Now mm has 32768 dollars.
poor ss!
ss has 0 dollars.
mm has 0 dollars.
Take $1 from each account.
Now ss has -1 dollars.
Now mm has 65535 dollars.
lucky mm!
因为short占16位,那么有符号short只有15位用于表示数值大小,2的15次方是32768,所以正数部分是0 000000000000001到0 111111111111111,即1到32767,而负数是1 111111111111111 到1 000000000000001,即-1到-32768(由补码求原码:符号位不变,其他所有位取反再加1)。
现在ss是0 11111111111111111111(32767),加1变为 1 000000000000000, 转为原码还是1 000000000000000 ,表示-32768
mm是0 11111111111111111111(32767),加1变为 1 000000000000000,由于第一位不是符号位,所以数值就是32768(
2
1
5
2^15
215)
ss是0, 则为0 000000000000000, 减去1, 即加上-1(1 111111111111111),得1 111111111111111, 转为原码是1 000000000000001,即-1;
mm是0, 则为0 000000000000000, 减去1, 即加上-1(1 111111111111111),得1 111111111111111,但是最高位不是符号位,所以这就是
2
1
6
−
1
=
65535
2^16-1=65535
216−1=65535。
另一个很好展示上图那种圆圈的示例
// 整数溢出的示例
#include <stdio.h>
int main()
{
int x = 2147483647; // 有符号int可以表示的最大值(32位)
unsigned int y = 4294967295; // 无符号int可以表示的最大值(32位)
printf("%d, %d, %d\n", x, x+1, x+2);
// 无符号int用%d显示则被当做是有符号的,unsigned int y = 4294967295本来是32个1,结果最高位被当做符号位,成为-1
printf("%d, %d, %d\n", y, y+1, y+2);
printf("%u, %u, %u\n", y, y+1, y+2);
return 0;
}
2147483647, -2147483648, -2147483647
-1, 0, 1
4294967295, 0, 1
补一个C语言的整数溢出导致无限循环示例
uint8_t无符号8位整型,i=0,i-1=255,所以永远不会退出循环
#include <inttypes.h>
#include <stdio.h>
#include <inttypes.h>
uint8_t i = 5;
uint32_t count = 0;
int main()
{
while(i-->=0)
{
count ++;
printf("the number of while count is : %u\r\n",count);
}
return 0;
}
16进制,8进制
#include<iostream>
#include<climits>
int main()
{
using namespace std;
int chest = 20; //十进制
int waist = 0x30; // 十六进制
int leg = 042; // 八进制
cout << "chest: " << chest << " (20 in decimal.)\n";
cout << "waist: " << waist << " (0x30 in hex.) \n";
cout << "leg: " << leg << " (042 in octal.)\n";
return 0;
}
chest: 20 (20 in decimal.)
waist: 48 (0x30 in hex.)
leg: 34 (042 in octal.)
也可以用控制符hex, oct改变基数
#include<iostream>
#include<climits>
int main()
{
using namespace std;
int chest = 20; //十进制
int waist = 0x30; // 十六进制
int leg = 042; // 八进制
cout << "chest: " << chest << " (20 in decimal.)\n";
cout << hex << "waist: " << waist << " (0x30 in hex.) \n";
cout << oct << "leg: " << leg << " (042 in octal.)\n";
return 0;
}
chest: 20 (20 in decimal.)
waist: 30 (0x30 in hex.)
leg: 42 (042 in octal.)
常量类型如何确定
只要不是超出范围或者有后缀说明,否则就存为int
char类型
#include<iostream>
#include<climits>
int main()
{
using namespace std;
char ch;
cout << "enter a character. \n";
cin >> ch; // cin把a转化为97存入内存
cout << "thanks for the " << ch << " character. \n"; //cout把97读为a
return 0;
}
enter a character.
a
thanks for the a character.
cin cout为我们完成了转换工作
c++对字符用单引号,对字符串用双引号
#include<iostream>
#include<climits>
int main()
{
using namespace std;
char ch = 'm';
int in = ch;
cout << "The ASCII code for " << ch << " is " << in << endl;
ch ++;
in = ch;
cout << "The ASCII code for " << ch << " is " << in << endl;
cout.put(ch);
cout << '!';
cout.put('!');
return 0;
}
The ASCII code for m is 109
The ASCII code for n is 110
n!!
cout.put()是OOP第一个示例。点号是成员运算符,put()是成员函数,用它是历史原因,总之现在已经可以不通过它了,cout已经可以一人完成所有任务了。
牛逼!char用作数值类型竟然可能不确定有无符号,必须明确指定
转义字符
#include<iostream>
#include<climits>
int main()
{
using namespace std;
cout << '\a';
cout << "I love \"you\".";
return 0;
}
\a会响诶,Windows启动的声音
I love "you".
bool类型
c语言以前是没有bool类型的,后来C99标准引入了,引入头文件<stdbool.h>即可,详见这篇博文
#include<iostream>
int main()
{
using namespace std;
bool is_ready = true;
int a = true;
int b = false;
bool c = -10;
bool d = 0;
cout << is_ready << endl;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
1
1
0
1
0
可以看到,给bool类型的变量赋0以外的值都会被存为1,不会存储原值
用true和false给int等数值类型赋值,赋的是1和0
const
#include<iostream>
int main()
{
using namespace std;
const int MONTHS = 12;
cout << MONTHS << endl;
cout << sizeof MONTHS << endl;
return 0;
}
12
4
浮点数
整数类型共有11种:
char
signed char, short, int , long, long long,
unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long
#include<iostream>
int main()
{
using namespace std;
float a = 5e12;
double b = 5e22;
long double c =5e202;
cout << a << endl;
cout << sizeof a << endl;
cout << b << endl;
cout << sizeof b << endl;
cout << c << endl;
cout << sizeof c << endl;
return 0;
}
5e+012
4
5e+022
8
5e+202
12
可以看到我的系统中float占4字节,double8字节,long double12字节,如果把c替换为5e602,cout会显示为inf,大概是超出了指数最大位数,但是我没有在float.h或者cfloat文件中找到描述指数最大位数的语句,于是不清楚最大指数位数
float和double精度差异
ios_base::fixed和ios_base::floatfield是iostream头文件提供的常量
大概ios_base也是个名称空间??
#include<iostream>
int main()
{
using namespace std;
float a = 10.0/3.0;
double b = 10.0/3.0;
const float million = 1e6;
cout.setf(ios_base::fixed, ios_base::floatfield);//使用定点表示法输出,默认只打印小数点后6位
cout << a << endl;
cout << b << endl;
cout << a * million << endl;
cout << b * million << endl;
cout << b * million * 10000 << endl;
return 0;
}
3.333333
3.333333
3333333.250000
3333333.333333
33333333333.333336
a, b初始化相同,刚开始cout显示6位小数,看不出区别,乘以100万后,再显示6位小数,就看出了区别,float从第8个有效位,即小数点后第一位就出错了;但是b的13位都是对的;但是第17位也开始出错了
suo以float正确了7位,double正确了16位
精度造成错误
#include<iostream>
int main()
{
using namespace std;
float a = 5.2e18;
float b = a + 1.0f;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << a << endl;
cout << b << endl;
cout << a - b << endl;
return 0;
}
5200000055834050560.000000
5200000055834050560.000000
0.000000
可以看到,float显示了前8位是对的,第9位就错了(但是后面实验表明实际上第8位并没被表示,只是巧合),而且b也没加上1,而是和a相等,这是因为a加1需要在小数点后18位加1,float根本没表示出来,当然不行啦
改a为float a = 5.2e6;
5200000.000000
5200001.000000
-1.000000
结果才对,说明float只能正确表示数字的前7位,从第8位开始就不行啦
通过这样的方式测试发现,double可以正确表示数字的前16位
#include<iostream>
int main()
{
using namespace std;
double a = 5.2e15;
double b = a + 1.0f;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << a << endl;
cout << b << endl;
cout << a - b << endl;
return 0;
}
5200000000000000.000000
5200000000000001.000000
-1.000000
long double 可以正确表示数字的前19位
#include<iostream>
int main()
{
using namespace std;
long double a = 5.2e18;
long double b = a + 1.0f;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << a << endl;
cout << b << endl;
cout << a - b << endl;
return 0;
}
5200000000000000000.000000
5200000000000000001.000000
-1.000000
小测试
用多种方式输出一个字符:
#include<iostream>
int main()
{
using namespace std;
char c = 88;
cout << c << endl;
cout << char(88) << endl; // c++风格强制转换,int to char
cout << (char)88 << endl; // c语言风格
cout.put(char(88));
return 0;
}
X
X
X
X