最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解C++移位運(yùn)算符

 更新時(shí)間:2016年05月31日 15:40:17   投稿:jingxian  
下面小編就為大家?guī)硪黄钊肜斫釩++移位運(yùn)算符。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

關(guān)于邏輯移位、算術(shù)移位可參見迅雷深大筆試題部分。的一道題。

以前看到C++標(biāo)準(zhǔn)上說,移位運(yùn)算符(<<、>>)出界時(shí)的行為并不確定:

The behavior is undefined if the right operand is negative, orgreater than or equal to the length in bits of the promoted left operand.

我當(dāng)時(shí)也沒有深究過這個(gè)問題。前幾天有個(gè)網(wǎng)友來信問起這件事,我才發(fā)現(xiàn),這和IntelCPU的移位運(yùn)算有關(guān)。下面是那位網(wǎng)友的來信以及我的回復(fù):

您好!運(yùn)算符<<作為位操作中的高效的操作,但我遇到一個(gè)問題:下面在VC環(huán)境下發(fā)現(xiàn)一個(gè)很不明白的地方,下面標(biāo)注。

#include <stdio.h>

void main()

{

  unsigned int i,j;

  i=35;

 

  //為什么下面兩個(gè)左移操作結(jié)果不一樣?

  j=1<<i; // j為8

  j=1<<35; // j為0

}

不知是哪里沒有理解對(duì)。

原因是這樣的:i=35;j=1<<i;這兩句在VC沒有做優(yōu)化的情況下,將被編譯成下面的機(jī)器指令:

mov dword ptr [i],23h

mov eax,1

mov ecx,dword ptr [i]

shl eax,cl

mov dword ptr [j],eax

在shl一句中,eax=1,cl=35。而IntelCPU執(zhí)行shl指令時(shí),會(huì)先將cl與31進(jìn)行and操作,以限制左移的次數(shù)小于等于31。因?yàn)?5 & 31 =3,所以這樣的指令相當(dāng)于將1左移3位,結(jié)果是8。

而j=1<<35;一句是常數(shù)運(yùn)算,VC即使不做優(yōu)化,編譯器也會(huì)直接計(jì)算1<<35的結(jié)果。VC編譯器發(fā)現(xiàn)35大于31時(shí),就會(huì)直接將結(jié)果設(shè)置為0。這行代碼編譯產(chǎn)生的機(jī)器指令是:

mov dword ptr [j],0

對(duì)上面這兩種情況,如果把VC編譯器的優(yōu)化開關(guān)打開(比如編譯成Release版本),編譯器都會(huì)直接將結(jié)果設(shè)置為0。

所以,在C/C++語言中,移位操作不要超過界限,否則,結(jié)果是不可預(yù)期的。

http://hovertree.com/menu/cpp/

下面是Intel文檔中關(guān)于shl指令限制移位次數(shù)的說明:

The destination operand can be a register or a memory location.The count operand can be an immediate value or register CL. The count is maskedto 5 bits, which limits the count range to 0 to 31. A special opcode encodingis provided for a count of 1.

1.掩碼

就是一串2進(jìn)制 對(duì)目標(biāo)字段進(jìn)行位與運(yùn)算,屏蔽當(dāng)前的輸入位。

將源碼與掩碼經(jīng)過邏輯運(yùn)算得出新的操作數(shù)。其中要用到邏輯運(yùn)算如OR運(yùn)算。AND運(yùn)算。用于如將ASCLL碼中大寫字母改作小寫字母。

2.與 或 異或 轉(zhuǎn)換成補(bǔ)碼運(yùn)算

3.  用法:掩碼 (&)

4. 用法:打開位 (|)

5.用法:關(guān)閉位 (&~)

6. 用法:轉(zhuǎn)置位 (^)

7. 將Value的第bit_number位置1       Value |= 1 << bit_number;

8. 將Value的第bit_number位置0       Value &= ~( 1 << bit_number );

