面试题:运算符优先级

#include <iostream>
using namespace std;

int main(){
	unsigned char a=0xA5;
	unsigned char b=~a>>4+1;
	printf("%d\n",b);
    return 0;
}

首先是运算符优先级:=、~、>>和+优先级顺序是怎样的

运算符优先级和口诀:

一共有十五个优先级: 

1   ()  []  .  ->

2   !  ~   -(负号) ++  --   &(取变量地址)*   (type)(强制类型)    sizeof 

3   * / %

4   + - 

5   >> <<  

6   > >= < <= 

7   == !=   

8   &  

9   ^   

10  |   

11  &&

12  ||

13  ?:

14   =  +=  -=  *=  /=   %=  |=   ^=   &=   >>=   <<=

15  ,

结合性:2   13  14  是从右至左   其他都是  从左至右

口诀:
括号成员第一;        //括号运算符[]() 成员运算符.  ->

全体单目第二;        //所有的单目运算符比如++、 --、 +(正)、 -(负) 、指针运算*、&乘除余三,加减四;   //这个"余"是指取余运算即%

移位五,关系六;    //移位运算符:<< >> ,关系:> < >= <= 等

等于(与)不等排第七;    //即== 和!=

位与异或和位或;    //这几个都是位运算: 位与(&)异或(^)位或(|)    

"三分天下"八九十;  

逻辑或跟与;            //逻辑运算符:|| 和 &&

十二和十一;            //注意顺序:优先级(||)  底于 优先级(&&) 

条件高于赋值,        //三目运算符优先级排到13 位只比赋值运算符和","高

逗号运算级最低!    //逗号运算符优先级最低 


所以优先级顺序是:~、+大于>>大于=,先做a的取反操作,然后4+1为5,然后~a>>5,然后赋值给b

下面,如果按照我们的常识,a取反右移5位应该是2才对,但是答案是250,对250分析可知,当~a右移时,前面补的是1,而不是0,为什么呢?

因为,无论是unsigned char,还是unsigned short、short、char等,都是转换成int来处理的,一般情况下,int为32位,所以a取反后是ffffff5a,右移5位,前面补1(最高位为1,在计算机中认为是负数,补1,如果是unsigned int型的变量的话,前面补0),最后转化成unsigned char型,所以取后8位是fa,即250

可以用以下程序测试:

#include <iostream>
using namespace std;

int main(){
	unsigned char a=0xA5;
	printf("%08x\n",a);
	printf("%08x\n",~a);
	unsigned int b=~a>>5;
	printf("%08x\n",b);
    return 0;
}

#include <iostream>
using namespace std;

int main(){
	unsigned int a=0xA5;
	printf("%08x\n",a);
	printf("%08x\n",~a);
	unsigned int b=~a>>5;
	printf("%08x\n",b);
    return 0;
}

两者输出的b截然不同,第一个输出为fffffffa,第二个为07fffffa




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. What will be the output of the following C code? #include <stdio.h> int main(int argc, char* argv[]) { int b=3; int arr[] = {6, 7, 8, 9, 10}; int *ptr = arr; *(ptr++) += 123; printf("%d, %d\n", *ptr, *(++ptr)); return 0; } 2. 下面程序的结果是多少? #include <stdio.h> int main(int argc, char* argv[]) { unsigned char a = 0xA5; unsigned char b = ~a>>4; printf("b = %d\n", b); return 0; } 3. 下面程序的结果是: #include <stdio.h> int main(int argc, char* argv[]) { unsigned int a = 0xFFFFFFF7; unsigned char i = (unsigned char)a; char * b = (char *)&a; printf("%08x, %08x\n", i, *b); return 0; } 4. 用一个表达式,判断一个数X是否为2的N次方(2,4,8,…),不可用循环语句。 5. 下面程序的结果是: #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { int count = 0; int m = 9999; while(m){ count++; m = m & (m - 1); } cout << count << endl; return 0; } 6. 不用判断语句,找出两个数中比较大的。 7. 如何将a、b的值交互,且不用任何中间变量。 8. 在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”? 9. 头文件中的ifndef/define/endif的作用? #pragma once的作用? 10. 结构体内存对齐问题。 11. 以下代码的输出是? char var[10]; int test(char var[]){ return sizeof(var); } 12. 写出下面程序的运行结果。 int a[3]; a[0] = 0; a[1] = 1; a[2] = 2; int *p, *q; p = a; q = &a[2]; cout << a[q - p] << endl; 13. 解释下面这段代码: int (*a)[10]; a++; 14. 以下程序的输出是: int a[] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&a + 1); cout << *(a+1) << endl; cout << *(ptr - 1) << endl; 15. 什么是智能指针? 16. Please write out the program output. #include <stdlib.h> #include <time.h> #define LOOP 1000 int main(int argc, char* argv[]){ int rgnC = 0; srand((unsigned int)time(NULL)); for (int i=0; i<LOOP; i++){ int x = rand(); int y = rand(); if (x*x + y*y < RAND_MAX * RAND_MAX) rgnC++; } printf("%d\n", rgnC); return 0; } 17. 下面程序的输出结果是: #include <iostream> #include <string> using namespace std; class Base{ private: int m_i; int m_j; public: Base(int i):m_j(i), m_i(m_j){ } Base():m_j(0), m_i(m_j){ } int GetI(){ return m_i; } int GetJ(){ return m_j; } }; int main(int argc, char* argv[]){ Base base(98); cout << base.GetI() << endl << base.GetJ() << endl; return 0; } 18. 请讲述Heap与Stack的差别。 19. 写一个字符串拷贝函数strcpy;为什么strcpy的返回值类型为char *。 20. 如何判断一个单向链表是否有环路? 21. 写出判断ABCD四个表达式的是否正确,若正确, 写出经过表达式中 a的值。 int a = 4; (A)a += (a++); (B) a += (++a) ; (C) (a++) += a; (D) (++a) += (a++); 22. 下面程序的输出为: union{

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值