文档章节

第15章 位操作 编程练习

idreamo
 idreamo
发布于 2017/06/29 06:03
字数 1747
阅读 70
收藏 1

1、编写一个将二进制字符串转化为数字值的函数。也就是说如果您有以下语句:

char * pbin="01001001";

那么您可以将pbin作为一个参数传递给该函数,使该函数返回一个int值。

#include <stdio.h>

int bin_dec(char *p);

char * pbin = "01001001";

int main(void)
{
    printf("bin: %s is dec: %d\n",pbin,bin_dec(pbin));
    return 0;
}

int bin_dec(char *p)
{
    int dec=0;
    while(*p !='\0')
        dec=(dec<<1)+*p++ -'0';
    return dec;
}

2、编写一个程序,该程序用命令行参数读取两个二进制字符串,并打印对每个数使用~运算符的结果,以及对这两个数使用&、|和^运算符的结果。使用二进制字符串形式显示结果。

#include <stdio.h>
#include <string.h>

#define M 8*sizeof(int)+1

char * extend(char * source,char * destination);
char * reverse(char * destination,char * source);
char * and(char *destination,char *source1,char *source2);
char * or(char *destination,char *source1,char *source2);
char * exclusive_or(char *destination,char *source1,char *source2);

int main(int argc,int argv[])
{
    char x[M],y[M],z[M];
    printf("    x = %s\n",extend(x,argv[1])); //拓展成M位宽
    printf("    y = %s\n",extend(y,argv[2]));
    printf("   ~x = %s\n",reverse(z,x));
    printf("   ~y = %s\n",reverse(z,y));
    printf("x & y = %s\n",and(z,x,y));
    printf("x | y = %s\n", or(z,x,y));
    printf("x ^ y = %s\n",exclusive_or(z,x,y));

    return 0;
}

char *extend(char *destination,char *source) //将二进制字符串传给一个32位长的字符串
{
    unsigned int i;
    for(i=0;i<M-1-strlen(source);i++)
        destination[i]='0';
        destination[i]='\0';
    strcat(destination,source);
    return destination;
}

char *reverse(char *destination,char *source)  //将二进制字符串取反
{
    char *save = destination;
    strcpy(destination,source);
    while(*destination!='\0')
    {
        if(*destination == '0') *destination = '1';
        else *destination='0';
        destination++;
    }
    return save;
}

char *and(char *destination,char *source1,char *source2)  //将两个二进制字符串求与
{
    char *save = destination;
    while(*source1 != '\0')
    {
        if(source1 == '1' && source2 == '1') *destination = '1';
        else *destination='0';
        source1++;
        source2++;
        destination++;
    }
    return save;
}

char* or(char *destination, char *source1, char *source2)//将两个二进制字符串 求或
{
 char *save = destination;
 while( *source1 != '\0' )
 {
  if( *source1 == '1' || *source2 == '1' ) *destination = '1';
  else *destination = '0';
  source1++;
  source2++;
  destination++;
 }
 return save;
}

char * exclusive_or(char *destination, char *source1, char *source2) //将两个二进制字符串 求异或
{
 char *save = destination;
 while( *source1 != '\0' )
 {
  if( *source1 != *source2  ) *destination = '1';
  else *destination = '0';
  source1++;
  source2++;
  destination++;
 }
 return save;
}

3、编写一个函数,该函数接受一个int参数,并返回这个参数中打开数的数量,在程序中测试该函数。

#include <stdio.h>

int count_on(int n);

int main(void)
{
    int n;
    printf("input a number (q to quit):");
    while(scanf("%d",&n)==1)
    {
        printf("%x----bit on number:%d\n",n,count_on(n));
        printf("input a number(q to quit):");
    }
    printf("quit\n");
    return 0;
}

int count_on(int n)
{
    int count = 0;
    while(n/2)
    {
        count+=n%2;
        n=n>>1;
    }
    count+=n%2;
    return count;
}

4、编写一个函数,该函数接受两个int参数,一个值和一个位的位置,如果指定的位上的值是1,则该函数返回1,否则返回0.在程序中测试该函数。

#include <stdio.h>
int check_bit(unsigned int number,unsigned int bit);

int main(void)
{
    unsigned int number,bit;
    printf("Input a number and a bit position(q to quit):");
    while(scanf("%d%d",&number,&bit)==2)
    {
        printf("bit %d of %d is %d\n",bit,number,check_bit(number,bit));
        printf("input a number(q to quit):");

    }
    printf("quit\n");

    return 0;
}

int check_bit(unsigned int number,unsigned int bit)
{
    return (number>>bit)&1;
}