9.value & 1 << bit_number 如果該位置已被置為1,則表達(dá)式的結(jié)果為非零值

C/C ++提供位邏輯運(yùn)算符和移位運(yùn)算符。二者只能用于整形和字符型。位運(yùn)算符是對(duì)每位進(jìn)行操作而不影響左右兩位,這有別于常規(guī)運(yùn)算符(&&|| !)是將整個(gè)數(shù)進(jìn)行操作的。

一.    位邏輯運(yùn)算符

1.    ~ 按位取反

將1變?yōu)?,將0變?yōu)?

EG:

~(10011010)

(01100101)

注:

VC++編譯器,計(jì)算~10,得出的結(jié)果是-11。為什么不是5呢

10的二進(jìn)制表示為1010,按位取反應(yīng)該為0101,也就是十進(jìn)制的5,為什么會(huì)得出-11?

VC是32位編譯器,所以

10 = 00000000 00000000 00000000   00001010

~10 = 11111111 11111111   11111111   11110101 =   -11

可以通過掩碼(位與) 與15位與

   15 = 00000000 00000000 00000000   00001111

~10 = 00000000 00000000 00000000   00000101   =   -11

2.    & 按位取與

只有兩個(gè)操作數(shù)都是1結(jié)果才是1,否則為0

10 = 00000000 00000000 00000000   00001010

12 = 00000000 00000000 00000000   00001100

&

8 = 00000000 00000000 00000000   00001000

3.    | 按位取或

兩個(gè)操作數(shù)任意一位為1結(jié)果就是1

10 = 00000000 00000000 00000000   00001010

12 = 00000000 00000000 00000000   00001100

|

14 = 00000000 00000000 00000000   00001110

4.    ^ 按位異或

兩個(gè)操作數(shù)不同為1,相同為0

10 = 00000000 00000000 00000000   00001010

12 = 00000000 00000000 00000000   00001100

^

14 = 00000000 00000000 00000000   00000110

5.    用法:掩碼

掩碼是通過&(位與)將某些位設(shè)置為開(1),將某些位設(shè)置為關(guān)(0)。將掩碼0看做不透明,將1看著透明。

EG:

如只顯示第二、三位

107 = 0110 1011

6            = 0000 0110

&

2   = 0000 0010

       

6.    用法:打開位

打開位是通過 |(位或)打開一個(gè)值的特定位,同時(shí)保持其他位的不變。這是因?yàn)楹?位或都為0,和1位或都為1。

EG:

如只打開第二、三位

107 = 0110 1011

6   = 0000 0110

|

111 = 0110 1111

7.    用法:關(guān)閉位

關(guān)閉某些位

EG:

如關(guān)閉第二、三位

107 = 0110 1011

6    = 0000 0110

& ~

105 = 0110 1001

8.    用法:轉(zhuǎn)置位

如果一位為1則轉(zhuǎn)置為0,如果一位為1則轉(zhuǎn)置為0

EG:

如轉(zhuǎn)置第二、三位

107 = 0110 1011

6    = 0000 0110

^

105 = 0110 1101

       

二.    移位運(yùn)算符

  1. << 左移

左移運(yùn)算符是把操作數(shù)的值的每一位向左移動(dòng),移動(dòng)的位數(shù)有右邊的操作數(shù)決定,右側(cè)空出的位數(shù)用0填充

EG:

如轉(zhuǎn)置第二、三位

107 = 0110 1011 <<2

<<

172 = 1010 1100

      

       在計(jì)算機(jī)中由于是32位的

107 = 0000 0000   0000 0000   0000 0000   0110 1011 <<2

<<

428 = 0000 0000   0000 0000   0000 0001   1010 1100

  1. >> 右移

右移運(yùn)算符是把操作數(shù)的值的每一位向右移動(dòng),移動(dòng)的位數(shù)有右邊的操作數(shù)決定,左邊丟棄的位數(shù)用0填充

