《C和C++程序员面试秘笈》第5章 位运算与嵌入式编程

目录

  • 1. 位制转换
  • 2. 位运算
  • 3. 设置或者清除特定的位
  • 4. 计算一个字节里有多少bit被置1
  • 5. 位运算--指定位 置零
  • 6. 运用位运算 交换a、b两数
  • 7. C++的4种运算符转化以及它们的不同点
  • 8. 用#define声明一个常量
  • 9. 如何用C语言编写死循环
  • 10. 访问特定位置的内存
  • 12. 整数的自动转换
  • 13. 关键字static的作用
  • 14. 关键字volatile的含义
  • 15. 判断处理器是大端还是小端
  • 16. 处理器字长

1. 位制转换

#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;
int main()
{
	int i = 5.01;
	float f = 5;

	printf("%f\n", 5);//内存访问越界,结果不可预料
	printf("%lf\n", 5.01);//5.010000//5.01是double类型
	printf("%f\n", f);//5.000000//f是float类型

	printf("%d\n", 5.01);//5.01占8个字节,而%d读取4个字节,因此结果不可预料
	printf("%d\n", i);//5
	
	system("pause");
	return 0;
}

32位平台中,intfloat都占4个字节,double8个字节
printf()%f认为参数是个double类型(printf函数中,float会自动转换成double)所以,%f从栈中读取8个字节
	因此,第1printf()内存访问越界,结果不可预料
	第4printf()5.018字节,而%d只读取4字节,结果不可预料
	

2. 位运算

要清楚各种数据类型在内存中的大小、所占位数、所占字节、及各种进制所占的字节数
利用位移运算来做乘除法效率是最高的

3. 设置或者清除特定的位

题目:
	整数a
	1. 设置a的3bit
	2. 清除a的3bit
解析:
	用#define和bit masks操作,这是一个有极高可移植性的方法。
总结:
	|=&= 分别用来置1和置0
#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;
#define BIT3 (0x1 << 3)
void set_bit3(int & a)
{
	a |= BIT3;// |=0不变,|=1置为1
}
void clear_bit3(int & a)
{
	a &= ~BIT3;//&=1不变,&=0置为0
}
int main()
{
	int a = 0; 
	set_bit3(a);
	cout << a << endl;
	clear_bit3(a);
	cout << a << endl;
	
	system("pause");
	return 0;
}

4. 计算一个字节里有多少bit被置1

#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
#define BIT7 (0x1 << 7)//一个字节有8位,将一个字节的最高位置成1
//
int calculate(unsigned char c)
{
	int count = 0, i = 0;
	unsigned char compare = BIT7;
	int len = sizeof(c) * 8;
	for (i = 0; i < len; i++)
	{
		if ((c & compare) != 0)
		{
			count++;
		}
		compare = compare >> 1;
	}
	return count;
}
int main()
{
	int c = 0;
	cin >> c;
	cout << calculate(c) << endl;
	
	system("pause");
	return 0;
}

5. 位运算–指定位 置零

#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
#define BIT_MASK(bit_pos) (0x01 << bit_pos)
//相应位置置为0
int Bit_Reset(unsigned int & val, unsigned char pos)
{
	if (pos >= (sizeof(unsigned int) * 8))
	{
		return 0;
	}
	val &= (~BIT_MASK(pos));
	return 1;
}
int main()
{
	unsigned int a = 0x02;
	cout << a << endl;

	Bit_Reset(a, 2-1);//把第 2位置为0,其余位不变
	cout << a << endl;
		
	system("pause");
	return 0;
}

6. 运用位运算 交换a、b两数

swap(int &a,int &b)
{
	a^=b;
	b^=a;
	a^=b;
}
注意:
	只能用于相同类型数的交换

7. C++的4种运算符转化以及它们的不同点

1const_cast操作符
	1、将限制为const成员函数的const定义解除
2dynamic_cast操作符
	1、可以将基类指针,指向不同的派生类,然后将被转型为基类的对象还原成原来的对象(子类对象)
	限于对象指针的类型转换,而不是对象变量
3reinterpret_cast操作符
	它潜在危险,除非有充分利用,否则不要使用它
	1、通常用于,某些非标准的指针数据类型转换
4static_cast操作符
	1、用在父类子类 对象和指针类型之间进行类型转换
	2、数字(原始数据类型)类型之间进行类型转换,通常用来将大类型转换为小类型

8. 用#define声明一个常量

#define YEAR_TIME (60*60*24*365)UL
注意:
	1、不能以分号结束
	2、括号的使用
	3、需要时要告诉编译器常数的类型
	比如:此处,UL表示无符号长整型,

9. 如何用C语言编写死循环

while(){}

10. 访问特定位置的内存

题目:
	设置一绝对地址为0x67a9的整型变量的值为0xaa66,编译器是一个纯粹的ANSI吧编译器

int *ptr;
ptr=(int *)0x67a9;
*ptr=0xaa66;
  1. 对中断服务代码的评论

12. 整数的自动转换

void foo()
{
	unsigned int a=6;
	int b=-20;
	if(a+b>6)
		puts(">6");
	else
		puts("<6");
}
总结:
	//表达式中同时存在有符号数和无符号数,有符号数自动转换为无符号数
	具体怎么转换的??????

13. 关键字static的作用

静态全局变量:只能在本源文件使用
静态函数:只能在本源文件内调用
静态局部变量:只能在该函数内部使用,并且调用过程之中维持其值不变

14. 关键字volatile的含义

	一个被定义为volatile的变量,是说这个变量可能会被意想不到的改变,这样,编译器就不会去假设这个变量的值了。
	准确地说,就是优化器在用到这个变量时,必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份
	几个例子:
		1、并行设备的硬件寄存器(如:状态寄存器)
		2、一个中断服务子程序中会访问到的非自动变量
		3、多线程应用中被多个任务共享的变量

15. 判断处理器是大端还是小端

#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
#define BIT_MASK(bit_pos) (0x01 << bit_pos)
//相应位置置为0
int checkCPU()
{
	union w
	{
		int a;
		char b;
	}c;
	c.a = 1;
	return (c.b == 1);//小端返回1,大端返回0
}
int main()
{
	cout << checkCPU() << endl;
		
	system("pause");
	return 0;
}

16. 处理器字长

unsigned int zero = 0;
unsigned int compzero = ~0;//不能写成0xFFFF

你可能感兴趣的:(《C和C++程序员面试秘笈》第5章 位运算与嵌入式编程)