day03:数据类型转换


1. 类型转换

  1. 自动类型转换
  2. 强制类型转换
  3. 字符型和整型的转换

1.自动类型转换
在不同数据类型的混合运算中,编译器会隐式地进行数据类型转换,称为自动类型转换。
自动类型转换遵守以下规则:
(1)若参与运算的数据类型不同,则先转换成同一类型,然后进行运算。
(2)转换按数据长度增加的方向进行,以保证精度不降低。例如int类型和long long类型运算时,先把int转换为long long后再运算。
(3)在赋值运算中,赋值号两边的数据类型不一样时,将把右面表达式的类型转换为左边变量的类型。如果右边表达式的数据类型长度比左边的长时,将丢失一部分数据。
即:char -->short -->int --> float -->double

#include<bits/stdc++.h>
using namespace std;

int main(){
    int a = 1, b = 2;
    double  c = 1.2, d = 2.3;
    double e = a + b + c + d;//a,b会隐式转换为double类型
    cout<<e;    //输出结果:6.5
    return 0;
}

2.强制类型转换
当自动类型转换不能实现目的时,可以显示的进行类型转换,称为强制类型转换。
强制类型转换的一般形式是: (类型名)(表达式) (类型名)变量
如(double)a 是将a转换为double型,
(int)(x + y) 是将 x+y 的值转换为整型,
(float)5/3 是将 5 的值转换成float型,再与 3 运算。
double为双精度浮点型,float为单精度浮点型,区别在于他们的精度不同。

#include<bits/stdc++.h>
using namespace std;

int main(){
    double a = 1.2, b = 2.3;
    int c = (int)a;
    double d = (int)a+b; 
    cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
    //输出结果:1.2 2.3 1 3.3
    return 0;
}

3.字符型和整型的转换
将一个字符放到内存单元时,实际上并不是把该字符本身放到内存中,而是将该字符的ASCII代码放到存储单元中。
如字符变量c1的值是'a',c2的值是'b',则在变量中存放的是 'a' 的ASCII码97,'b' 的ASCII码98

#include<iostream>
using namespace std;

int main(){
    char a = 'a';
    cout<<a<<" "<<(int)a<<endl;//a 97

    char b = 'b';
    cout<<b<<" "<<(int)b<<endl;//b 98

    int c = 97;
    cout<<c<<" "<<(char)c<<endl;//97 a

    int d = 98;
    cout<<d<<" "<<(char)d<<endl;//98 b

    cout<<++a<<endl;//b
    cout<<--b<<endl;//a
    cout<<(char)(c-32)<<endl;//A
    cout<<(char)(d-32)<<endl;//B
    return 0;
}

2. c++输入输出

基本输入输出格式 输入 输出
符号 cin cout
单个使用 cin>>a; cout<<a;
多个使用 cin>>a>>b>>c; cout<<a<<" "<<b<<" "<<c;

注意:任何变量在使用前都需要先定义。

预定义对象 cin 和 cout 都是 iostream 类的实例,与流插入运算符 << 结合使用,使用前需要导入头文件iostream

cin 对象附属到标准输入设备,通常是键盘。
cout 对象"连接"到标准输出设备,通常是显示屏。

c++中对于浮点数的输出需要注意,这一点在之前已经提过,这里不过老生常谈!

浮点数也就是小数,同理还存在定点数,也就是我们说的整数。

当我们要输出 :3.1415926535 小数点后3位的时候,就需要使用输出格式控制了!如下程序

#include<iostream>
#include<iomanip>
using namespace std;

int main(){
    cout<<fixed<<setprecision(3)<<3.1415926535<<endl;
    return 0;
}

通过fixed<<setprecision(3);就可以达到这个效果了,如下图。

但是我们使用的这个函数是其他库里的,所以我们需要导入iomanip这个头文件。
fixed :是指定位小数点
setprecision(num) :是指控制输出num位有效数字

原则还是和数学上相同:对第num+1位进行四舍五入
day03:数据类型转换_输入输出

具体详细说明见以下程序,并在之后附有执行效果图:

#include<iostream>
#include<iomanip>
using namespace std;

int main(){

    //默认输出6位有效数字
    cout<<3.1415926535<<endl; //3.14159

    //默认输出6位有效数字,如果数据过大,会使用科学计数法输出
    cout<<3141592.6535897<<endl; //3.14159e+006

    //输出3位有效数字
    cout<<setprecision(3)<<3.1415926535<<endl; //3.14

    //输出小数点后3位有效数字
    cout<<fixed<<setprecision(3)<<3.1415926535<<endl; //3.142

    //fixed<<setprecision(3)的作用还存在
    cout<<3.1415926535<<endl; //3.142

    //fixed的作用还存在
    cout<<setprecision(4)<<3.1415926535<<endl; //3.1416

    //清除所有与域相关,与基数相关,与浮点相关的设置
    cout.unsetf(ios::adjustfield | ios::basefield | ios::floatfield) ;

    //fixed作用已经取消,但是setprecision(3)的作用还存在
    cout<<3.1415926535<<endl; //3.142

    //重新设置成原默认设置,fixed作用已经取消
    cout<<setprecision(6)<<3.1415926535<<endl; //3.14159

    return 0;
}

