芯动科技笔试题嵌入式工程师const的作用
1、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
解答:这一题主要容易错的地方就是:意识到这个表达式将使一个16位机的整型数溢出,因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
2、写一个"标准"宏MIN,这个宏输入两个参数并返回较小的一个。
解答:这一题主要容易错的地方就是:懂得在宏中小心地把参数用括号括起来。
#define MIN(A,B)((A)<=(B)?(A):(B))
当然,使用宏也是有副作用的。就拿这一个例子来说:该宏定义对MIN(*p++,b)的作用结果是:((*p++)<=(b)?(*p++):(b))这个表达式会产生副作用,指针p会作两次++自增操作。
3、用变量a给出下面的定义:一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数。
解答:这一道题主要容易错的地方就是:函数指针、指针数组。
int(*a[10])(int);
4、关键字static的作用是什么?
解答:在C语言中,关键字static有三个明显的作用:
在函数体中,一个被声明为静态的变量在这一函数被调用过程中只会被分配一次内存,且整个运行期间不会重新分配;
在函数体外、某个源文件内,一个被声明为静态的变量只可被该源文件内的所有函数访问,但不能被其他源文件的函数访问。它是一个本地的全局变量;
在某个源文件内,一个被声明为静态的函数仅仅只可以被这个源文件的其它函数调用。也就是说,这个函数被限制在声明它的源文件的本地范围之内使用。
5、关键字const的作用是什么?
解答:简单地说,const意味着常数。
const定义的变量,它的值不能被改变,在整个作用域中都保持固定;
同宏定义一样,可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改;
可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。const是通过编译器在编译的时候执行检查来确保实现的。
const与指针
下面的声明都是什么意思:
const int a;
int const a;
const int*a;
int*const a;
const int*const a;
int const*const a;
前两个的作用是一样,a是一个常整型数;
第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以);
第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的);
最后两个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
const与函数
const通常用在函数形参中,如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用const来限制。比如在String的程序中有很多const修饰形参的情况:
void StringCopy(char*strDestination,const char*strSource);
const还可以表示该函数返回一个常量,放在函数的返回值的位置。比如:
const char*GetString(void);
在类成员函数的声明和定义中,const放在函数的参数表之后,函数体之前,表示该函数的this指针是一个常量,不能修改该对象的数据成员。比如:
void getId()const;
6、关键字volatile有什么含意?并给出三个不同的例子。
解答:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
存储器映射的硬件寄存器通常也要加voliate,因为每次对它的读写都可能有不同意义;
在中断函数中的交互变量,一定要加上volatile关键字修饰,这样每次读取非自动存储类型
的值(全局变量,静态变量)都是在其内存地址中读取的,确保是我们想要的数据;
多任务环境下各任务间共享的标志应该加volatile。
一个参数既可以是const还可以是volatile吗?
可以的,例如只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。软件不能改变,并不意味着我硬件不能改变你的值,这就是单片机中的应用。
参考文章:C语言中的volatile——让我保持原样。
一个指针可以是volatile吗?
可以。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
下面的函数有什么错误:
int square(volatile int*ptr)
{return*ptr**ptr;}
这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int*ptr)
{int a,b;
a=*ptr;
b=*ptr;
return a*b;}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int*ptr)
{int a;
a=*ptr;
return a*a;}
7、给定一个整型变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit3。
解答:这道题清除a的bit3,使用“&=~”的方法。
#define BIT3(0x1<<3)
static int a;
void set_bit3(void)
{a|=BIT3;}
void clear_bit3(void)
{a&=~BIT3;}
8、嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。
解答:这一问题测试你是否知道为了访问一绝对地址,把一个整型数(绝对地址)强制转换为一指针是合法的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论