热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(转载)C语言右移运算符的问题(特别当与取反运算符一起时)

(转载)http:hi.baidu.comfanggaiitem1c44f1f2e3d81dc4a935a266关键词:C语言,右移运算符,右移运算符+取反运算符,算术右
(转载)http://hi.baidu.com/fanggai/item/1c44f1f2e3d81dc4a935a266

关键词:C语言,右移运算符,右移运算符+取反运算符,算术右移

环境:VC6.0

由一段C语言面试题引起,对其中的某些运算结果有疑惑,写了段小程序测试了下。
由下面的程序和输出结果得出一些结论:
1.位运算符不改变原变量的值,即无副作用;
2.进行取反运算~时,编译器会将char型转换为int型进行计算(VC6.0,其他编译器未测试),这时要特别注意,一般int型字节数比char型多,转换后高位为0,取反后为1,若后续有右移运算,则会将这些1移入,影响计算结果。

unsigned char a = 0xA5;
unsigned char b = ~a>>4;
printf("b= %d \n", b);//245

a = 0xA5取反后2进制表示为01011010,若按该数值进行右移运算>>4(无论是逻辑右移还是算术右移),则结果应为00000101,对应的十进制数应为5,而输出结果为245,这是为什么呢?
其实应该是这样的:
1)将a转换为int型(4字节),即00::0010100101(32位,::表示20个0);
2)将a取反,则变为11::1101011010(32位,::表示20个1);
3)a开始右移,右移4位,然后截取低8位赋值给b,即11110101,对应的十进制数值为245。

附测试程序如下:
#include
int main()
{

   unsigned char a = 0x11;//初始值最高位为0
unsigned char b = (~a)<<4;
printf("b= %d \n", b); //224
b = ~a<<4;
printf("b= %d \n", b); //224
b = ~(a<<4);
printf("b= %d\n",b); //239

b = (~a)>>4; //~优先级高于>>
printf("b= %d\n",b);//254
b = ~(a>>4);
printf("b= %d\n",b);//254
b = ~a>>4; //
printf("b= %d\n",b);//254


a = 0xA5; //初始值最高位为1
b = ~a>>4;
printf("b= %d \n", b);//245,

b = (~a)>>4;
printf("b= %d \n", b);//245,


a = 0xA5;
b = a>>4; //没有取反运算
printf("b = %d \n", b); //10,

return 0;                                                                  
}

3.判断VC6.0是逻辑右移还是算术右移

#include
int main()
{
  int i = 0x80028002;
  int j = i>>31;   // int型变量可以做移位运算
  printf("j= %d \n", j);  // -1,由此判定右移时还是算术右移
}

分析过程:

上述程序输出j = -1,则推断为算术右移。

1)i = 0x80028002的二进制表示1000 0000 0000 0010 1000 0000 0000 0010;

2)由于最高符号位为1,i右移31位,i的二进制表示1111 1111 1111 1111 1111 1111 1111 1111;

3)i的原码表示1000 0000 0000 0000 0000 0000 0000 0001,故i的值为-1。

欢迎讨论。

 

 


 

例子:

#include 

int main(int argc, char** argv)
{
    unsigned char a = 0xa5;
    unsigned char b = (~a) >> 4;

    char c = 0xa5;
    char d = (~c) >> 4;

    printf("%d\n", b);
    printf("%d\n", d);
    printf("\n");
    printf("%d\n", sizeof(~a));

    return 0;
}

程序输出:

b = ~a >> 4的运算顺序肯定是a先取反,但a是字符型,进行取反运算的时候编译器自动转换为int型,于是a变成int型。

然后取反,再进行右移4位操作,就可以得到这个结果了。其实用sizeof(~a)就可以检测出~a之后是int型。

总结:对char、unsigned char取反时,现将其提升为int类型,然后再进行取反。


推荐阅读
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
author-avatar
mobiledu2502917563
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有