EG:

如轉(zhuǎn)置第二、三位

107 = 0110 1011 >>2

>>

26 = 0001 1010

一、傳統(tǒng)的C方式位操作:

1.基本操作:

   使用一個(gè)unsigned int變量來作為位容器。

2.操作符:

|   按位或操作符:result=exp1|exp2;當(dāng)exp1和exp2中對(duì)應(yīng)位中至少有一個(gè)為1時(shí),result中對(duì)應(yīng)位為1,否則為0。

&  按位與操作符::result=exp1&exp2;當(dāng)exp1和exp2中對(duì)應(yīng)位全為1時(shí),result中對(duì)應(yīng)位為1,否則為0。

^  按位異或或操作符:result=exp1^exp2;當(dāng)exp1和exp2中對(duì)應(yīng)位不相同時(shí),result中對(duì)應(yīng)位為1,否則為0。

~  反轉(zhuǎn)操作符:將位容器中的所有位都反轉(zhuǎn),1變?yōu)?,0變?yōu)?。

<< 按位左移操作符:exp<<n,將容器中所有的位向左移n位,空出的位用0填充。

>> 按位右移操作符:exp>>n,將容器中所有的位向右移n位,空出的位用0填充。

|=,&=,^= 分別對(duì)應(yīng)|&^三種操作符的復(fù)合操作符。

3.常用操作

   這里我們假設(shè)有一個(gè)result的unsigned int變量用來儲(chǔ)存32個(gè)學(xué)生的成績(jī)(通過和不通過分別用0和1),這樣result就有33位(result從右至左,從0開始計(jì)算位數(shù),在這個(gè)例子中0位被浪費(fèi))。

(a) 將第27位設(shè)置為及格(設(shè)作1)其他位不變:

   result|=(1<<27) //任意的位值與1作按位或操作其值為1,而與0作按位與操作其值不變

(b) 將第27位設(shè)置成不及格(設(shè)為0)。

   result&=~(1<<27) //任意的位值與0作按位與操作其值為0,而與1作按位與操作其值不變

(c) 反轉(zhuǎn)第27位的值。

   result^=(1<<27) //任意的位值與1作按位異或操作其值為1,而與0作按位異與操作其值不變

二、C++中的bitset容器

1.頭文件:

  #include <bitset>

2.聲明一個(gè)容器:

 (a)聲明一個(gè)指定位數(shù)的空容器(所有位設(shè)為0): bitset<int> bits;

 (b)聲明一個(gè)指定位數(shù)并將指定的幾個(gè)位初始化為相應(yīng)值的容器: bitset<n> bits(int);

     bitdet<int> bits(string&)

總結(jié):bitset模板類中類型參數(shù)傳遞容器的位數(shù),而構(gòu)造函數(shù)參數(shù)通過一個(gè)int或一個(gè)string&值來從右至左初始化容器中的相應(yīng)值。

3.bitset的基本用法:

操作

功能

用法

test(pos)

pos位是否為1?

a.test(4)

any()

任意位是否為1?

a.any()

none()

是否沒有位為1?

a.none()

count()

值是1的位的小數(shù)

count()

size()

位元素的個(gè)數(shù)

size()

[pos]

訪問pos位

a[4]

flip()

翻轉(zhuǎn)所有位

a.flip()

flip(pos)

翻轉(zhuǎn)pos位

a.flip(4)

set()

將所有位置1

a.set()

set(pos)

將pos位置1

a.set(4)

reset()

將所有位置0

a.reset()

reset(pos)

將pos位置0

a.reset(4)

4.bitset與傳統(tǒng)C位操作及字符串的轉(zhuǎn)換

   可以通過to_string()成員將容器轉(zhuǎn)輸出為一個(gè)string字符串,另外還可以用to_long()成員將容器輸出到傳統(tǒng)的用于C風(fēng)格的位容器中。如:

  unsigned long bits = bits.to_long();

  sting str(bits.to_string());