5、编写一个函数,该函数将一个unsigned int中的所有的位向左旋转指定数量的位。例如,rotate_1(x,4)将x中的所有位向左移动4个位置,而且从左端丢失的位会重新出现在右端。也就是说从高位移出的位放入低位。在程序中测试该函数。

#include <stdio.h>
int rotate_1(unsigned int number,unsigned int bit);

int main(void)
{
    unsigned int number,bit;
    printf("Input a hexadecimal number and rotated bits number(q to quit):");
    while(scanf("%d%d",&number,&bit)==2)
    {
        printf("%x rotate %d bit left:%x\n",number,bit,rotate_1(number,bit));
        printf("input a number(q to quit):");

    }
    printf("quit\n");

    return 0;
}

int rotate_1(unsigned int number,unsigned int bit)
{
    unsigned int i;
    unsigned int hign=8*sizeof(unsigned int);  //最高位
    for(i=0;i<bit;i++)
        if(number&(1<<(hign-1))) number=(number<<1) | 1;
    else number=number<<1;
    return number;
}

6.设计一个位字段结构用来存储以下信息:

    Font ID:0到255之间的一个数

    Font Size:0到127之间的一个数

    Bold: Off (0)或on (1)

    Italic: Off (0)或on (l)

    Underline: Off (0)或on (1)

    在程序中使用这个结构来显示字体参数,并使用循环的菜单来让用户改变参数。例如,程序的一个运行示例如下:

  ID SIZE ALIGNMENT   B   I   U

   1   12   left     off off off

 

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

s

Enter font size (0-127): 36

 

  ID SIZE ALIGNMENT   B   I   U

   1   36   left     off off off

 

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

a

Select alignment:

l)left   c)center   r)right

r

 

  ID SIZE ALIGNMENT   B   I   U

   1   36  right     off off off

 

f)change font    s)change size    a)change alignment

b)toggle bold    i)toggle italic  u)toggle underline

q)quit

 

i

 

 

 

  ID SIZE ALIGNMENT   B   I   U

 

   1   36  right     off  on off

 

 

 

f)change font    s)change size    a)change alignment

 

b)toggle bold    i)toggle italic  u)toggle underline

 

q)quit

 

q

 

Bye!

这个程序应该使用&操作符和合适的掩码来保证Font ID和Font size信息被转换到指定的范围内。

#include <stdio.h>

struct {
 unsigned int id   :8;
 unsigned int size  :7;
 unsigned int alignment :2;
 unsigned int bold  :1;
 unsigned int italic  :1;
 unsigned int underline :1;
}font;

char align[3][7]={"left", "center", "right"};
char on_off[2][4]={"off", "on"};

int main(void)
{
 int n;
 char command[5];
 while(1)
 {
  printf("%-14s%-14s%-14s%-14s%-14s%-14s\n", "ID", "SIZE", "ALIGNMENT", "B", "I", "U");
  printf("%-14d%-14d%-14s%-14s%-14s%-14s\n", font.id, font.size, align[font.alignment], on_off[font.bold], on_off[font.italic], on_off[font.underline] );
  printf("f)change font    s)change size    a)change alignment\n");
  printf("b)toggle bold    i)toggle italic  u)toggle underline\n");
  printf("q)quit\n");
  gets(command);
  switch(command[0])
  {
   case 'f' : printf("Enter font ID (0-255): ");
      scanf("%d", &n);
      getchar();
      font.id = n;
      break;
   case 's' : printf("Enter font size (0-127): ");
      scanf("%d", &n);
      getchar();
      font.size = n;
      break;
   case 'a' : printf("Select alignment:\nl)left   c)center   r)right\n");
      gets(command);
      switch(command[0])
      {
       case 'l' : font.alignment = 0; break;
       case 'c' : font.alignment = 1; break;
       case 'r' : font.alignment = 2; break;
       default  : puts("error!");  break;
      }
      break;
   case 'b': font.bold = !font.bold;
      break;
   case 'i': font.italic = !font.italic;
      break;
   case 'u': font.underline = !font.underline;
      break;
   default : puts(command);
      return 0;
  }

 }
}

7、编写一个与练习6所描述的功能相同的程序。使用一个unsigned long来保存字体信息,使用位运算符而不是成员来管理这些信息。

#include <stdio.h>

unsigned long font;

char f = 0;   //id
unsigned long fm = 0xff<<f;  //id_mask

char s = 8;
unsigned long sm = 0x7f<<s;

char a = 15;
unsigned long am = 0x3<<a;

char b = 17;
unsigned long bm = 0x1<<b;

char i = 18;
unsigned long im = 0x1<<i;

char u = 19;
unsigned long um = 0x1<<u;

char align[3][7]={"left", "center", "right"};
char on_off[2][4]={"off", "on"};

