本人本科在国内双非,现在就读土澳研究生,毕业后想从事关于c++相关方向,所以在学习c以及c++相关知识,由于本人本科阶段略微接触过c和c++,但都不深入,所以想通过博客进行知识的复习和深化。志同道合的朋友可以找我加个微信,学习上有伴也会减少孤独和迷茫。一下进入正题。
C
的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为
整型
提升
。
整型提升的意义
:
表达式的整型运算要在
CPU
的相应运算器件内执行,
CPU
内整型运算器
(ALU)
的操作数的字节长度
一般就是
int
的字节长度,同时也是
CPU
的通用寄存器的长度。
因此,即使两个
char
类型的相加,在
CPU
执行时实际上也要先转换为
CPU
内整型操作数的标准长
度。
通用
CPU
(
general-purpose CPU
)是难以直接实现两个
8
比特字节直接相加运算(虽然机器指令
中可能有这种字节相加指令)。所以,表达式中各种长度可能小于
int
长度的整型值,都必须先转
换为
int
或
unsigned int
,然后才能送入
CPU
去执行运算。
概念看上去晦涩难懂,用人话表示就是char 和 short在使用时要从1字节或2字节扩充到int的长度即4字节。
如何进行整体提升呢?
整形提升是按照变量的数据类型的符号位来提升的
整形提升的例子
:
//
负数的整形提升
char
c1
= -
1
;
变量
c1
的二进制位
(
补码
)
中只有
8
个比特位:
1111111
因为
char
为有符号的
char
所以整形提升的时候,高位补充符号位,即为
1
提升之后的结果是:
11111111111111111111111111111111
//
正数的整形提升
char
c2
=
1
;
变量
c2
的二进制位
(
补码
)
中只有
8
个比特位:
00000001
因为
char
为有符号的
char
所以整形提升的时候,高位补充符号位,即为
0
提升之后的结果是:
00000000000000000000000000000001
//
无符号整形提升,高位补
0
//
实例
1
int
main
()
{
char
a
=
0xb6
; //10110110
short
b
=
0xb600
; //1011011000000000
int
c
=
0xb6000000
;
if
(
a
==
0xb6
)
printf
(
"a"
);
if
(
b
==
0xb600
)
printf
(
"b"
);
if
(
c
==
0xb6000000
)
printf
(
"c"
);
return
0
;
}
实例
1
中的
a,b
要进行整形提升
,
但是
c
不需要整形提升
a,b
整形提升之后
,
变成了负数
,
所以表达式
a==0xb6
,
b==0xb600
的结果是假
,
但是
c
不发生整形提升
,
则表 达式 c==0xb6000000
的结果是真
.
所程序输出的结果是
:
c,另外也可以根据char的取值范围为-128-127,而a已经等于182超出范围实际值等于-74来看。
//
实例
2
int
main
()
{
char
c
=
1
;
printf
(
"%u\n"
,
sizeof
(
c
));
printf
(
"%u\n"
,
sizeof
(
+
c
));
printf
(
"%u\n"
,
sizeof
(
-
c
));
return
0
;
}
实例
2
中的
,c
只要参与表达式运算
,
就会发生整形提升
,
表达式
+c
,
就会发生提升
,
所以
sizeof(+c)
是
4
个字
节
.
表达式
-
c
也会发生整形提升
,
所以
sizeof(
-
c)
是
4
个字节
,
但是
sizeof(c)
,
就是
1
个字节
.
//实例3
int main(){
char a = 3;
// //00000000000000000000000000000011
// //00000011-截断
char b = 127;
// //00000000000000000000000001111111
// //01111111-截断
//
char c = a + b;
// //00000000000000000000000000000011
// //00000000000000000000000001111111
// //00000000000000000000000010000010
// //10000010 - c
// //整型提升
printf("%d\n", c);
// //11111111111111111111111110000010
// //11111111111111111111111110000001
// //10000000000000000000000001111110
// //-126
//
return 0;
//}
}