c语言数值类型与字长的理解
c语言数据类型
数据声明与字长
1.首先字长是计算机可以处理的二进制数的位数,字节是基本单位,一字节等于8位,1位是0或1。
2.关于int,short,long,long long , unsigned声明与可处理二进制数位数的关系:
首先提醒:
如-3:可以表示为,10000011,其中最左边的那个数所在的位置叫符号位,在没有声明为unsigned的情况下,符号位默认为最左边那位二进制数所占位置,若有unsigned,则不存在符号位。
eg:以64位计算机为例,int处理数据并将其转化为二进制数,为32位的二进制数,而long long 为至少为64位二进制数表示的数字
我的意思就是,如果拿应该给long声明处理的超大数据,在printf时使用%d占位符,不用%ld占位符,就会使这个数据被截断,即截断前32位表示成10进制数后输出,不能通过完整的64位二进制数转化位十进制数后输出
3.当然%d可以完整输出的数据,用%ld也可以完整输出,没问题的
源码反码和补码
1.首先,我们说说,int表示的最大正数数/最小负数是多少,(64位操作系统的情况下)根据二进制和十进制的转换:
正数的范围:最大的正数是符号位为0,其余位全为1的情况。对于 32 位的int,最大正数的二进制表示为01111111 11111111 11111111 11111111。
如下图:

对于有unsigned前缀声明的变量,没有符号位,32位都是二进制,所以直接2的32次幂。
所以最大整数就是:

2.有关源码反码和补码
为了计算的方便,诞生了这个概念:
计算:
5-3=2,在计算机内被转化为:
5+(-3)=2
可能有些抽象,我先来定义一下这几个概念:


在计算方面:
5-3的计算,就相当于5的二进制数加上3的二进制数的补码,可以化减法为加法

可移植类型:<stdint.h>和<inttypes.h>
详细说明,见C prime plus教材48页
这里进行补充:
1.这两种库的区别:

2.输出宏和占位符的区别:

浮点数后缀解释
是的,正如你所理解的那样。如果你声明一个 float
类型的变量并给它赋一个没有加后缀 f
的浮点数(比如 11.0
),那么这个数会被默认当作 double
类型来处理,而不是 float
。这种情况下,虽然你声明的是 float
类型的变量,但浮点常量(比如 11.0
)默认是 double
类型,所以在赋值时会发生隐式转换,将 double
转换为 float
。
流程
没有
f
后缀时:11.0
被当作double
类型。赋值给float
类型变量时会发生类型转换(从double
转为float
),这个过程中可能会有精度丢失,因为float
的精度比double
要低。加上
f
后缀时:11.0f
被明确当作float
类型,直接赋值给float
类型的变量时,没有类型转换,避免了精度损失。
内存处理:
- 在内存中,
double
类型的数据通常占 8 字节,而float
类型占 4 字节。所以如果你不加f
后缀,虽然变量是float
,但是你给它赋的double
数值会先被存储为double
,然后再强制转换为float
存储,可能会丢失一些精度。
举个例子:
1 |
|
结论:
- 没有
f
后缀:浮点常量11.0
会被视为double
类型,赋值给float
类型时会进行类型转换。 - 加上
f
后缀:常量被明确作为float
类型,避免了隐式转换。
这样,当你希望显式控制数据的类型时,加上后缀 f
是非常重要的,特别是在性能要求较高或精度敏感的场合。
补充:
你可以通过统一声明为 float
类型,并加上 f
后缀来控制常量的类型,这样可以避免隐式类型转换时造成的精度损失。
然而,是否选择 float
作为默认类型,需要根据你的实际需求来判断。如果需要更高的精度,double
可能会是更好的选择,因为它的精度更高且范围更大。
转换说明(%转换字符)
在 C 语言中,浮点数的转换说明符(也叫转换字符)用于格式化 float
、double
和 long double
类型的数据。以下是与浮点数相关的常见转换说明符:
1. %f
:标准浮点数表示
- 用于以小数点形式显示浮点数。
- 默认保留 6 位小数,可通过指定精度改变小数位数。
示例:
1 | float f = 3.14159; |
2. %e
或 %E
:科学计数法表示
- 用于以科学计数法(指数形式)表示浮点数。
%e
使用小写e
表示指数,%E
使用大写E
表示指数。
示例:
1 | double d = 12345.6789; |
3. %g
或 %G
:自动选择简洁表示
- 自动在
%f
和%e
之间选择最简洁的表示形式。 %g
使用小写e
,%G
使用大写E
(当选择科学计数法时)。
示例:
1 | double d = 0.000123456; |
4. %a
或 %A
:十六进制浮点数表示(C99 标准引入)
- 用于以十六进制表示浮点数,指数以
p
或P
表示(表示 2 的幂次)。 %a
使用小写字母,%A
使用大写字母。
示例:
1 | double d = 123.456; |
5. %Lf
、%Le
、%Lg
:用于 long double
- 当处理
long double
类型时,需要在标准说明符前加L
前缀。%Lf
:以小数点形式输出long double
。%Le
:以科学计数法输出long double
。%Lg
:以最简洁的形式输出long double
。
示例:
1 | long double ld = 3.141592653589793238L; |
6. 宽度与精度控制
可以通过格式说明符进一步控制输出的宽度和精度:
%m.nf
:指定总宽度m
和小数部分的位数n
。m
:整个数值占的最小宽度,不足时补空格。n
:小数部分的位数。
示例:
1 | double d = 123.456; |
小结
转换字符 | 含义 |
---|---|
%f |
按小数点形式输出浮点数 |
%e /%E |
按科学计数法输出浮点数 |
%g /%G |
自动选择 %f 或 %e 的简洁形式 |
%a /%A |
按十六进制表示浮点数(C99) |
%Lf |
以小数点形式输出 long double |
%Le |
以科学计数法输出 long double |
%Lg |
以最简洁形式输出 long double |
%o |
输出整数的八进制形式 |
%#o |
输出带有0 前缀的八进制形式 |
根据需要选择合适的格式化符来输出浮点数。 | |
注意:float和double都是用%e或%E直接表示科学计数法形式 |