面试准备每日五题:C++(二)——malloc&new、宏、volatile、const&volatile、(a)和(&a)

1.C语言的 malloc 和 C++ 中的 new 有什么区别

new 、delete 是操作符,可以重载,只能在C++ 中使用;

malloc、free 是函数,可以覆盖,C、C++ 中都可以使用;

new 可以调用对象的构造函数,对应的delete 调用相应的析构函数;

malloc 仅仅分配内存,free 仅仅回收内存,并不执行构造和析构函数;

new 、delete 返回的是某种数据类型指针,malloc、free 返回的是void 指针;

注 意 : m a l l o c 申 请 的 内 存 空 间 要 用 f r e e 释 放 , 而 n e w 申 请 的 内 存 空 间 要 用 d e l e t e 释 放 , 不 要 混 用 ;

2. 写一个 “标准”宏MIN

#define min(a,b) ((a)<=(b)?(a):(b))

3. 介绍 volatile 及其作用

volatile 影响编译器编译的结果,volatile指出 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会 进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化)

比如:

volatile int i=10; 
int j = i; 
... 
int k = i;

volatile告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。 而优化做法是,由于编译器 发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容 易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错;

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

  1. 并行设备的硬件寄存器(如:状态寄存器)

  2. 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

  3. 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。

我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。

  1. 一个参数既可以是const还可以是volatile吗?解释为什么。

  2. 一个指针可以是volatile 吗?解释为什么。

  3. 下面的函数有什么错误:

int square(volatile int *ptr)
 { 
	return *ptr * *ptr; 
}

下面是答案:

  1. 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

  2. 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向buffer的指针时。

  3. 这段代码有点变态,这段代码的目的是用来返指针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;
 }

总结volatile的作用有如下两点:

  1. 告诉compiler不能做任何优化;
  2. 表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用;

一般在下列场所使用volatile

  • 状态寄存器一类的并行设备硬件寄存器。
  • 一个中断服务子程序会访问到的非自动变量。
  • 多线程间被几个任务共享的变量。

注 意 : 虽 然volatile在 嵌 入 式 方 面 应 用 比 较 多 , 但 是 在 P C 软 件 的 多 线 程 中 , volatile修 饰 的 临 界 变 量 也 是 非 常 实 用 的 ;

参考文章:
C语言中volatile的用法及意义

4. 一个参数可以既是const又是volatile吗

这个其实在第三个题已经说了,肯定是可以的,二者目的不同;

可 以 , 用 c o n s tv o l a t i l e同 时 修 饰 变 量 , 表 示 这 个 变 量 在 程 序 内 部 是 只 读 的 , 不 能 改 变 的 , 只 在 程 序 外 部 条 件 变 化 下 改 变 , 并 且 编 译 器 不 会 优 化 这 个 变 量 。 每 次 使 用 这 个 变 量 时 , 都 要 小 心 地 去 内 存 读 取 这 个 变 量 的 值 , 而 不 是 去 寄 存 器 读 取 它 的 备 份 。注 意 : 在 此 一 定 要 注 意 c o n s t 的 意 思 , const 只 是 不 允 许 程 序 中 的 代 码 改 变 某 一 变 量 , 其 在 编 译 期 发 挥 作 用 , 它 并 没 有 实 际 地 禁 止 某 段 内 存 的 读 写 特 性 。

5. a 和&a 有什么区别

& a : 其 含 义 就 是 “ 变 量 a 的 地 址 ” ,在C++中亦有引用的意思,通过内存地址来操作对象本身,属于引用传递;

*a: 用 在 不 同 的 地 方 , 含 义 也 不 一 样 。

  • 在声明语句中,*a只说明a是一个指针变量,如int *a
  • 在其他语句中,*a前面没有操作数且a是一个指针时,*a代表指针a指向的地址内存放的数据,如b=*a
  • *a前面有操作数且a是一个普通变量时,a 代 表 乘 以 a , 如 c = b*a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值