【C++笔记】二、简单数据类型与算数运算符

1.基础数据类型:整形

1.1 有符号整型

short:2字节  16位  -2^15 -- 2^15 - 1(有一位是符号位)  -32768 -- 32767

(这样理解:假设数据有4位,除去符号位有3位,那么2^3-1等于111)

int: 4字节  32位  -2^31 -- 2^31 - 1

long: 如果是32位的系统下:long = int,32位,如果是64位系统下,long:64位 ,long long:64位 

-2^63 -- 2^63 - 1

1.2 无符号整型

unsigned short: 0 -- 2^16 - 1

例如:1000000000000001 有符号数:-1  无符号数:32769

1.3 获取整形尺寸

1.4 获取整形最大值,最小值:

1.5 整形的溢出:

注意:补码是除符号位外的原码取反加一,原码是除符号位外的补码取反加一,数据以补码形式存储,打印时输出的也是补码的值。

在整形溢出时,会根据最大,最小值范围循环,就比如第一行的INT_MAX + 1后,得到INT_MIN。

2.基础数据类型:字符(char)

2.1 有符号:char

占用1个字节,8位,范围是-128到+127(若赋值溢出,则循环)

(例如1 111 1111,其中最高位是符号位,剩下的111 1111是2^7 - 1,即127)

对于char类型,输出的是相应的字符,若是把结果赋给short类型,则输出的是对应的ASCII码值。

可以用put直接输出字符:

输出结果为: $ a b

对put传入short类型变量时,依然会输出其ASCII码对应的字符。

2.2 无符号:unsigned char

占用1个字节,8位,范围是0到255

3.C++ 中的特殊字符

3.1 根据ASCII获取字符

核心思想:把ASCII转换成char类型

要记住一些ASCII所对应的字符:

字符0对应48,字符0到9的ASCII值依次递增

字符a(注意大小写)对应的ASCII值为97,字符a - z的ASCII值依次递增

字符A(注意大小写)对应的ASCII值为65,字符A - Z的ASCII值依次递增

3.2 根据字符获取ASCII

核心思想:把字符转换成int类型

cout << (int) '\a' << endl  //获取特殊字符'\a'的ASCII值,其中单引号表示\a为字符类型

3.3 特殊字符

\n : newline相当于std::endl

\t : tab 列对齐,水平制表符

\v : tab 垂直制表符

\b : backspace退格

\a : alert警告

\\ : 输出反斜杠 \

\' : 输出单引号

\" : 输出双引号

4.宽字符类型

    单字符类型char只能保存单字节的字符,即ASCII所能表示的范围。如果超过这个范围,就很难保存。

所以需要宽字符类型:

4.1 宽字节

wchar_t  有符号类型 32位  4字节  在定义时前加前缀 L

4.2 在C++11中的宽字节

char16_t   无符号类型 2字节  在定义时前加前缀u  

char32_t   无符号类型 4字节  在定义时前加前缀U

查看不同数据类型的宽度

如果直接用cout输出c1,会显示'a'对应的ASCII值,若想要以字符形式输出宽字符类型的数据,就需要用到wcout,且宽字符应该是有符号类型.

使用相应的宽输出就可以输出字符了

由上图可见,字符‘中’所对应的数值是20013,20013换算成16进制等于4E2D,那么就可以通过4E2D来输出字符‘中’。

其中\u前缀表示unicode编码。这样就实现了通过编码输出相应的文本,即利用宽字符类型,输出中文字符对应的编码,再将其转换为16进制,即得到这个中文字符的编码。再利用这个编码输出中文文本。

注意:char16_t和char32_t属于无符号类型,如果使用wcout输出这种类型,则输出的是字符对应的编码,若想要直接输出宽字符,则需要转换为wchar_t类型.

在C++中,用单引号括起来的内容为字符,双引号括起来的为字符串

5.基础数据类型:布尔(bool)