day03:数据类型转换_#include_02



3. C语言输入输出

基本输入输出格式 输入 输出
符号 scanf printf
int类型的输入输出 scanf("%d",&a); printf("%d",a);
float类型的输入输出 scanf("%f %f",&a, &b); printf("%f %f",a, b);
double类型的输入输出 scanf("%lf",&a); printf("%lf",a);

注意:使用前需要导入头文件cstdio

#include<cstdio>
using namespace std;

int main(){
    int a;
    scanf("%d", &a);    //输入并赋值给a,注意输入有符号&,输出没有
    printf("a = %d\n", a);    //输出a的值,并换行 

    float b;
    scanf("%f", &b);
    printf("b = %f\n", b);    //输出b,默认保留小数后6位 
    printf("b = %.4f\n", b);//输出b,保留小数后4位 

    double c;
    scanf("%lf", &c);
    printf("c = %6.4lf\n", c);//输出c,宽度为6,保留小数后4位 

    long long d;
    scanf("%ld", &d);
    printf("d = %ld\n", d);//输出d

    //也可以一起使用
    printf("a = %d b = %f c = %lf d = %lld\n",a,b,c,d);
    printf("a = %d b = %2.3f c = %3.4lf d = %lld\n",a,b,c,d);
    return 0;
}

函数名:scanf
功 能:执行格式化输入
用 法:int scanf(char *format[,argument,...]);
scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息。
可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。
其调用格式为: scanf("<格式化字符串>",<地址表>);
scanf()函数返回成功赋值的数据项数,出错时则返回EOF

C++和C语言输入输出的比较

  1. cin和cout在DevC++中只能调用库,而其他输入输出格式要调用<stdio.h>库或库。
  2. cin和cout属于C++的概念,调用时涉及输入输出流,而scanf和printf属于C的概念,是C语言的标准输入/输出库中的函数,所以在时效上,scanf和printf优于cin、cout,对于大数据的输入输出,通常情况下应该用scanf、printf。
  3. 对于普通数据的输入输出,cin和cout比较方便,而在格式化方面,scanf和printf比较容易。cin效率比scanf低很多,尤其输入数据达到20万以上时非常明显,在100万时cin读入就会超时。
  4. scanf和printf也有缺点,cin和cout能够自动识别变量的数据类型,因此,在进行输入输出时,不需要指定数据类型,printf和scanf函数在输入输出时需指定数据类型。

格式表示 意义
%c 一个(ASCII)字符,一个汉字实际上在内存中要占据两个字符的位置。
%s 一串字符,字符串。
%nd %ld 一个十进制整数,n为输出占位宽度。
printf(“%12d”,a); 如a为数字8,则前面补齐11个空格, ld表示 长整型数据
%nx %nX 一个十六进制整数,n为输出占位宽度。
%no 一个八进制整数,n为输出占位宽度。
%n.mf 单精度浮点数,n代表该浮点数的占位宽度,.m代表小数点后保留几位
a为12.2324,printf(“%.3”,a); 12.232,自动四舍五入。
%n.mlf 双精度浮点数,n代表该浮点数的占位宽度,.m代表小数点后保留几位
a为12.2324,printf(“%.3”,a); 12.232,自动四舍五入。
%E 输出科学计数法,12.12 输出为 1.212000E+001,只适用 float,double。
%p 指针(变量的地址)
%% 输出时有用,表示输出一个%

注意:格式在输入时不能有,在输出时可以有也可以没有
注意:%为变量占位符,\只在printf中使用,为特殊字符的转义字符

流操纵算子 作用
dec 以十进制形式输出整数
cout << hex << 12 << " " << 24; 则输出:c 18
hex 以十六进制形式输出整数
oct 以八进制形式输出整数
fixed 以普通小数形式输出浮点数
scientific 以科学计数法形式输出浮点数
left 左对齐,即在宽度不足时将填充字符添加到右边
right 右对齐,即在宽度不足时将填充字符添加到左边
setbase(b) 设置输出整数时的进制,b=8、10 或 16
setw(w) 指定输出宽度为 w 个字符,或输人字符串时读入 w 个字符
setfill(c) 在指定输出宽度的情况下,输出的宽度不足时用字符 c 填充(默认情况是用空格填充)
setprecision(n) 设置输出浮点数的精度为 n, 在使用非fixed且非scientific 方式输出的情况下,n 即为有效数字最多的位数,
如果有效数字位数超过 n,则小数部分四舍五人,或自动变为科学计数法输出并保留一共 n 位有效数字
在使用 fixed 方式和 scientific 方式输出的情况下,n 是小数点后面应保留的位数
setiosflags(标志) 将某个输出格式标志置为 1,设置输出标志
resetiosflags(标志) 将某个输出格式标志置为 0,清除输出标志

