c语言学习笔记(8)位运算符,++,--运算符的用法

摘要:总结了位运算符,++,--运算符的用法,给出了一个使用异或方法巧解面试题的例子,分析了贪心法的规则。


一、位运算符用法

    c语言中的位运算符主要有以下几种:

   c语言学习笔记(8)位运算符,++,--运算符的用法_第1张图片

    使用的时候主要有以下几个注意点:

    1.左移运算符将<<将运算数的二进位左移,高位丢弃,低位补零。

    2.右移运算符将>>将运算数的二进位右移,低位丢弃,高位补零。

    3.避免位运算符,逻辑运算符和数学运算符出现在同一个表达式中,如果要在同一个表达式中出现,那么需要用括号来表达运算次序。

    4.左移n位相当于乘以2的n次方,右移n位相当于除以2的n次方,但是他们的运算效率要比数学运算符高。


不用第三个中间变量实现两个数的交换

    方法1:

    a=a+b;

    b=a-b;

    a=a-b;

    方法2:

    a=a^b;

    b=a^b;

    a=a^b;


    面试题解析

    有一个数列,其中的自然数都是以偶数的形式出现,只有一个自然数出现的次数为奇数次。编写程序找出这个自然数。

    最简单的方法使用异或方法,如下:

#include 
 
#define SIZE(a) sizeof(a)/sizeof(*a)
 
int a[]={1,2,3,4,5,2,3,4,5,1,1,1,1,1,2};
 
int main(void)
{
    intresult=0;
    inti=0;
   
    for(i=0;i

    这主要运用了两个规则:第一,自己和自己异或等于0;第二:异或具有交换律的特性。

 

    1<<32位的结果是什么?1<<-1的结果是什么?

#include 
 
int main(void)
{
   
    printf("%d\n",1<<32);
    printf("%d\n",1<<-1);
   
    return0;
}

编译出现如下错误:

    其实这个是可以理解的,因为我们数据int时32位的,这样就越界了,负数这里不允许移位,在我看来也没有什么具体的意义,如有知道的大侠可以告知。


二、++和—运算符的用法

    

先看一个例子:

    i=3;(++i)+(++i)+(++i)等于多少?

    答案一定不是15,而是根据编译器的规则,一般是16,也可能是18。第一种,它结合前两个,先++i两次使得i=5,,再两者相加等于10,然后再计算最后一个++i,这时候i=6,然后再全部相加=16.第二种,它直接将三个括号里面的++i先计算,使得i=6,然后三者相加=18。具体哪一种根据编译器来决定,这属于c语言的灰色地带,为什么是灰色地带,因为一般没有人这么写。。。

    其实++和—我们用的已经很熟练,但是这里有一个贪心法,还是蛮有意思,规则如下:

    1.编译器处理的每个符号,应该尽可能多的包含字符。

    2.编译器以从左向右的顺序一个一个尽可能多的读入字符。

    3.当即将读入的字符不可能和已读入的字符组成合法符号为止。

    4.为了避免贪心发造成的混淆,我们可以适当的使用空格将字符断开。


    贪心法的例子

    c=a+++b;编译器会从左到右,尽可能的多读,这样就变成了a++ + b,如果a=1,b=2,那么最终c的值是3,a变为2,因为a++是先取走a的值再自增1。

    同时,为什么我们写成/*的形式之后,后面接着的字符全部变为了注释,这样是贪心法和注释规则导致的。

    这部分比较简单,就总结到这里,如有不正确的地方还请指出,大家共同进步。

你可能感兴趣的:(C)