true false

6.基础数据类型:浮点类型

6.1 浮点类型有哪些

单精度浮点类型:float

双精度浮点类型:double

长双精度浮点类型:long double

6.2 浮点类型占用的字节数

float : 4

double : 8

long double : 16

6.3 浮点类型的 表达方式

    float value1 = 234.56;
    double value2 = 123.11;

    // 科学计数法
    //1. 尾数   2.E/e   3.指数
    double value3 = 1234500000000000;
    double value4 = 1.2345E15;    //value3和value4相同

6.4 浮点类型取值范围

//浮点数的指数的取值范围(科学计数法中)
    //float +38  -37
    //double +308  -307
    //long double  +4932   -4931
    float f_max = FLT_MAX_10_EXP;  //float类型的正指数的最大值(以10为底),为38
    float d_max = DBL_MAX_10_EXP;  //double类型的正指数的最大值(以10为底),为308
    float ld_max = LDBL_MAX_10_EXP;

6.5 浮点类型精度

    /*
    精度
    float: 6到7
    一个float32位:1位符号位,8位指数位,23位存尾数即1.2345中的‘2345’
    2的23次方等于8388608,一共7位,如果精确到7位,那么2的23次方表示不了9999999这个数
    即精确到7位的话,不是所有数都能表示,所以精确到6-7位

    double:15到16
    long double: 18到19
    */
    int f_dig = FLT_DIG;  //6
    int d_dig = DBL_DIG;  //15
    int ld_dig = LDBL_DIG;  //18


    float v1 = 1.1234323432;
    double v2 =1.123432343234512678;
    printf("%.18f\n", v2);    //输出18位的double类型数据,但只能准确显示到.....126,后面的内容            
                              //随机输出

6.6 浮点类型值之间的比较

    float fv1 = 123.4;
    float fv2 = 123.4;
    if(fv1 == fv2)
    {
        cout << "equal" << endl;
    }

6.7 习题

    float f_v1 = 20;
    float f_v2 = 20.3;
    float f_v3 = 20.5;
    
    double d_v1 = 20;
    double d_v2 = 20.3;
    double d_v3 = 20.5;
    
    cout << ((f_v1 == d_v1)?"true":"false") << endl;   //运行结果:true
    cout << ((f_v2 == d_v2)?"true":"false") << endl;   //运行结果:false
    cout << ((f_v3 == d_v3)?"true":"false") << endl;   //运行结果:true
    
    //  1.  输出true,还是false
    //  2.  why
    //  3.  如果让输出false的语句仍然通过比较输出true

可以通过   cout << ((f_v2 == (float)d_v2)?"true":"false") << endl;让第二个运行结果显示true。

6.8 浮点数是如何存储的

float:32位,4字节

符号位:1

指数位:8

尾数位:23

double:64位,8字节

符号位:1

指数位:11

尾数位:52

long double:128位,16字节

符号位:1

指数位:64

尾数位:63

6.9 如何将十进制浮点数转换为二进制浮点数

将十进制整数转换为二进制整数

    bitset<32> myset(443);   //将十进制443转换为32位的二进制数
    cout << myset << endl;

将十进制浮点数转换为二进制浮点数

20.5

20 = 10100

0.5 * 2 = 1.0 (1)

0 * 2 = 0 (0)

0 * 2 = 0 (0)

即 0.5(十进制) = 0.1(二进制)

20.5 = 10100.1

20.3

20 = 10100

0.3 * 2 = 0.6 (0)

0.6 * 2 = 1.2 (1)

0.2 * 2 = 0.4 (0)

0.4 * 2 = 0.8 (0)

0.8 * 2 = 1.6 (1)

0.6 * 2 = 1.2 (1)    //进入循环

0.2 * 2 = 0.4 (0)    //进入循环

0.4 * 2 = 0.8 (0)    //进入循环

0.8 * 2 = 1.6 (1)    //进入循环

