4.2 浮点数的两种形式
4.2.1 十进制小数形式
📝 合法的浮点数形式举例:
double a = 520.1314; //输出520.131400 double b = 520.; //输出520.000000 double c = 520.0; //输出520.000000 double d = -0.1314; //输出 -0.131400 double e = .1314; //输出 0.131400
4.3.2 指数形式(科学计数法)
C 语⾔允许使⽤科学计数法表示浮点数,使⽤字⺟ e/E 来分隔⼩数部分和指数部分。
- 比如 13.14e+2就等价于 13.14 ∗ 1 0 2 13.14*10^213.14∗102 ,即 1314
- 比如 13.14e-2就等价于 13.14 ∗ 1 0 − 2 13.14*10^{-2}13.14∗10−2 ,即 0.1314
📍 注意事项和细节说明:
- e/E 后面的指数必须为整数。
- e/E 后⾯如果是加号 + ,加号可以省略。
- 科学计数法⾥⾯ e/E 的前后,不能存在空格。
📝 合法的浮点数形式举例:
double a = 520.13e+2; //输出 52013.000000 double b = 520.e+3; //输出 520000.000000 double c = 520.0e-2; //输出 5.200000 double d = .1314e4; //输出 1314.000000
4.3 浮点型对应占位符
#include<stdio.h> int main() { float a = 2.5; double b = 9.99; long double c = 520.1314; printf("单精度浮点型 a = %f\n\n", a); printf("双精度浮点型 b = %lf\n\n", b); printf("长双精度浮点型 c = %llf\n\n", c); return 0; }
🚩 总结
数据类型 | 形式 | 占位符 |
float | 十进制 | %f |
double | 十进制 | %lf |
long double | 十进制 | %llf |
float | 指数形式 | %e 或 %E |
double | 指数形式 | %le 或 %lE |
long double | 指数形式 | %lle 或 %llE |
4.4 注意事项和细节说明
在实际开发中,我们都不会选用单精度浮点数float,因为该类型很容易导致精度丢失,导致计算错误。我们通常会采用精度更高的double类型。
📝 我们来看一个浮点数精度不准确造成的问题:
#include<stdio.h> int main() { double a = 0.1; double b = 0.2; if (a + b == 0.3) printf("精度未丢失"); else printf("精度丢失,a + b = %lf",a + b); return 0; }
是不是就很匪夷所思,这是因为由于底层存储小数不准确问题导致在计算时 a+b 的结果其实是无限接近于0.3的,但不等于0.3,因此 a+b == 0.3 为 假(false)。
❓ 你是不是不相信我说的话呀?因为你发现 在上图的输出中 的确输出的是 0.300000 呀,但其实呀,有这样一件事我需要和你说清楚,一个女孩说对你有好感❤️ ,可你却以为她是在说喜欢你,可是这是真的吗,其实你并未看到全部,只是你的自作多情和一厢情愿罢了。这里也是一样的道理,我们在打印数据的时候默认只打印到了小数点后六位,我们修改一下打印位数:
#include<stdio.h> int main() { double a = 0.1; double b = 0.2; if (a + b == 0.3) printf("精度未丢失"); else //我们这里是 .32lf 即打印到小数点后32位 printf("精度丢失,a + b = %.32lf", a + b); return 0; }
但是这个问题我们能够怎样解决呢?这里提供一种方式:
#include<stdio.h> int main() { double a = 0.1; double b = 0.2; if (a + b - 0.3 < 0.000001) printf("精度未丢失"); else //我们这里是 .32lf 即打印到小数点后32位 printf("精度丢失,a + b = %.32lf", a + b); return 0; }
5.字符型
5.1 基本使用说明
- 字符常量使用单引号
' '
括起来的单个字符。 - C还允许使用转义字符
\
来将其后的字符转变为特殊字符型常量。
5.2 字节大小
#include<stdio.h> int main() { printf("有符号字符型的字节大小:%lld\n", sizeof(char)); printf("无符号字符型的字节大小:%lld\n", sizeof(unsigned char)); return 0; }
🚩 总结
数据类型 | 字节大小 |
char | 1 |
unsigned char | 1 |
5.3 字符型对应占位符
数据类型 | 占位符 |
char | %c |
unsigned char | %c |
5.4 char的本质
关于更加具体的字符编码说明,查看文章:https://blog.csdn.net/qq_62982856/article/details/127440216?spm=1001.2014.3001.5502
- 计算机在存储字符时并不是真的要存储字符实体,而是存储该字符在字符集中的编号(也可以叫编码值)。对于 char 类型来说,它实际上存储的就是字符的 ASCII 码。
- 无论在哪个字符集中,字符编号都是一个整数;从这个角度考虑,字符类型和整数类型本质上没有什么区别。
- 我们可以给字符类型赋值一个整数,或者以整数的形式输出字符类型。反过来,也可以给整数类型赋值一个字符,或者以字符的形式输出整数类型。
char的本质是一个整数,在输出时,是 ASCII码表中对应的字符。
- 因此,可以直接给char赋一个
整型数据
,然后输出时,会按照该整数对应的ASCII字符输出。
#include<stdio.h> int main() { int b = 65; char a = b; //因为左边接收类型是 char,整数65对应的ASCII字符是 'A',因此 a 被赋值为 'A' printf("%c\n", a); // %c --> 以ASCII字符形式输出 printf("%d\n\n", a); // %d --> 以ASCII值形式输出 char d = 'D'; printf("%c\n", d); printf("%d\n\n", d); return 0; }
- char类型是可以进行运算的,相当于一个整数(对应规则来自ASCII表)
#include<stdio.h> int main() { char a = 'A'; char b = a + 1;//'A'对应整数 65,因此 a+1 为66,接收类型为 char,整数66对应的ASCII字符为 'B',因此 b 为 'B' int c = a + 1; //'A'对应整数 65,因此 a+1 为66,接受类型为 int,因此 c 为 66 printf("%d\n", b); // %d --> 以ASCII值形式输出 printf("%c\n\n", b); // %c --> 以ASCII字符形式输出 printf("%d\n", c); printf("%c\n\n", c); return 0; }
6.补充:布尔类型 bool
6.1 C89标准
C 语言标准 C89
没有定义布尔类型,所以 C 语言判断真假时以 0 为假(false),非 0 为真(true)
#include<stdio.h> int main() { int a = -1; if (a) // -1 是非0数,因此if语句成立为true printf("非0为真\n\n"); if (a + 1) // a+1的结果为0,因为0为假,所以if语句不成立为false printf("输出1:0为假\n\n"); else //因此执行 else语句 printf("输出2: 0为假\n\n"); if (a + 1 == 0) // a+1为0,则0==0说明if语句成立为true printf("a+1为0成立\n\n"); int b = 0; if (!b) // b是0,为false,!是取反操作,即false变true printf("取反为true输出\n\n"); return 0; }