本系列博客基于董山海的
第五章:位运算与嵌入式编程
位制转换:
32位平台上 int 与 float 都占4个字节;
double 占8个字节;
unsigned short int 占2个字节,范围为 0~65535;
unsigned short char 占1个字节,范围为 0~255;
print("%f\n",5) 中的 “%f” 默认的参数是double类型,在printf中,float会转换为 double 类型,因此从栈中读了8个字节。类似的,如果是%d,则从栈中读取4个字节”。
#include
#include
int main(int argc, char* argv[]) {
int i = 5.01;
float f = 5;
//首先参数5为int型,所以在栈中分配了4个字节的内存存放5,但是printf会读取8个字节,会出错
printf("%f\n", 5);
printf("%1f\n", 5.01);
printf("%f\n", f);
//首先参数5。01为float型,所以在栈中分
//配了8个字节的内存,但是printf会读取4个字节,会出错
printf("%d\n", 5.01);
printf("%d\n", i);
system("pause");
return 0;
}
位运算:
左移操作 << 相当于乘法操作,
<< n 相当于乘以 2n;
右移操作>>相当于除法操作,>>n相当于除以 2n。
#include
#include
int main(int argc, char* argv[]) {
unsigned short int i = 0;
unsigned char ii = 255;
int j = 8, p, q;
p = j << 1;
q = j >> 1;
i = i - 1;
ii = ii + 1;
printf("i = %d\n", i);
printf("ii = %d\n", ii);
printf("p = %d\n", p);
printf("q = %d\n", q);
system("pause");
return 0;
}
设置或清除特定的位:嵌入式系统总是要求用户对变量或寄存器进行位操作。给定一个整型变量 a ,设置 a 的 bit 3,第二个清除 a 的 bit 3,保持其他位不变。
#define BIT3 (0x1<<3) //这边BIT3是来计算需要操作的位,bit 3 第三位
static int a;
void set_bit3(void) {
a |= BIT3; //|= 表示指定位置1
}
void clear_bit3(void) {
a &= ~BIT3; //&= 表示指定位置0
}
计算一个字节里有多少 bit 被置为1:
#include
#include
//一个字节有8位,首先在宏定义BIT7中将最高位置为1
#define BIT7 (0x1<<7)
int calculate(unsigned char c) { //这边输入一个数字
int count = 0;
int i = 0;
unsigned char comp = BIT7; //最高位
//
for (i = 0; i < sizeof(c) * 8; i++) {
if (( c & comp) != 0) { //比较每个位是否被置为1
count++;
}
comp = comp >> 1; //位右移
}
return count;
}
int main(int argc,char* argv[]) {
unsigned char c = 0;
int count = 0;
printf("c = ");
scanf_s("%d", &c);
count = calculate(c);
printf("count = %d\n", count);
system("pause");
return 0;
}
位运算:
//掩码 BIT_MASK(bit_pos):需要置0的位是1,其他位都是0
#define BIT_MASK(bit_pos) (0x01<<(bit_pos))
int Bit_Reset(unsigned int* val, unsigned char pos) {
if (pos >= sizeof(unsigned int) * 8) {
return 0;
}
val = (val && ~BIT_MASK(pos));
return 1;
}
位运算交换a、b两数:
#include
#include
int main() {
int a = 3;
int b = 5;
//进行三次异或操作,即比较相同两位的异同,如果相同,则赋值为0,否则为1。
a ^= b;
b ^= a;
a ^= b;
printf("a = %d,b = %d\n", a, b);
system("pause");
return 0;
}
列举并解释C++中的4种运算符转化以及他们的不同点:
用 #define 定义一个常数
#define SECONDS_PER_YEAR ( 60 ∗ 60 ∗ 24 ∗ 365 60*60*24*365 60∗60∗24∗365)UL
上面的 UL 表示无符号长整型。
用C语言编写死循环:
如何访问特定位置的内存:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
对嵌入式系统中断服务的理解:
_interrupt double compute_srea(double radius) {
double area = PI * radius * radius;
printf("Area = %f", area);
return area;
}
使用 _interrupt关键字去定义一个中断服务子程序(ISR):
4. ISR 不能返回一个值;
5. ISR 不能传递参数;
整数的自动转换:
void foo(void){
unsigned int a=6;
int b=-20;
if(a + b > 6){
puts("> 6");
}
else{
puts("<= 6");
}
}
答案是:> 6,因为当表达式存在 有符号和无符号类型时候,所有的操作数都自动转换为无符号类型。
关键字 static 的作用是什么?
关键字volatile有什么含义?
一个定义为 volatile 的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说,就是优化器在用到这个变量时必须每次小心的读取这个变量的值,而不是使用保存在寄存器里的备份。
判断处理器是 Big_endian 还是 Little_ebdian?
Big_endian:对操作数的存放方式为:从高字节到低字节;
Little_ebdian:对操作数的存放方式:从低字节到高字节;