《C陷阱与缺陷》第二章阅读笔记

语法“陷阱”

2.1 理解函数声明

声明类型的类型转换符的方法:只需要将声明中的变量和声明末尾的分毫去掉,再将剩余的部分用一个括号整个封装起来即可。
eg1:

float (*h)()

表示h是一个指”向返回值为float类型的函数的指针“。
因此

(float (*)())

表示一个“指向返回值为float类型的函数的指针“的类型转换符”

2.2 运算符的优先级问题

优先级最高者并不是真正意义上的运算符,包括:数组下标("[]")、函数调用操作符"()"、各结构成员选择操作符".","->"。他们都是自左向右结合。

次优先级为单目运算符。在所有真正意义上的运算符中,单目运算符的优先级做高。

!				逻辑反操作符
~				对二进制数值按位取反
++				前置、后置++
--				前置、后置--
-				负
+				正
(type)			强制类型转换
*				解引用操作符
&				取地址
sizeof

双目运算符比单目运算符优先级低。在双目运算符中,算术运算符的优先级最高,移位运算符次之,关系运算符再次之,接下来是逻辑运算符,赋值运算符,最后是条件运算符。

算数运算符
*
/
%
+
-
移位运算符
<<
>>
关系运算符
>
>=
<
<=
==
!=
逻辑运算符
&				按位与
^				异或
|				按位或
&&			逻辑与
||				逻辑或
赋值运算符
=
*=
/=
%=
+=
-=
<<=
>>=
&=
^=
|=
条件运算符
? :
逗号表达式
,

2.3 注意作为语句结束标志的分号

要注意分号的书写,多写或者缺失会导致意想不到的结果。
eg1:

if(a>0);
	a++;

该例本意为当a>0为真时,a自加1,由于if条件后多写了一个分号,导致每次程序运行,不管a>0是否成立,a++都会执行。上面的代码实际相当于:

if (a>0)
{
}
a++;

eg2:

if (n < 3)
	return
logrec.data = x[0];
logrec.time= x[0];
logrec.code= x[0];

此处,return后面缺少一个分号,然而这段代码编译并不会出错,只是将语句logrec.data = x[0]作为return语句的操作数。上面的代码实际相当于:

if (n < 3)
	return logrec.data = x[0];
logrec.time= x[0];
logrec.code= x[0];

当一个声明的结尾紧跟一个函数定义时,如果声明结尾的分号被省略,编译器可能将声明的类型作为函数的返回值类型。示例如下:
eg3:

struct logrec{
		int data;
		int time;
		int code;
}
main()
{
...
}

程序本意是main函数的默认返回值是int,由于结构体声明后缺失了一个分号,导致main函数的返回值成为了struct logrec类型的结构。

2.4 switch语句

eg1:

switch(color)
{
	case 1:
		printf("red")'
		break;
	case 2:
		printf("yellow");
	case 3:
		printf("blue");
		break;
}

当color为1或3时,执行完成之后,程序将会跳出switch语句。当color为2时,执行完2分支之后,程序会继续执行3分支,当3分支执行完成之后,程序跳出switch语句。

2.5 函数调用

假设f是一个函数,

f();

是一个函数调用语句,而

f;

却是一个什么也不做的语句。更精确的说,这个语句计算函数f的地址,却不调用该函数。

2.6 ”悬挂“else引发的问题

eg1:

if (x == 0)
	if (y == 0) error();
else{
z = x + y;
f(&z);
}

C语言中有这样的规则,else始终与同一括号内最近未匹配的if结合。上面的代码相当于

if (x == 0)
{
	if (y == 0)
		 error();
	else
	{
		z = x + y;
		f(&z);
	}
}

与本意相违背。在编写代码的时候应该这样编写:

if (x == 0)
{
	if (y == 0) 
		error();
}
else
{
	z = x + y;
	f(&z);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值