位运算与嵌入式编程

/***********************************************程序员面试宝典(第二版)******************************************************/

1.下列程序的输出结果
#include <stdio.h>
int main()
{
	printf("%f\n", 5);
	printf("%d\n", 5.01);
}
答:printf根据说明符%f,认为参数应该是个double型
在printf函数中,float会自动转换成doble,从stack中
读了8个字节。内存越界,输出0.000000
第二个是一个大数
2. 下面程序是否有错?如果有,错在哪里?
struct a{
	int x:1;
	int y:2;
	int z:33;
};
答:int z:33定义整形变量z为33位,也就是超过了4字节
会造成越界。
3.Write a program that convert an octet number to a decimal number
写一个进制转化成十进制数的程序。
unsigned int oct2dec(unsigned int oct)
{
	return oct/10 * 8 + oct%10;
}
4.下面程序的运行结果是什么?
#include <stdio.h>
int main()
{
	unsigned short int i = 0;
	int j = 8, p;
	p = j << 1;
	i = i-1;
	printf("p=%d, i = %d\n", p, i);
}
答:p = 8 << 1,左移1位乘以2的1次方为16
unsigned short int 中无符号的-1结果是65535
5.内存中的数据排列问题
#include <stdio.h>

union {
	unsigned char a;//低地址
	unsigned int i;//高地址
}u;

int main()
{
	u.i = 0x12345678;
	printf("u.a=%0x\n", u.a);
}
答:输出u.a = 78,高字节,低地址存高字节
6.嵌入式系统总是要用户对变量或寄存器进行位操作,给定一个整型变量a
写两份代码,第一个设置a的bit 3, 第二个清除a的bit 3,在以上两个操作中
要保持其他位不变
#define BIT3 (0x1 << 3)
static int a ;

void set_bit3(void)
{
	a |= BIT3;
}

void clear_bit3(void)
{
	a &=~BIT3;
}
7.写出程序的运行结果
#include <stdio.h>
int main ()
{
	int *pa = NULL;
	int *pb = pa + 15;
	printf("%d\n", pb);
	return 0;
}
答:15 * 4 = 60
在系统里使用未初始化的指针是很危险的

8. In embedded system, we usually use the keyword "volatile"
what does the keyword mean?
答:volatile修饰的是为了防止该变量被编译器优化,编译器每次都必须
重新读这个数据里面的值。

9. 关键字volatile有什么含意?并给出3个不同的例子
答:一个定义为volatile的变量是说这变量可能会被意想不到地改变
优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使
用保存在寄存器里的备份。
1)并行设备的硬件寄存器(状态寄存器)
2)一个中断服务子程序中会访问到的非自动变量
3)多线程应用中被几个任务共享的变量

10. 一个参数可以是const又是volatile吗?一个指针可以是volatile吗?
答:第一个问题是的,例子是只读的状态寄存器,它是volatile,因为它可
能被意想不到地改变,它又是const,因为程序不应该试图去修改它
第二个问题:是的,中断服务子程序修改一个指向一个buffer的指针
11. 下面函数有什么错误
int square(volatile int *ptr)
{
	int a, b;
	a = *ptr;
	b = *ptr;
	return *ptr * *ptr;
}
答:由于*ptr的值可能被意想不到地改变,因此a和b可能是不同的。
改正
long square(volatile int *ptr)
{
	int a;
	a = *ptr;
	return a* a;
}

11. 写一个C函数,若处理器是Big_endian的,则返回0,若是Little_endian的
则返回1
答:大端是:低地址低字节
	小端是:低地址高字节
#include <stdio.h>

int check_CPU()
{
	union {
		int a;//低地址
		char b;
	}c;
c.a = 1;//基中1为低字节
return (c.b == 1);//若返回1说明高地址放低字节为小端,返回0为大端
}


你可能感兴趣的:(位运算与嵌入式编程)