15.1
#include<stdio.h>
#include<limits.h>
#include<string.h>
# include <stdlib.h>
# include <ctype.h>
#define SIZE 33
int gets_bstr(char *st, int n);
bool check_value(const char *st);
int binstr_to_dec(const char *st);
int main(void)
{
char value[SIZE];
int num;
printf("请输入二进制数 max<=32 (输入空行退出)\n");
while (gets_bstr(value, SIZE) && value[0] != '\0')
{
printf("check_value(value) = %d", check_value(value));
if (!check_value(value))//输入的数字只能是0或1,value相当于指针
{
puts("7");
puts("输入有误,只能是0、1。");
}
else
{
puts("6");
printf("%s is %d\n", value, binstr_to_dec(value));
}
}
puts("done");
return 0;
}
//从标准输入里读取二进制字符串,给出字符串数组地址,和读取长度,读取n-1个二进制字符.自动添加'\0'
//返回成功读取的字符个数,读取失败返回0,遇到不是二进制字符,或者达到指定个数,都将停止读取
int gets_bstr(char *st, int n)
{
puts("3");
char ch;
int i;
for (i = 0; i < n - 1 && (ch = getchar()) != '\n' && (isdigit(ch) || isspace(ch)); i++)
{
puts("4");
st[i] = ch;
}
st[i] = '\0';
if (ch != '\n')
while (getchar() != '\n');
return i;
}
bool check_value(const char *st)
{
puts("1");
while (*st != '\0')//我们需要一个个去判断,数组中的数字
{
if (*st != 0 && *st != 1)
{
puts("5");
return 0;
}
st++;
}
return 1;
}
//二进制转整数
int binstr_to_dec(const char *st)
{
puts("2");
int val = 0;
while (*st)
{
val = val * 2 +(*st - '0');//ascii码中,‘1’对应49,‘0’对应48
st++;
}
return val;
}
15.2
//资源15章《位操作》有详细解释
#include<stdio.h>
#include<limits.h>
#include<string.h>
# include <stdlib.h>
# include <ctype.h>
#define SIZE 33
int binstr_to_dec(const char *st);
char *int_to_binary(int num, char *st);
int main(int argc, char*argv[])
{
int value1 = 0;
int value2 = 0;
char bstr[CHAR_BIT *sizeof(int) + 1];
if (argc != 3)
{
printf("Usage: %s binary_num1 binary_num2\n", argv[0]);
return 0;
}
value1 = binstr_to_dec(argv[1]);
value2 = binstr_to_dec(argv[2]);
printf("~%s = %s\n", argv[1], int_to_binary(~value1, bstr));
//直接对value1取反,int_to_binary函数得出反码0010->1101这样
printf("~%s = %s\n", argv[2], int_to_binary(~value2, bstr));
printf("%s & %s = %s\n", argv[1], argv[2], int_to_binary((value1 & value2), bstr));
printf("%s | %s = %s\n", argv[1], argv[2], int_to_binary((value1 | value2), bstr));
printf("%s ^ %s = %s\n", argv[1], argv[2], int_to_binary((value1 ^ value2), bstr));
return 0;
}
//二进制转整数
int binstr_to_dec(const char *st)
{
puts("2");
int val = 0;
while (*st)
{
val = val * 2 + (*st - '0');//ascii码中,‘1’对应49,‘0’对应48
st++;
}
//输入:0111
//val = 0 val = 0x2+(48-48)=0
// val = 0x2+(49-48)=1
// val = 1x2+(49-48)=3
// val = 3x2+(49-48)=7
return val;
}
//整形value1取反~后转换成字符串,存放进数组中,返回数组首地址
char *int_to_binary(int num, char *st)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for (i = size - 1; i >= 0; i--, num >>=1)
{
st[i] = (1 & num) + '0';
}
st[size] = '\0';
return st;
}
.
.
.
15.4.1方法一
较难理解地方:
- binstr[31 - pos] == ‘1’ :的31 - pos
#include<stdlib.h>
#include<stdio.h>
char *int_to_binstr(int n, char *st);
void show_binstr(const char *sd);
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("Usage: %s int_num bit_pos\n", argv[0]);
return 0;
}
int value, pos;
char binstr[CHAR_BIT * sizeof(int) + 1];
value = atoi(argv[1]);//数字
pos = atoi(argv[2]);//判断第pos位是不是1
int_to_binstr(value, binstr);//转换
show_binstr(binstr);//输出binstr中字符串
if (check_pos(value, pos) == 1) //打开计算器或列出0-31位,按照数组索引顺序数-pos,即为按照二进制顺序数
printf("bit %d is 1\n", pos);
else
printf("bit %d is 0\n", pos);
return 0;
}
char *int_to_binstr(int n, char *st)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for (i = size - 1; i >= 0; i--, n >>= 1)
{
st[i] = (1 & n) + '0';
}
st[size] = '\0';
return st;
}
void show_binstr(const char *sd)
{
int i = 0;
printf("二进制字符串显示 :\n");
while (*sd)
{
putchar(sd[i]);
if (++i % 4 ==0 && sd[i])
{
putchar(' ');
}
}
}
int check_pos(int value, int pos )
{
char binstr[CHAR_BIT * sizeof(int) + 1];
int_to_binstr(value, binstr);
if (binstr[31 - pos] == '1') //打开计算器或列出0-31位,按照数组的索引顺序数-pos,即为按照二进制的顺序数(数组左是低位,二进制右是低位,都是从低位开始顺序排列)
printf("bit %d is 1\n", pos);
else
printf("bit %d is 0\n", pos);
}
15.4.2方法二
毕竟难理解的地方 :(value & (1 << (n - 1)));
- value :我们输入的整数,计算机中二进制存在
- &‘与’上的地方,就是打开的地方,‘1’既是打开,‘0’既是关闭
- for循环,每次&一个位
//编写一个程序,接受两个int类型的参数:一个是值;一个是位的位置.如果指定位的位置为1, 该函数返回1;否则返回0. 在一个程序中测试该函数
# include <stdio.h>
# include <stdlib.h>
# define COUNT_BIT 8
int bit_value(int value, int n);
int main(void)
{
int num;
printf("请输入您要查看打开位状况的数(q 退出);");
while (scanf(" %d", &num))
{
while (getchar() != '\n');
for (int i = 0; i < COUNT_BIT; i++)
printf("%d 第%d位打开状况: %s\n", num, i + 1, bit_value(num, i + 1) ? "打开" : "关闭");
printf("请输入您要查看打开位状况的数(q 退出);");
}
return 0;
}
int bit_value(int value, int n)
{
if (!n)
{
fputs("位置值不能为0.--bit_value", stderr);
exit(1);
}
return (value & (1 << (n - 1)));
}
验算
.
15.5
毕竟难理解的地方是这俩:
- overflow = num >> (32 - shift); :这是为了可以让左移后的位数,‘或’上左移出去的位数
- (num << shift) | overflow; :左移后的位数‘或’上左移出去的位数
- 同样,需要用到整数->成字符串的函数,显示成二进制字符串
- 32 - shift :得到需要右移的位数
//
# include <stdio.h>
# include <stdlib.h>
unsigned int rotate_l(unsigned int num, unsigned int shift);
char * int_to_binstr(int num, char *st);
int main(void)
{
unsigned int value;
unsigned int places;
unsigned int rot;
char binstrs1[CHAR_BIT * sizeof(int) + 1];
char binstrs2[CHAR_BIT * sizeof(int) + 1];
while (scanf("%ud", &value) && value > 0)
{
printf("please enter numbers of bits that you want to rotate:\n");
scanf("%ud", &places);
rot = rotate_l(value, places);
int_to_binstr(value, binstrs1);
int_to_binstr(rot, binstrs2);
printf("%ud rotated is %ud\n", value, rot);
printf("%s rotated is %s", binstrs1, binstrs2);
}
return 0;
}
//左移的0\1,换到右侧
unsigned int rotate_l(unsigned int num, unsigned int shift)
{
unsigned int overflow;
overflow = num >> (32 - shift);
return (num << shift) | overflow;
}
char * int_to_binstr(int num, char *st)
{
int i;
const static int size = CHAR_BIT * sizeof(int);
for (i = size -1; i >= 0; i--, num >>= 1)
{
st[i] = (1 & num) + '0';
}
st[size] = '\0';
return st;
}