Char 、Unsigned char 移位和转int 问题

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Char 、Unsigned char 移位和转int 问题今天小菊同学遇到了个问题,是关于char 移位之后转化为unsigned int 之后结果和预期不一样。

先讲讲char 和Unsigned char 的区别,首先在内存中两者没什么区别都是一个字节,唯一的区别是,char的首位是符号位和unsigned char 的首位是数字位,char能表示-128~127,unsigned char能表示 0~256。当char或unsigned char 移位的时候都会先转化为int型,转化的时候需要对char或unsigned char 进行扩展;如下代码:

char buffer = 0xF0;

Buffer >>2 ;

这时候buffer先会转为int 型然后在移位,转int型的时候,由于计算机里数值都是以补码形式存在,所以这个时候转化为int的Buffer 值应该为

0xFFFFFFF0(将-16以补码形式的表现),然后在做右移两位操作;

而如果是unsigned char buffer = 0xF0的话转化为Int还是0xF0,所以不会有影响;

不仅仅对于移位操作,还有很多运算符都会转化的,如下:

void foo(void)

{

unsigned int a = 6;

int b = -20;

(a+b>6)?puts(">6"):puts("<=6");//puts为打印函数

}

这个时候会b会隐式转化为 unsigned int类型变成了正数

上面的两个例子主要说明了两点:

1.

2.

在来讲讲C++的隐式转化问题:

C++定义了一组内置的类型对象之间的标准转换,在必要时它们被编译器隐式的应用到对象上。在算式转换保证了二元操作符,如加法或乘法的两个操作数被提升为共同的类型,然后再用它表示结果的类型。

1较宽的类型。

2

规则的定义如上面所述,这些规则定义了一个类型转换层次结构,我们从最宽的类型long double 开始,那么另一个操作数无论是什么类型都将被转换成long double .如果两个操作数都不是long double 型,那么若其中一个操作数的类型是double 型,则另一个就被转换成double 型。例如:

int ival;

float fval;

double dval;

dval + fval + ival //在计算加法前fval和ival都被转换成double

否则如果两个操作数都不是3种浮点类型之一,它们一定是某种整值类型。在确定共同的目标提升类型之前,编译器将在所有小于int 的整值类型上施加一个被称为整值提升的过程。

在进行整值提升时类型char、signed char、unsigned char和short int 都被提升为类型int 。如果机器上的类型空间足够表示所有unsigned short 型的值,这通常发生在short用半个字而int 用一个字表示的情况下,则unsigned short int 也被转换成int 否则它会被提升为unsigned int 。wchar_t 和枚举类型被提升为能够表示其底层类型所有值的最小整数类型。在下列表达式中:

在确定两个操作数被提升的公共类型之前,cval found 和mval都被提升为int 类型。

一旦整值提升执行完毕,类型比较就又一次开始。如果一个操作数是unsigned long 型,则第二个也被转换成unsigned long 型。在上面的例子中所有被加到ulong上的3个对象都被提升为unsigned long 型。如果两个操作数类型都不是unsigned long型而其中一个操作数是long型,则另一个也被转换成long型。例如:

long类型的一般转换有一个例外。如果一个操作数是long型而另一个是unsigned int 型,那么只有机器上的long型的长度足以容纳unsigned int 的所有值时(一般来说,在32位操作系统中long型和int 型都用一长表示,所以不满足这里的假设条件),unsigned int 才会被转换为long型,否则两个操作数都被提升为unsigned long 型。若两个操作数都不是long型而其中一个是unsigned int 型,则另一个也被转换成unsigned int 型,否则两个操作数一定都是int 型。

一般来说各种类型的长度关系

为 long double > double > float >= int >= short > char,

unsigned > signed 。

尽管算术转换的这些规则带给你的困惑可能多于启发,但是一般的思想是尽可能地保留类型表达式中涉及到的值的精度。这下是通过把不同的类型提升到当前出现的最宽的类型实现的。

参考:/echoisland/article/details/6851686

隐式类型转换&& 负数的补码

偶然看到一道C++面试题:

void foo(void)

{

unsigned int a = 6;

int b = -20;

(a+b>6)?puts(">6"):puts("<=6");//puts为打印函数

}

问输出是什么?答案是输出>6。

这道题主要考察两个东西。

1.隐式类型转换:int型变量转化成unsigned int,b成了正数.

2.负数的补码:计算机系统中的数值是以补码形式表示(存储)的。

一、C++隐式类型转换

C++定义了一组内置的类型对象之间的标准转换,在必要时它们被编译器隐式的应用到对象上。在算式转换保证了二元操作符,如加法或乘法的两个操作数被提升为共同的类型,然后再用它表示结果的类型。两个通用的指导原则如下:

1、为防止精度损失,如果必要的话,类型总是被提升为较宽的类型。

2、所有含有小于整形的有序类型的算术表达式在计算之前其类型都会被转换成整形。

规则的定义如上面所述,这些规则定义了一个类型转换层次结构,我们从最宽的类型long double 开始,那么另一个操作数无论是什么类型都将被转换成long double .如果两个操作数千不是long double 型,那么若其中一个操作数的类型是double 型,则另一个就被转换成double 型。例如:

int ival;

float fval;

double dval;

dval + fval + ival //在计算加法前fval和ival都被转换成double

类似地,如果两个操作数都不是double型而其中一个操作float型,则另一个被转换成float 型。例如:

char cval;

int ival;

float fval;

cval + ival + fval //在计算加法前ival和cval都被转换成float

否则如果两个操作数都不是3种浮点类型之一,它们一定是某种整值类型。在确定共同的目

标提升类型之前,编译器将在所有小于int 的整值类型上施加一个被称为整值提升的过程。

在进行整值提升时类型char、signed char、unsigned char和short int 都被提升为类型int 。如果机器上的类型空间足够表示所有unsigned short 型的值,这通常发生在short用半个字而int 用一个字表示的情况下,则unsigned short int 也被转换成int 否则它会被提升为unsigned int 。wchar_t和枚举类型被提升为能够表示其底层类型所有值的最小整数类型。在下列表达式中:

char cval;

bool found;

enum mumber{m1,m2,m3}mval;

unsigned long ulong;

cval + ulong;ulong + found; mval + ulong;

在确定两个操作数被提升的公共类型之前,cval found 和mval都被提升为int 类型。

一旦整值提升执行完毕,类型比较就又一次开始。如果一个操作数是unsigned long 型,则

第二个也被转换成unsigned long 型。在上面的例子中所有被加到ulong上的3个对象都被提升

相关文档
最新文档