0.3 = 01001100110011001......1001

20.3 = 10100.010011001....1001

6.10 将浮点数存储在一组字节中(解释了习题的答案)

20.5 = 10100.1(二进制) = 1.01001E100(2^4)

存储:符号位-指数位(移位存储)-尾数位

移位存储:对于float,加上127,对于double,加上1023,再进行存储。

127对应二进制为:01111111  ,127+4 = 131 对应二进制为 10000011

存储方式(float): 0-10000011-01001000000000000000000

存储方式(double):0-10000000011-01001000000000000000000...000000

20.3

0.3 = 01001100110011001......1001

20.3 = 10100.010011001....1001 = 1.0100010011001...E100(科学计数法)

存储方式(float):0-10000011-01000100110011001100110

存储方式(double):0-10000000011-010001001100110011001100011110011...1

(注:2的10次方是1024,那么2^10 - 1等于1023,即1111111111,1111111111 + 4 = 10000000011)

6.11 如何将浮点数以二进制形式输出

float v1 = 20.5;
unsigned int *n = (unsigned int*)(&v1);
for(int i = 31; i >= 0;i--)
{
//float有32位,右移31位表示把最高位移到了最低位,又与了1,表示只保留最低位,后面的'-'是为了把符号位
//和指数位和尾数位用'-'区分开
    cout << (*n>>i & 1) << (i == 31 || i == 23?"-":"");
}
cout << endl;


输出结果:0-10000011-01001000000000000000000
    double v2 = 20.3;
    unsigned long long *m = (unsigned long long*)(&v2);
//这里为什么要用long long类型呢??
    for(int i = 63; i >=0;i--)
    {
        cout << (*m>>i & 1) << (i == 63 || i == 52?"-":"") ;
    }
    cout << endl;

0-10000000011-0100010011001100110011001100110011..

(这里有疑问)

7.变量初始化

7.1 与C语言兼容的初始化方式

int n = 20;
int m = 30;
int k = n + m - 50;
int x;
x = n - m;

7.2 C++不同于C语言的初始化方式

float price(30.2);

7.3 C++ 98的初始化方式

int count = {20};
count = {400};

7.4 C++ 11的初始化方式

int day = {20};
int year{};  //默认为0

8.常量

#include <iostream>
using namespace std;
#define ABC 20    //可以通过宏的方式定义常量
int main(int argc, const char * argv[])
{
    //  常量
    const int n = 10;   //可以使用const关键字将变量定义为常量
    
    return 0;
}

9.C++中的基本操作符

#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
    /*
     C++中的基本操作符
     1. +:加
     2. -:减
     3. *:乘
     4. /:除
     5. %:取余(取模)
     6. 指定数值为float和long类型(F/f和L/l)
     7. 通过操作符计算后的浮点数精度
     */
    
    int value1 = 4 + 1;
    int value2 = 4 *2;
    int value3 =5/2;
    int value4 =10-4;
    
    int  value5 = (3 +4)*2;
    
    int value6 = 10 %3;
    cout << value6 << endl;
    
    float f_v = 123.4F;
    long l_v = 34L;

/*float尾数有23位,2的23次方等于8388608,精确到6-7位,那么65292484256转换为2进制后,必然超过了精度范围
*/

    float v1 = 565.292484256;  
    printf("%0.7f\n", v1);   
//输出小数点后7位,尾数:65292484256,精确到6-7位指的是科学计数法中尾数的6-7位.
//所以,会打印565.29244805,其中565.292448为原数,05为随机生成。

    printf("%0.12f\n", 1e7 / 9.0);   //结果:1111111.111111111008
//输出小数点后12位,float类型在科学计数法中精确到6-7位,double在科学计数法中精确15-16位

    printf("%0.12f\n", 1e7F / 9.0F); 
//打印:1111111.125000000000,float类型在科学计数法中精确到6-7位

  
    return 0;
}