int main(void)
{
 int n;
 char command[5];
 while(1)
 {
  printf("%-14s%-14s%-14s%-14s%-14s%-14s\n", "ID", "SIZE", "ALIGNMENT", "B", "I", "U");
  printf("%-14d%-14d%-14s%-14s%-14s%-14s\n", (font&fm)>>f, (font&sm)>>s, align[(font&am)>>a], on_off[(font&bm)>>b], on_off[(font&im)>>i], on_off[(font&um)>>u] );
  printf("f)change font    s)change size    a)change alignment\n");
  printf("b)toggle bold    i)toggle italic  u)toggle underline\n");
  printf("q)quit\n");
  gets(command);
  switch(command[0])
  {
   case 'f' : printf("Enter font ID (0-255): ");
      scanf("%d", &n);
      getchar();
      font = font & ~fm | n<<f;
      break;
   case 's' : printf("Enter font size (0-127): ");
      scanf("%d", &n);
      getchar();
      font = font & ~sm | n<<s;
      break;
   case 'a' : printf("Select alignment:\nl)left   c)center   r)right\n");
      gets(command);
      switch(command[0])
      {
       case 'l' : font = font & ~am | 0<<a; break;
       case 'c' : font = font & ~am | 1<<a; break;
       case 'r' : font = font & ~am | 2<<a; break;
       default  : puts("error!");    break;
      }
      break;
   case 'b': font ^= 1<<b;
      break;
   case 'i': font ^= 1<<i;
      break;
   case 'u': font ^= 1<<u;
      break;
   default : puts(command);
      return 0;
  }

 }
}

 

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
关东升的《从零开始学Swift》第2版已经出版

关东升的《从零开始学Swift》第2版已经出版 大家好: 苹果2015WWDC大会发布了Swift2.0,它较之前的版本Swift1.x有很大的变化,所以我即将出版《从零开始学Swift》 《从零开始学Swift》将在《...

tony关东升
2016/02/24
0
0
关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架,它是关东升老师历时8个月的呕心沥血所编著,全书600多页,此本书基于Swift 2.x,通过大量案例全面介绍苹果平台的应用开发。全书共分5 部...

智捷课堂
2016/03/11
43
0
关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架,它是关东升老师历时8个月的呕心沥血所编著,全书600多页,此本书基于Swift 2.x,通过大量案例全面介绍苹果平台的应用开发。全书共分5 部...

tony关东升
2018/06/26
0
0
关东升的《《从零开始学Swift》即将出版

大家好: 苹果2015WWDC大会发布了Swift2.0,它较之前的版本Swift1.x有很大的变化,所以我即将出版《从零开始学Swift》《从零开始学Swift》将在《Swift开发指南》第1版的基础上添加Swift2.0的...

智捷课堂
2015/08/17
0
0
那些年,我们学过的编程语言——Python篇

Hello World!不少人都与这句话邂逅在大家最初学习编程的时候。 2014年12月的编程语言排行榜中,Python位列在众多语言中的第8位,一直保持在前列。初学者看着简单清晰的语言极其容易上手。即...

生气的散人
2014/12/26
1K
4

没有更多内容

加载失败,请刷新页面

加载更多

Taro ScrollView 组件的 scrollTop 属性是个坑

官方issue:ScrollView设置scrollTop没效果 同样的,设置 scrollTop=0 并不能实现置顶,官方回复早就修复了,我的 Taro 版本已经是最新的,然而并未修复。 万能的评论区,给出了失效的原因。...

dkvirus
18分钟前
1
0
Qt那些事0.0.21

这次还是关于PRO文件中QMAKE_POST_LINK的故事。 平时都是使用VS2015作为编译器,恰巧想用MinGW编一版程序,结果偏偏出现了错误。话说测试的这个项目可是在Linux下(fodera 20)可以正确编译通...

Ev4n
28分钟前
0
0
OSChina 周六乱弹 —— 抖音外放 亲妈下葬。

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :一直没想明白黎明是怎么混进「四大天王」的,直到最近网易云音乐心动模式开启之后 #今日歌曲推荐# 《那有一天不想你》- 黎明 手机...

小小编辑
59分钟前
301
8
Linux使用源码包安装软件

前言: 最近整理一些以前的学习笔记。 过去都是存储在本地,此次传到网络留待备用。 源码包 Linux软件多数免费、开源,是开发人员编写的,具有很强可读性的一组相关代码文本。 源码包 --> 编...

迷失De挣扎
今天
6
0
IPv4如何转换为IPv6?

ipv6已经逐渐在应用,现在已经有很多的运营商支持ipv6,前天我们也发布了如何让电脑使用ipv6地址?有很多朋友在问?ipv6有什么作用,它的表示方式是什么,今天我们来一起来详细了解下ipv6相关计...

xiangyunyan
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部