15章C Primer Plus详细解答--附带详细注释

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方法一

较难理解地方:

  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)));

  1. value :我们输入的整数,计算机中二进制存在
  2. &‘与’上的地方,就是打开的地方,‘1’既是打开,‘0’既是关闭
  3. 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

毕竟难理解的地方是这俩:

  1. overflow = num >> (32 - shift); :这是为了可以让左移后的位数,‘或’上左移出去的位数
  2. (num << shift) | overflow; :左移后的位数‘或’上左移出去的位数
  3. 同样,需要用到整数->成字符串的函数,显示成二进制字符串
  4. 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;
}

在这里插入图片描述

后续太多麻烦,知识点类似所以不做写了,工程代码中不会这么复杂

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扳手的海角

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值