Hacks in C Programming Language

很早之前转载过这样一篇文章,但并没有写答案,今天把答案补上,再发一次。

 

 下面这个程序输出什么?

 

解析:我没有更改原题,不过相信如果把enum中的true和false更换位置,结果会让一部分人吃惊。C语言没有提供标准的布尔类型,部分因为选一个这样的类型涉及最好由程序员决定的空间/时间折衷.(使用int可能更快,而使用char可能更节省数据空间.然而,如果需要和int反复转换,那么小类型也可能生成更大或更慢的代码.)

    使用#de ne还是枚举常数定义true/false可以随便,无关大雅,使用以下任何一种形式都OK
#define TRUE 1#defineYES1
#define FALSE 0#defineNO0
enum bool {false, true}; enum bool {no, yes};
或直接使用1和0,只要在同一程序或项目中一致即可.如果你的调试器在查看变量的时候能够显示枚举常量的名字,可能使用枚举更好.
    有些人更喜欢这样的定义
    #defineTRUE(1==1)
    #define FALSE (!TRUE)
    或者定义这样的"辅助"宏
    #define Istrue(e) ((e) != 0)

 

你相信么?下面这个程序输出的两行东西不一样!
 

解析:在宏的替换过程中,当出现#或者##时,不在继续替换。

所以,对于h(f(1,2)),编译器看到h,再看到(时,知道是function-like的macro,因此替换参数,变成g(f(1,2)),再继续替换f,变成g(12),第一次扫描结束,再次扫描,得到结果12.

对于g(f(1,2)),先替换g,替换的时候编译器看到了#符号,因此变成了(#)(这个只是为了说明)f(1,2),因此不会再替换f,得到的结果就是f(1,2)。

 


下面的程序看似完全正确。你能看出它为什么通不过编译吗?
看出问题前不要去试着编译,不然你会后悔你没看出来这个低级的语法错误。

 

解析:OS_HP-UX_print。。。中间那横真幽默~~

 


为什么下面这个程序的输出不是NONE?看你多久才能看出来。
 

解析:我就不更改题目了,default写错了,我觉得题目的本意应该是考察int和char的互换,另a=50,可能才会引起一些不解。

下面这个程序输出什么?

解析:printf。。。打了几个字符,返回几,知道怎么不写分号打印一串东西么?

if(printf(....)){

}

 

 

下面这个程序输出什么?
 

switch,不回执行case上面那条语句

 

 

下面这个程序输出什么?
 
sizeof只会计算operand的类型,除非里面是变长数组,所以i++是不会执行的,在编译的时候编译器判断完类型后就已经将sizeof的值替换上去了,关于这个内容,晚些时候再写篇博客说明吧~


下面这个程序输出什么?
 

解析:8进制,不解释

 

下面这个程序输出什么?
 

解析:printf太强大了,我也是经MM指点才知道原来printf还有这么强大的功能,在字串是%s的情况下,前面的&a表示去除前a个字符。

 

下面这个程序输出什么?

解析:输出的两个值应该都是23, 可以理解为

printf("%d %d/n",i,i);

i++;

i++;

 

为什么下面这个程序的输出不是10?我故意取消了语法高亮:)
 


解析:csdn帮了忙,瞬间变成注释了~~

 

下面这个程序输出什么?
 
解析:之前除了写vba的时候遇到了a || b,当a为true,它还会去算b的情况,其他的语言好像没有还没遇到这类情况,答案应该是8

 

下面这段代码是否合法?
 

解析:这里返回的需要是一个expression,而不是statement,使用return是很幽默的

这是什么意思?有什么潜在的问题?
 


解析:看名字就知道啥意思了,如果传入的是表达式也许就会有问题了吧


这是什么意思?
 

对于两个正整数 x, n 总存在整数 q, r 使得
x = nq + r, 其中  0<= r <n                  //最小非负剩余
q, r 是唯一确定的。q = [x/n], r = x - n[x/n]. 这个是带余除法的一个简单形式。在 c 语言中, q, r 容易计算出来: q = x/n, r = x % n.
所谓把 x 按 n 对齐指的是:若 r=0, 取 qn, 若 r>0, 取 (q+1)n. 这也相当于把 x 表示为:
x = nq + r', 其中 -n < r' <=0                //最大非正剩余  
nq 是我们所求。关键是如何用 c 语言计算它。由于我们能处理标准的带余除法,所以可以把这个式子转换成一个标准的带余除法,然后加以处理:
x+n = qn + (n+r'),其中 0<n+r'<=n            //最大正剩余
x+n-1 = qn + (n+r'-1), 其中 0<= n+r'-1 <n    //最小非负剩余
所以 qn = [(x+n-1)/n]n. 用 c 语言计算就是:
((x+n-1)/n)*n
若 n 是 2 的方幂, 比如 2^m,则除为右移 m 位,乘为左移 m 位。所以把 x+n-1 的最低 m 个二进制位清 0就可以了。得到:
(x+n-1) & (~(n-1))

 

一些C语言的教材上会给出一个很经典的宏定义
 
但这种宏定义的方法存在不足之处,一旦遇到下面这种情况就出问题了:
 
为了避免这种问题,应该怎样来定义isupper?


怎样用printf函数打印"I can print %"?别忘了百分号是用于格式化输出的。
不用任何比较运算符,写一个程序找出三个数中的最小数。
不用+号,(用位运算)实现加法运算。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值