10.类型自动转换

10.1 将一个值赋给某一类型的变量时,C++会自动转换

short s_v = 20;
int i_v = 20.3;  //20.3的精度会丢失

float v = 123456789456;   
//输出123456790528.000000 其中7后面应该是8,显示9是因为8后面的9四舍五入给了8
//把小数点放到1后面(科学计数法)的话,这个浮点数精确到了7位
float v1 = 1.2345678E20; //可以这样写
bool b_v = 0;          //bool类型赋值0为假。赋值非0为真
b_v = 200;
if(b_v == false)
{
    cout << "false" << endl;
}
char c1{127};   //字符类型最大就127
char a{200};   //这个语句会报错,使用C11的初始化方式时,会检查初始值是否超出了类型范围
wchar_t c2{3000};   //宽字符类型

long x = 2000;  
char c3 = x;  //传统初始化方式就不检查范围,不会报错

//变量类型的取值范围大于被赋值变量类型的取值范围时, {...}中不允许直接使用变量,只允许使用值
char c4{c1};  
// 表达式中有多种类型,C++会自动转换为取值范围最大的类型
// 在表达式中,如果有一个变量是long double数据类型,则表达式中所有其他变量的值都会转换成long double

// 表达式中的类型转换遵循以下逻辑;

if(long double)
     {
         expr = long double
     }
     else if(double)
     {
         expr = double
     }
     else if(float)
     {
         expr = float
     }
     else if(操作数都是有符号或都是无符号的值)
     {
         short + int + long = long
         unsigned short  + unsigned int = unsigned int
     
     }
     else if(操作数包含有符号和无符号的数,无符号类型的取值范围可以容纳有符号类型的值)
     {
         unsigned long + short + int = unsigned long
     }
     else if(操作数包含有符号和无符号的数,无符号类型的取值范围不能容纳有符号类型的值)
     {
         unsigned short + int + long = long
     }
     else
     {
        unsigned int + int = unsigned int
     }

11.强制类型转换

11.1 传统的C语言类型强制转换

int x = 65;
char c{x};   //会报错
char c{(char)x};   //  C语言中的类型强制转换方式

cout << c << endl;   //会输出A

11.2 C++中的类型强制转换

int y = 97;
char c1{char(y)};  //  C++语言中的类型强制转换方式

11.3 强制转换操作符static_case(var)

cout << 'X' << endl;    //输出大写字母X
cout << int('X') << endl;    //输出大写字母X对应的ASCII码

char c_x = static_cast<char>(x);   //将x转换为char类型,并用这个初始化c_x

12.C++11中的auto关键字

12.1 auto关键字的使用

int n = 200;   //传统赋值方式
//如果写成“auto n = 200L;”,会识别成int类型;如果写成“int n = 200L;”,n为int类型
auto n = 200L;

//auto关键字要求必须在定义变量时初始化

12.2 类型自动识别(auto)的好处

12.2.1.  简化了代码

12.2.2.  当无法清楚地记得类型名时,可以直接使用auto

// STL(传统的写法)
vector<string> products;
//vector<string>::iterator product = products.begin();

//  C++ 11  STL
auto product = products.begin();   //清爽了许多

12.2.3.  当改变初始化表达式返回值的数据类型时,不必再重新修改变量类型

int value = 20 + 45;    //表达式返回值是int
cout << value << endl;

double value = 20 + 45.6;  //表达式返回值是double
cout << value << endl;

int value = 20 + 45.6;  //表达式返回值是int
cout << value << endl;   //此时要保证返回值精度的话,左侧就需要把int转换为double
    
auto value1 = 20 + 45.9;  
cout << value1 << endl;

12.3 一旦类型被识别,将无法更改

auto s = "abcd";   //s为字符串类型
s = 4;    // 这里会报错

12.4 当传递参数值到函数或方法中时

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DUANDAUNNN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值