以上這篇深入理解C++移位運(yùn)算符就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++基于遞歸和非遞歸算法求二叉樹鏡像的方法

    C++基于遞歸和非遞歸算法求二叉樹鏡像的方法

    這篇文章主要介紹了C++基于遞歸和非遞歸算法求二叉樹鏡像的方法,針對(duì)二叉樹遍歷結(jié)合實(shí)例形式分析了遞歸與非遞歸算法的實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2017-05-05
  • C語言算法的時(shí)間復(fù)雜度和空間復(fù)雜度

    C語言算法的時(shí)間復(fù)雜度和空間復(fù)雜度

    這篇文章主要介紹了C語言算法的時(shí)間復(fù)雜度和空間復(fù)雜度,算法在編寫成可執(zhí)行程序后,運(yùn)行時(shí)需要耗費(fèi)時(shí)間資源和空間(內(nèi)存)資源,更多相關(guān)需要的朋友可以參考一下
    2022-07-07
  • C語言繪制簡(jiǎn)單時(shí)鐘小程序

    C語言繪制簡(jiǎn)單時(shí)鐘小程序

    這篇文章主要為大家詳細(xì)介紹了C語言繪制簡(jiǎn)單時(shí)鐘小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解

    C語言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解

    這篇文章主要介紹了C語言中fchdir()函數(shù)和rewinddir()函數(shù)的使用詳解,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • 約瑟夫經(jīng)典問題擴(kuò)展成雙向約瑟夫問題

    約瑟夫經(jīng)典問題擴(kuò)展成雙向約瑟夫問題

    今天小編就為大家分享一篇關(guān)于約瑟夫經(jīng)典問題擴(kuò)展成雙向約瑟夫問題,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • c++命名對(duì)象和匿名對(duì)象的解析

    c++命名對(duì)象和匿名對(duì)象的解析

    像按值傳遞的對(duì)象(函數(shù)入?yún)?,函?shù)返回值)都是匿名對(duì)象,那匿名對(duì)象的特點(diǎn)是什么呢?下面通過實(shí)例代碼給大家解析c++命名對(duì)象和匿名對(duì)象的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-10-10
  • 五個(gè)嵌入式C語言中的實(shí)用技巧分享

    五個(gè)嵌入式C語言中的實(shí)用技巧分享

    這篇文章主要和大家分享一下五個(gè)嵌入式C語言中的實(shí)用技巧,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定的幫助,需要的可以參考一下
    2022-12-12
  • C++中std::thread線程用法

    C++中std::thread線程用法

    本文主要介紹了C++中std::thread線程用法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • C++使用TinyXML解析XML

    C++使用TinyXML解析XML

    本文詳細(xì)講解了C++使用TinyXML解析XML的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • C++入門概覽和嘗試創(chuàng)建第一個(gè)C++程序

    C++入門概覽和嘗試創(chuàng)建第一個(gè)C++程序

    這篇文章主要介紹了C++入門概覽和嘗試創(chuàng)建第一個(gè)C++程序,同時(shí)也包括編寫類的示例展示C++面向?qū)ο蟮奶匦?需要的朋友可以參考下
    2015-09-09

最新評(píng)論

焉耆| 祁东县| 磐安县| 客服| 中卫市| 临武县| 射阳县| 西平县| 南宫市| 霍山县| 余姚市| 清涧县| 安西县| 苏尼特左旗| 喀喇沁旗| 安宁市| 土默特右旗| 宿州市| 霞浦县| 新乡县| 龙川县| 重庆市| 广饶县| 内丘县| 博乐市| 红河县| 栖霞市| 中阳县| 临邑县| 锡林浩特市| 浙江省| 阜城县| 麻阳| 泰安市| 都匀市| 阿城市| 石嘴山市| 云梦县| 杨浦区| 十堰市| 搜索|