C語言移位知識小結

2021-07-29 01:19:37 字數 4042 閱讀 4155

關於c語言移位功能的知識小結如下:

1,進行2的n次方計算,使用移位效率會提公升很多;

2,移位有時候會導致資料丟失,但有時候這正是我們要的功能;

3,右移位操作是不可移植的;

4,移位的操作符好是負數的時候,行為不確定。

關於第4點進行一點簡單的驗證,寫**如下:

#include"stdio.h"

int main(void)

unsigned int a = 1;

printf("left move 5 bit:%d\n",a << 5);

printf("left move -5 bit:%d\n",a << -5);

return 0;

**編譯執行結果:

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>gcc exp02.c

exp02.c: infunction 'main':

exp02.c:8:2:warning: left shift count is negative

printf("left move -5 bit: %d\n",a<< -5);

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>a

left move 5 bit:32

left move -5 bit:134217728

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>python

python 3.6.0(v3.6.0:41df79263a11, dec 23 2016, 08:06:12) [msc v.1900 64 bit (amd64)] onwin32

>>>bin(134217728)

'0b1000000000000000000000000000'

>>>len(bin(134217728)) - 2

專門加入了python處理了一下結果,得出結論如下:

1,移位操作符是5的時候,計算正常沒有什麼需要**的;

2,移位運算元是5的時候,實際的運算是左移操作了27位,這事兒很詭異的用法。很多書中會把這種操作定義為一種未定義的操作,因為不同的平台不同編譯器會有不同的行為。如果非得找什麼規律,單純的乙個驗證能夠腦補出來的也不過是27 + 5的值為32,正好是int長度。

增加一段**測試,**如下;

#include"stdio.h"

int main(void)

unsigned int a = 1;

printf("left move 6 bit:%d\n",a << 6);

printf("left move -6 bit:%d\n",a << -6);

return 0;

編譯與執行結果:

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>gcc exp02.c

exp02.c: infunction 'main':

exp02.c:8:2:warning: left shift count is negative

printf("left move -6 bit: %d\n",a<< -6);

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>a

left move 6 bit:64

left move -6 bit:67108864

e:\workspace\02_技術實踐\01_程式語言\01_c語言\02_c和指標\exp02>python

python 3.6.0(v3.6.0:41df79263a11, dec 23 2016, 08:06:12) [msc v.1900 64 bit (amd64)] onwin32

>>>len(bin(67108864)) - 2 - 1

從上面的結果還真看出了這個結論,如此初步得出的結論是:在windows平台下使用gcc編譯的時候這個功能類似於迴圈右移。而我用的作業系統是windows 10 hb,而編譯器的具體版本資訊如下:

using built-inspecs.

collect_gcc=gcc

target:i686-w64-mingw32

configured with:../../../src/gcc-4.9.2/configure --host=i686-w64-mingw32--build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32--with-gxx-include-dir=/mingw32/i686-w64-mingw32/include/c++ --enable-shared--enable-static --disable-multilib --enable-languages=c,c++,fortran,lto--enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp--enable-libatomic --enable-lto --enable-graphite --enable-checking=release--enable-fully-dynamic-string --enable-version-specific-runtime-libs--enable-sjlj-exceptions --disable-isl-version-check--disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug--disable-bootstrap --disable-rpath --disable-win32-registry --disable-nls--disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686--with-tune=generic --with-libiconv --with-system-zlib--with-gmp=/opt/build/prerequisites/i686-w64-mingw32-static--with-mpfr=/opt/build/prerequisites/i686-w64-mingw32-static--with-mpc=/opt/build/prerequisites/i686-w64-mingw32-static--with-isl=/opt/build/prerequisites/i686-w64-mingw32-static--with-cloog=/opt/build/prerequisites/i686-w64-mingw32-static--enable-cloog-backend=isl --with-pkgversion='i686-posix-sjlj, built bystrawberryperl.com project' cflags='-o2 -pipe-i/opt/build/i686-492-posix-sjlj-rt_v402/mingw32/opt/include-i/opt/build/prerequisites/i686-zlib-static/include-i/opt/build/prerequisites/i686-w64-mingw32-static/include' cxxflags='-o2 -pipe-i/opt/build/i686-492-posix-sjlj-rt_v402/mingw32/opt/include-i/opt/build/prerequisites/i686-zlib-static/include-i/opt/build/prerequisites/i686-w64-mingw32-static/include' cppflags=ldflags='-pipe -l/opt/build/i686-492-posix-sjlj-rt_v402/mingw32/opt/lib-l/opt/build/prerequisites/i686-zlib-static/lib -l/opt/build/prerequisites/i686-w64-mingw32-static/lib-wl,--large-address-aware'

thread model:posix

gcc version 4.9.2(i686-posix-sjlj, built by strawberryperl.com project)

C語言知識小結

c語言小結 1.概述 源程式.c 目標程式.obj 可執行目標程式.exe 2.資料型別 運算子 表示式 基本型別 整型,字元型,浮點型 構造型別 陣列,結構,聯合,列舉 指標型別 空型別變數命名的規定 只能由字母,數字,下劃線組成,第乙個字元必須為字母或下劃線 整型資料 int 4個位元組 範圍 ...

C語言知識小結(五)

二維陣列 二維陣列的定義 型別 陣列名 常量表示式 常量表示式 例如 int a 2 3 float b 3 4 二維陣列的引用 陣列名 下標 下標 例如 a 4 3 二維陣列的初始化 1 分行給二維陣列賦初值 定義的時候賦值 int a 3 4 2 將所有的陣列放在乙個括號內 int a 3 4 ...

C語言 指標相關知識小結

1.int p null 和 p null的區別 int p null指的是將乙個指標初始化為null,具體過程為 int p p null。2.a與a的區別 inta 5 int p a int q a 這樣的 對嗎?解釋 a得到陣列的位址。a表示陣列首元素的首位址。a的a的值一樣,兩個指向的位置...