位操作的方式有兩種: 一種是位運(yùn)算符埠居。一種是位字段
位運(yùn)算符
- 二進(jìn)制反碼或按位取反: ~
運(yùn)算符將1變?yōu)?,0 變?yōu)?
~(10011010) //表達(dá)式
(01100101) //結(jié)果值
#include <stdio.h>
int main(void)
{
unsigned char val = 2;
unsigned char newval;
newval = ~val;
printf(" %d \n", val); //注意該操作并不會(huì)改變原val的值
printf(" %d \n", newval);
return 0;
}
按位與: &
逐位對比兩個(gè)運(yùn)算對象持隧,生成一個(gè)新值碑隆。對于每個(gè)位瞬内,只有都為1時(shí)結(jié)果才為1
(10010011) & (00111101)
(00010001) //結(jié)果
C提供運(yùn)算符: &=
val &= 0377;
val = val & 0377;
這兩個(gè)相等按位或: |
逐位對比兩個(gè)運(yùn)算對象厘贼,生成一個(gè)新值颂龙。對于每個(gè)位,只要有一位是一就都是一
(10010011) | (00111101)
(10111111) //結(jié)果
C提供運(yùn)算符: |=
val |= 0377;
val = val | 0377;
這兩個(gè)相等按位異或: ^
逐位對比兩個(gè)運(yùn)算對象攒霹,對于每個(gè)位,如果兩個(gè)運(yùn)算對象中相應(yīng)的位一個(gè)為1(但不是兩個(gè)位1)浆洗,結(jié)果為1(簡單來說就是,這兩個(gè)位必須不相同)
(10010011) ^ (00111101)
(10101110) //結(jié)果
C提供運(yùn)算符: ^=
val ^= 0377;
val = val ^ 0377;
移位運(yùn)算符
- 左移: <<
將其左側(cè)運(yùn)算對象每一位的值向左移動(dòng)其右側(cè)運(yùn)算符對象指定的位數(shù)集峦,左側(cè)運(yùn)算對象移出左末端位的值丟失伏社,用0填充空出的位置
(10001010) << 2
(00101000) //結(jié)果值 - 右移: >>
對于無符號(hào)類型與左移一樣抠刺,對于有符號(hào)類型,其結(jié)果取決于機(jī)器摘昌∷傺空出的位置可用0填充,或用符號(hào)位(即聪黎,最左端的位)的副本填充:
位字段
操作位的第二種方法是位字段罕容。位字段是一個(gè)signed int 或unsigned int變量中的一組相鄰的位
struct box_props
{
bool opaque : 1;
unsigned int fill_color : 3;
unsigned int : 4;
bool show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned int : 2;
};
1
/**
* 編寫一個(gè)函數(shù),把二進(jìn)制字符串轉(zhuǎn)換為一個(gè)數(shù)值稿饰。例如,有下面語句:
* char * pbin = "01001001"
* 那么把pbin作為參數(shù)傳遞給該函數(shù)后锦秒,他應(yīng)該返回一個(gè)int類型的值25
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
int twototen(const char * ps);
int main(void)
{
int num;
char * pbin = "01001001";
num = twototen(pbin);
printf("%d", num);
return 0;
}
int twototen(const char * ps)
{
int val = 0;
while (*ps != '\0')
{
val = 2 * val + (*ps++ - '0');
}
return val;
}
2
/**
* 編寫一個(gè)程序, 通過命令行參數(shù)讀取兩個(gè)二進(jìn)制字符串喉镰,對這兩個(gè)二進(jìn)制數(shù)使用~運(yùn)算符旅择、&
* 運(yùn)算符、|運(yùn)算符和^運(yùn)算符侣姆,并以二進(jìn)制字符串形式打印結(jié)果
*/
#include <stdio.h>
#include <limits.h>
int twototen(const char *);
char * itobs(int , char *);
int main(int argc, char const *argv[])
{
int n1, n2;
char bran[CHAR_BIT * sizeof(int) + 1];
n1 = twototen(argv[1]);
n2 = twototen(argv[2]);
printf("~%s : %s\n", argv[1], itobs(~n1, bran));
printf("~%s : %s\n", argv[2], itobs(~n2, bran));
printf("&運(yùn)算: %s\n", itobs((n1&n2), bran));
printf("|運(yùn)算: %s\n", itobs((n1|n2), bran));
printf("^運(yùn)算: %s\n", itobs((n1^n2), bran));
return 0;
}
int twototen(const char *str)
{
int n = 0;
while (*str)
{
n = 2 * n + (*str++ - '0');
}
return n;
}
char * itobs(int n, char *str)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for ( i = size - 1; i >= 0; i--, n >>= 1)
{
str[i] = (01 & n) + '0';
}
str[size] = '\0';
return str;
}
3
/**
* 編寫一個(gè)函數(shù)生真,接受一個(gè)int類型的參數(shù),并返回該參數(shù)中打開位的數(shù)量捺宗。在一個(gè)程序中測試該函數(shù)
*/
#include <stdio.h>
#include <limits.h>
int on_off(int n);
int main(void)
{
int num;
int i;
puts("Please enter num");
scanf("%d", &i);
num = on_off(i);
printf("%d", num);
return 0;
}
int on_off(int n)
{
int count = 0;
int i;
const static int size = CHAR_BIT * sizeof(i);
for ( i = 0; i < size; i++, n >>= 1)
{
if (n & 01)
{
count++;
}
}
return count;
}
4
/**
* 編寫一個(gè)程序柱蟀,接受兩個(gè)int類型的參數(shù): 一個(gè)是值;一個(gè)是位的位置。如果指定
* 的位置為1蚜厉,該函數(shù)返回1;否則返回0.在一個(gè)程序中測試該函數(shù)
*/
#include <stdio.h>
#include <limits.h>
int localtion(int, int);
int main(void)
{
int value, num;
int result;
puts("Please enter values");
scanf("%d", &value);
puts("Please enter numbers");
scanf("%d", &num);
result = localtion(value, num);
printf("%d", result);
return 0;
}
int localtion(int value, int num)
{
value >>= (num-1);
if (value & 1)
{
return 1;
}
return 0;
}
5
/**
* 編寫一個(gè)函數(shù)长已,把一個(gè)unsigned int 類型值中的所有位向左旋轉(zhuǎn)指定數(shù)量的位。例如
* rotate_l(x, 4)把x中所有位同左移4個(gè)位置弯囊,而且從最左端移出的位會(huì)重寫出現(xiàn)在右端
* 也就是說痰哨,把高階位移出的位放入低階位。在一個(gè)程序中測試該函數(shù)
*/
#include <stdio.h>
void rotate_l(int x, int n);
int main(void)
{
unsigned int num;
unsigned int n;
puts("Please enter num"); //要被移動(dòng)的數(shù)字
scanf("%u", &num);
puts("Please enter nums"); //移動(dòng)位數(shù)
scanf("%u", &n);
rotate_l(num, n);
return 0;
}
void rotate_l(int x, int n)
{
unsigned int val;
val = x >> (32 - n);
x <<= n;
x |= val;
printf("%u", x);
}
6
/**
* 設(shè)計(jì)一個(gè)位字段結(jié)構(gòu)以存儲(chǔ)下面的信息.
*/
#include <stdio.h>
#include <stdbool.h>
struct set_word
{
unsigned int typeface : 8;
unsigned int bigorsmall : 7;
unsigned int : 1; //作為間隙
unsigned int aline : 3;
unsigned int : 1;
bool bold : 1;
bool italic : 1;
bool underline : 1;
unsigned int : 1;
};
const char * italics[8] = {"left", "middle", "right"}; //等會(huì)打印用到
const char * on_off[3] = {"off", "on"};
void show_news(struct set_word * pst); //展示字體信息
char menu(void); //展示菜單選項(xiàng)
char get_ch(void); //讀取選項(xiàng)的函數(shù)
void chang_font(struct set_word * pst); //改變字體
void chang_size(struct set_word * pst); //改變大小
void chang_alignment(struct set_word * pst); //對齊方式
void change_italic(struct set_word * pst); //是否斜體
void change_bold(struct set_word * pst); //是否實(shí)線
void change_under(struct set_word * pst); //有沒有下劃線
int main(void)
{
char ch;
struct set_word sets = {
1, 12, 0, 0, 0, 0
};
show_news(&sets);
while ((ch = menu()) != 'q')
{
switch (ch)
{
case 'f':
chang_font(&sets);
break;
case 's':
chang_size(&sets);
break;
case 'a':
chang_alignment(&sets);
break;
case 'b':
change_bold(&sets);
break;
case 'i':
change_italic(&sets);
break;
case 'u':
change_under(&sets);
break;
default:
puts("Error!");
break;
}
show_news(&sets);
}
show_news(&sets);
return 0;
}
void show_news(struct set_word * pst)
{
puts("ID SIZE ALIGNMENT B I U");
printf("%-8d%-8d%-8s %-8s%-8s%-8s\n", pst->typeface,
pst->bigorsmall, italics[pst->aline], on_off[pst->bold], on_off[pst->italic],
on_off[pst->underline]);
}
char menu(void)
{
char ch;-
puts("f)change font s)change size a)change alignment");
puts("b)toggle bold i)toggle italic u)toggle underline");
puts("q)quit");
ch = get_ch();
return ch;
}
char get_ch(void)
{
char ch;
scanf("%c", &ch);
while (getchar() != '\n')
continue;
return ch;
}
void chang_size(struct set_word * pst)
{
unsigned int n;
scanf("%u", &n);
while (getchar() != '\n')
continue;
if (n > 127)
{
n &= 127; //二進(jìn)制是1111111
}
pst->bigorsmall = n;
}
void chang_alignment(struct set_word * pst)
{
char ch;
puts("Select alignment:");
puts("1)left c)center r)right");
scanf("%c", &ch);
while (getchar() != '\n')
continue;
switch (ch)
{
case 'l':
pst->aline = 0;
break;
case 'c':
pst->aline = 1;
break;
case 'r':
pst->aline = 2;
break;
default:
puts("Errorrrr!");
break;
}
}
void change_italic(struct set_word * pst)
{
if (pst->italic == 0)
{
pst->italic = 1;
}
else
{
pst->italic = 0;
}
}
void change_bold(struct set_word * pst)
{
if (pst->bold == 0)
{
pst->bold = 1;
}
else
{
pst->bold = 0;
}
}
void change_under(struct set_word * pst)
{
if (pst->underline == 0)
{
pst->underline = 1;
}
else
{
pst->underline = 0;
}
}
void chang_font(struct set_word * pst)
{
unsigned int n;
scanf("%u", &n);
while (getchar() != '\n')
continue;
if (n > 255)
{
n &= 255; //二進(jìn)制是1111111
}
pst->typeface = n;
}