4. 转义字符

作用:用于表示一些不能显示出来的ASCII字符
现阶段我们常用的转义字符有: \n \\ \t

转义字符 含义 ASCII码值(十进制)
\a 警报 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 数字0 000
\ddd 8进制转义字符,d范围0~7 3位8进制
\xhh 16进制转义字符,h范围0 ~ 9,a ~ f,A ~ F 3位16进制

5. 实例练习

1.地球人口承载力估计【小学奥数7653】

假设地球上的新生资源按恒定速度增长。照此测算,地球上现有资源加上新生资源可供x亿人生活a年,或供y亿人生活b年。为了能够实现可持续发展,避免资源枯竭,地球最多能够养活多少亿人?

输入:一行,包括四个正整数 x,a,y,b,两个整数之间用单个空格隔开。x>y,a<b,ax<by,各整数均不大于10000
输出:一个实数z,表示地球最多养活z亿人,舍入到小数点后两位。
样例输入: 110 90 90 210
样例输出: 75.00

本题题解
本题目主要找到平衡点,也就是不变量来建立等式
本题目所求的是避免资源枯竭,地球最多能够养活多少亿人,也就是说在现有资源不被消耗的情况下,刚好将新增资源消耗完毕的时候,能养活多少人,也就是要求出新生资源的增长速度。
由于题目中说明新生资源按恒定速度增长,证明新生资源的增长速度是一个定量,那么我们假设该定量为 m.
又地球上现有资源加上新生资源可供x亿人生活a年,或供y亿人生活b年。
首先,现有资源一定是一个定量,新生资源由于ab的变化在发生变化,所以我们可以建立以下等式
现有资源 = x*a - m*a;
现有资源 = y*b - m*b;
所以 m = (x*a-y*b)/(a-b);

所以标程(针对本题的解答程序)如下:

#include<cstdio>
int main(){
    int x,a,y,b;
    scanf("%d %d %d %d",&x, &a, &y, &b);
    double z = 1.0*(x*a-y*b)/(a-b);
    printf("%.2lf", z);
    return 0;
}

2.数学中经典的"鸡兔同笼"问题,已知头共30个,脚共90只,问笼中的鸡和兔各有多少只?

解决方案一:
    听我口令,所有动物,提起一只脚 
    听我口令,所有动物,提起第二只脚
    好了,现在着地的还有90-30-30=30只脚
    由于鸡只有两只脚,所以这时候的全部鸡都是跪着的,
    这30只脚应当都是兔子的,每只兔子有4只脚,提起2只,还剩2只
    所以兔子的数量为:30/2=15只
    所以鸡的数量为30-15只

解决方案二:
    差值求解
    假设都为兔,则 缺少 30*4 - 90 = 30支脚
    所以这 缺少的脚就是鸡, 所以鸡的数量 = 30/2=15;
    兔的数量 = 30-15;

解决方案三:
    列方程,设鸡 x只,兔 y只, 则 
    x + y = 30
    2*x + 4*y = 90
    解得 x = 15, y = 15

解决方案四:
    循环遍历,假设 鸡兔都为0只,每次递增+1,直到满足方案三中方程的xy出现
    输出结果
#include<cstdio>
int main(){
    int x,y;
    x = (30*4-90)/2;
    y = 30-x;
    printf("%d %d\n", x, y);
}

3.计算并联电阻的阻值
对于阻值为r1和r2的电阻,其并联电阻阻值公式计算如下:R = 1/(1/r1 + 1/r2)。
输入两个电阻阻抗大小,浮点型。输出并联之后的阻抗大小,结果保留小数点后2位。
输入:两个电阻阻抗大小,浮点型,以一个空格分开。
输出:并联之后的阻抗大小,结果保留小数点后2位
样例输入:1 2
样例输出:0.67

#include<cstdio>
int main(){
    double r1,r2,R;
    scanf("%lf%lf", &r1, &r2);
    R = 1/(1/r1+1/r2);
    printf("%.2lf\n", R);
}

4.海伦公式
传说古代的叙拉古国王海伦二世发现的公式,利用三角形的三条边长来求取三角形面积。已知△ABC中的三边长分别为a,b,c,求△ABC的面积。(提示:海伦公式)
day03:数据类型转换_类型转换_03

#include<cstdio>
#include<cmath>
int main(){
    double a, b, c, p, s;
    scanf("%lf%lf%lf", &a, &b, &c);
    p = (a+b+c)/2;
    s = sqrt(p*(p-a)*(p-b)*(p-c));
    printf("%.2lf\n", s);
}