笔试面试题记录(0x01) —— #define
来源:互联网 发布:手机音乐识别软件 编辑:程序博客网 时间:2024/05/21 15:49
一直感觉自己明白#define是怎么回事
直到迪普笔试遇到这道题:
设有以下宏定义
#define N 3
#define Y(n) ((N+1)*n)
则执行语句:z=2*((N+Y(5+1));后,z的值为( )。
A、 出错
B、 42
C、 48
D、 54
define, 宏定义
define在程序运行之前,编译预处理时, 替换
比如:#define PI 3.1415926
在程序编译预处理的时候,将会把程序中所有的PI都替换成3.1415926
这样写的好处有很多, 比如可以方便程序修改, 在程序中用PI代替3.1415926这串数字也增加了程序的可读性
我觉得也许我的C根本没入门
当时觉得 2*(N+Y(5+1)) == 2 *(3 + (3 + 1) * 6) == 2 * 27 == 54
选了D
后来面试我的人,问我,这样define的写法, 和写成函数形式的区别
我答:define是在运行之前替换,而函数是运行时调用, 巴拉巴拉巴拉...
他说:那你怎么没直接替换呢?..
我 :......
他说:下次注意就行了,小问题。( 他以为我懂,以为我是笔误呢)
其实面试结束我也不明白我错哪了, 呵呵。
后来回到家里, 从网上看到了这道题, 才明白自己到底错在哪了
#define 就是在运行之前替换, 替换就是替换, 你就只需要替换就行
不需要做多余的操作 , 比如上题中, 我自己把 5 + 1 求出来了
替换就是替换, 替换就是替换, 替换就是替换, 所以你只需要替换即可
无论需要替换的是一个数字, 还是一个表达式
所以我们应该把 5+1 代替 Y(n)中的n , 而不是6
所以, 2*(N+Y(5+1)) == 2 *(3 + (3 + 1) *5 + 1) == 2 * 24 == 48
神奇了, 神奇之处在于, 把 5+1带入之后, 运算的优先级导致你不是简单的直接5+1了
而是要考虑其他运算符的优先级顺序
这也让我忽然想到了, 为什么之前很多人一直强调, 在#define后面, 用()
比如, #define f(a) a+a 要写成 #define f(a) ((a)+(a))
之前我一直认为多写这些括号是多余的, 现在看来,如果没有这些括号根本不对
看到这里也应该能很轻易想出 上面第一种写法 出错的 反例
你只需要让f(a)和其他数字N进行一次乘法运算就行了
比如, 你想要得到 N * (a + a) , 但是第一种解法得到的结果却是 N * a + a
至于里面(a)+(a)这里坚持加两个括号的原因:找个反例吧
反例是如果是(a)*(a) 而a代表的是一个加法表达式呢?
好像写的好啰嗦, 就到这吧
下面给出几个define的类似题目, 来自互联网。
01、下面程序的运行结果是
#define ADD(x) x+x
int main()
{
int m=1, n=2, k=3;
int sum = ADD(m+n)*k;
printf("sum=%d\n", sum);
return 0;
}
A、sum=9
B、sum=10
C、sum=12
D、sum=18
02、下列程序执行后的输出结果是
#define MA(x) x*(x-1)
int main()
{
int a = 1, b = 2;
printf("%d\n", MA(1+a+b));
}
A、6
B、8
C、10
D、12
03、以下程序的输出结果是
#define f(x) x*x
int main()
{
int a=6, b=2, c;
c = f(a) / f(b);
printf("%d\n",c);
}
A、9
B、6
C、36
D、18
04、以下程序运行后,输出结果是( )。
#define P 5.5
#define S(X) P*X*X
int main()
{
int a=1, b=2;
printf("%.1lf\n", S(a+b));
}
A、49.5
B、9.5
C、22.0
D、45.0
05、以下程序的运行结果是
#define MIN(x,y) (x)<(y)?(x):(y)
int main()
{
int i=10, j=15, k;
k = 10 * MIN(i,j);
printf("%d\n",k);
return 0;
}
A、10
B、15
C、100
D、150
06、从下列选项中选择不会引起二义性的宏定义是( )。
A) #define POWER(X) X*X
B) #define POWER(X) (X)*(X)
C) #define POWER(X) (X*X)
D) #define POWER(X) ((X)*(X))
key:
01 B note: m+n+m+n*k == 1 + 2 + 1 + 2 * 3 == 10
02 B note: 1+a+b*(1+a+b-1) == 8
03 C note: 6 * 6 / 2 * 2 == 36
04 B note: P * a + b * a + b == 5.5 * 1 + 2 * 1 + 2 == 9.5
05 B note: k = 10 * 10 < 15 ? 10 : 15 = 15
06 D
附1:带参数宏与函数的区别(摘自清华大学C语言程序设计PPT)
简单的字符置换 分配内存
先求实参值 再代入形参
- 笔试面试题记录(0x01) —— #define
- 笔试面试题记录
- 笔试面试题记录
- 笔试/面试题记录
- 面试笔试题记录
- java——笔试题记录
- C++面试宝典笔试题记录
- 面试题记录第一节——(activity、fragment)
- 面试题记录第二节——(service、Broadcast)
- 面试题记录第二节——(Binder)
- 面试题记录第五节——Asynctask
- 面试题记录第七节——(事件分发)
- VC笔试题记录
- 笔试题记录
- 笔试题记录
- Java笔试题记录
- 常见笔试题记录
- 笔试题记录1
- 在Liferay中使用Ajax
- 已知一个函数f可以等概率的得到1-5间的随机数,问怎么等概率的得到1-7的随机数
- 汇编简单的输入输出
- 通过电话号码查人名(ContentProvider)
- Linux下缓冲区溢出攻击的原理及对策
- 笔试面试题记录(0x01) —— #define
- arcmap_python_LabelClass
- Drools Expert(jbpm5学习资料)
- struts2 理解
- Liferayの调度器-定时任务
- [转载]蓄水池抽样 均匀抽样
- 天空的颜色 363
- 怎样学习编程
- 《windows程序设计》笔记(2章)