《c陷阱与缺陷》1-3章笔记

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

词法陷阱

1、注意=与==的使用
比较容易犯错的是将==写成了=,除了自己多加注意以外,养成习惯将要比较的常量值放在左边,这样如果写成了=号,编译就会报错。

类似的还有&和&&、|和||。

2、对于多运算符操作的语句,直接用括号来显示运算优先级,使代码易读清晰


语法陷阱

1、理解函数声明

分析的过程:
A、从左开始查看变量或函数名,然后按照优先级顺序依次读取
B、优先级从高到低依次是:
1. 声明中被括号括起来的那部分
2. 后缀操作符:括号()表示这是一个函数,而方括号表示这是一个数组
3. 前缀操作符:星号*表示 “指向…的指针”。

C、如果const和volatile关键字的后面紧跟类型说明符(如int, long等),那么它作用于类型说明符。在其他情况下,const和(或)volatile关键字作用于它左边紧邻的指针星号。

比如singal函数:

void (*signal(int sig, void(*func)(int)))(int);
1、先找到signal名,后面是个括号,先把括号里的东西作为一个整体,表示signal是个函数。
2、signal前面是个星号,表示函数返回一个指针。
3、星号所在括号后面紧跟一个括号,表示指针指向带有一个int型参数并返回void的函数指针
4、signal函数参数则是一个int型及一个指向带有一个int型参数并返回void的函数指针
这里找出共同部分就是指向带有一个int型参数并返回void的函数指针
将该共同部分定义成一个新类型, 则singal函数可声明如下:
typedef void (*handle)(int);
handle signal(int , handle);

2、注意作为语句结束标志的分号是否漏写了。

3、注意switch语句的每个case处理完操作后是否漏写break语句,如果确实不需要,最好添加注释说明

4、习惯if语句代码块用大括号包住,避免出现else语句混乱的问题


语义陷阱

1、指针与数组

1、c语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。然后c语言的数组中的元素可以是任何类型的对象,当然也可以是另一个数组。
2、对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操组,哪怕看上去是以数组下标进行运算的,实际上都是通过指针进行的。
3、数组名如果不是用于sizeof的操作数,总是被转换成一个指向该数组的起始元素(指向该数组下标为0的元素)的指针。
4、任何指针都是指向某种类型的变量。如果p指向一个整数,那么p+1指向的是计算机内存中的下一个整数(计算步长以指针所指向的变量类型为单位),在大多数现代计算机中,它都不同于p所指向地址的下一个内存位置。

int calendar[12][31];
// 声明一个指向该数组的指针
// 1、首先得到该一维数组的元素是有着31个整型元素的数组
// 2、声明指向上述元素类型的指针
int (*p)[31];
p = calendar; <==> p = &calendar[0]
p+1指向的就是&calendar[1]

2、非数组的指针

1、尤其要注意strlen、strcpy、strcmp等字符串相关函数其传入的参数不能是空指针
2、用strncpy在做拼接字符串的时候,尤其注意”%s”所对应的字符串是不是一定以‘\0’结尾的,否则会出现越界的情况。
3、用strlen来计算长度并malloc动态申请空间,考虑要多申请一个字节用于存储’\0’,因为strlen是不计算’\0’字符的
4、注意内存的申请和释放

3、作为参数的数组声明

前面说过数组名除在sizeof操作符情况下,都作为第一个元素的起始地址,当数组名作为参数传递函数的时候,实际与将数组第一个元素的地址作为参数传递的作用是一样的,如
char hello[] = “hello”;
printf(“%s\n”, hello); <==> printf(“%s\n”, &hello[0]);
因此,数组作为函数参数将毫无疑义(这个我真有点理解不过来…)。所以c语言中会自动将作为参数的数组声明转换为相应的指针声明。如:
int strlen(char s[]); <==> int strlen(char *s);

但是
extern char *hello; 和 extern char hello[]; 是完全不同的
如果一个指针参数并不实际代表一个数组,即使从技术上而言是正确的,采用数组形式的记法经常会起误导作用。

4、指针在使用前一定要判断是否为空指针

5、边界计算与不对称边界

1、两个原则:

  • 首先考虑最简单情况下的特例,然后将得到的结果外推
  • 仔细计算边界,绝不掉以轻心

2、不对称边界
比如要定义一个拥有10个元素的数组,那么0就是数组下标的第一个“入界点”(指处于数组下标范围以内的点,包括边界点),而10就是数组下标中的第一个“出界点”(指不在数组下标范围以内的点,不含边界点),为此我们这样写:
int a[10], i;
for (i = 0; i < 10; i++)
而不是写成下面这样:
int a[10], i;
for (i = 0; i <= 9; i++)

3、–n >= 0 与 n– > 0 是等效的
前者是先将n进行减1,再进行判断;后者是将n保存,再将n减1,然后在将原先保存的值做比较

6、求值顺序

C语言中只有四个运算符(&&、||、?:和,)存在规定的求值顺序。

  • 运算符&&和||首先对左侧操作数求值,只在需要时才对右侧操作数求值
  • 运算符?:有三个操作数:在a?b:c中,a先被求值,再根据a的值求操作数b或c
  • 逗号运算符,首先对左侧操作数求值,然后该值被“丢弃”,再对右侧操作数求值

其他运算符对其操作数的求值顺序时未定义的,尤其时赋值运算符

7、整数溢出

这一话题建议多搜索看看,比如 C语言的整型溢出问题

8、为函数提供返回值

【C语言】词法陷阱缺陷总结 C语言词法陷阱多,如贪心法解析、整型前缀误解、字符串混淆等,需警惕运算符优先级、内存管理等问题,确保编码严谨,避免缺陷 阅读详情

相关推荐

C陷阱缺陷笔记

任何一种程序设计语言,总存在一些语言特性。而《C陷阱缺陷》此书,就是对C语言一些程序员常犯错误的特性的总结。

瓦釜苑 1483

拷贝部分字符串

        利用标准库函数strncpy(),可以将一字符串的一部分拷贝到另一个字符串中。strncpy()函数有3个参数:第一个参数是目录字符串;第二个参数是源字符串;第三个参数是一个整数,代表要从源字符串拷贝到目标字符串中的字符数。以下是一个用strncpy()函数拷贝字符串的一部分的例子: #include#include#include int main(int

wwbinghai的专栏 9274

C陷阱缺陷 参考答案 第一

练习 1-1  string s=/*/**/"*/"/*"/**/;                int ans=/*/*/0*/**/1;练习 1-2 个人看法,略。练习 1-3 词法分析规则规定前一个符号所含字符越长越好,直到无法组成一个符号练习 1-4 ((a++)+(++b))...

qq_34689392的博客 1755

strncpystrncat的第三个参数,以及警告C6059

①char *strncpy( char *strDest, const char *strSource, size_t count ); The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is les

我的专栏 6232

C语言的小括号和花括号结合使用&&复合语句

先上代码,对于基于f-statck协议栈改进项目时候,看到一段代码,内核里面的很多宏也经常使用这种复合型语句,看了相关的资料和博客,写下来自己的理解: static int (*real_clock_gettime) (clockid_t , struct timespec *); #define SYSCALL(func) ...

喝醉的鱼博客 8005

C语言进阶:C陷阱缺陷(读书笔记总)

C陷阱缺陷读书笔记,C语言进阶

嵌入式小师兄的博客 4253

《C陷阱缺陷》学习笔记

第一 词法陷阱 笔记本:《C陷阱缺陷》 创建时间:2018/4/23 22:06:21 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs

lyy296293760的博客 4694

C陷阱缺陷读书心得

《C语言陷阱缺陷》中词法陷阱,语法陷阱,语义”缺陷“,连接,库函数,预处理器,可移植性缺陷

chenemy的博客 1306

C陷阱缺陷--笔记

原文链接:http://codeshold.me/2017/01/c_trapsandpitfalls.html

onephone的专栏 2885

《C陷阱缺陷》总结

这本书不是对C语言的批判,而是列出了一些使用C语言常见的错误,以及一些看似简单的陷阱。对于提升对C语言的使用及认识有很大的作用!         该书主要讲解了词法分析、语法分析以及语义细节问题。接着讲解了链接、预处理以及可移植性问题。讲解的都是基础的,容易出错的,都是C语言的基本问题。     词法陷阱很常出现。     1、赋值运算符=逻辑运算符==的区别

u011795520的专栏 2870

【C陷阱缺陷】第2:语法陷阱解析 | 避开C语言中级坑

《C陷阱缺陷》第二解析了C语言中常见的语法陷阱,包括函数声明、运算符优先级、分号使用、switch语句穿透、函数调用和悬挂else等问题。文指出,理解函数声明类型转换的规则至关重要,运算符优先级错误可通过显式加括号避免,分号误用会导致隐蔽错误,switch缺少break会引发穿透执行,函数调用必须带括号,else匹配最近if。通过typedef简化复杂声明、规范代码格式可减少错误。这些陷阱涉及C语言核心概念,理解后能显著提升代码质量。文最后强调,掌握这些细节是成为优秀C程序员的关键。

yuhuasheng1997的博客 1062

【C陷阱缺陷】第1:词法陷阱解析 | 避开C语言编程的初级坑

在C语言编程中,许多看似简单的错误往往源于对词法规则的误解。《C陷阱缺陷》的第一深入剖析了这些“词法陷阱”,帮助程序员从底层理解程序符号(token)的组成解析逻辑。本文基于原书内容整理并扩展,结合实例分析常见问题,为C语言学习者提供实用参考。第一从词法角度揭示了C语言中看似简单却极易出错的细节。这些陷阱不仅是初学者的“拦路虎”,也是资深程序员需持续警惕的问题。通过理解底层规则,我们能更高效地编写可靠代码,避免低级错误。谨慎检查运算符:尤其是==&&等易混淆符号。理解贪心法规则。

yuhuasheng1997的博客 1252

笔记总结】C陷阱缺陷

第一——词法“陷阱” =是赋值运算符,==是比较运算符;=赋值运算符的优先级要低于逻辑运算符|| ,!=和==的优先级要高于&运算符,==比较运算符的结果只可能是0或者1,不可能小于0 字符是用单引号引起的实际代表一个整数,整数值对应于该字符在编译器采用的字符集的序列号如ASCII码;字符串是用双引号引起的实际代表的是一个指向无名数组的起始字符的指针,该数组被双引号之间的字符以及一个'\0'初始化。比如:'yes'表示一个整数值,由y、e、s所代表的整数值按照特定的编译器实现中定义的方式组

XBlog 2371

《C陷阱缺陷笔记

1、运算符优先级:最高级:() [] -> .接着:单目运算符>算数>移位关系逻辑赋值>三目运算符2、注意作为语句结束标志的分号3、小心switch语句的case和break4、悬挂else问题:使用{ }可以避免else问题1、编译器分别将多个源文件单独编译生成多个目标文件,链接器将多个目标文件整合成一个可执行文件,链接器的输入是一组目标模块和库文件,输出一个可执行文件。

潦草大王的博客 1172

C 陷阱缺陷 笔记

C 陷阱缺陷 笔记 引言 《C 陷阱缺陷》是本豆瓣评价很高的一本C语言书。猛戳。关于这本书有多好就不再多说了。这里不求全面的记录全书,只是一些平时不注意和不知道的C特性。 第一:词法"陷阱" 1.1 "&"  PK "&&"   " |"  PK  " ||" & 和 | 是位运算符 ---> 数值  C的安位运算符包括 &,|,~。对操作数的处理方式是将其视为一个二进

chenhuaijin的专栏 678

《C陷阱缺陷》读书笔记

最近花了一点时间阅读了《C陷阱缺陷》 ,东西不多,有些标题就够了,自己总结下需要记录的,以后没事看看。 第 0   导读 无 第 1   词法“陷阱” 本都是一些,拼写错误,主要是仔细,别误写即可。 1.1 =不同于== 比较运算符赋值运算符的相互误写 1.2 &和|不同于&&和|| 按位运算符逻辑运算符的混用 1.3 词法分析中的“贪心法” 1)“大嘴法”:每一个

小人物的草稿本 1050

C陷阱缺陷学习笔记

N年读过这本书,当时读的时候囫囵吞枣,加上时间久远,90%的内容都忘记了。昨天在整理书籍的时候翻出来了,这本书短小精悍却不失为经典之作。抽出时间再拜读一遍,顺便做做笔记,记录精华。

zfs2008zfs的博客 3601

《C陷阱缺陷

用单引号括起的一个字符代表一个整数,而用双引号括起的一个字符代表一个指针,混用会出问题。1、符号间的空白(空格符、制表符、换行符)将被忽略。这里就是先判断==,再进行=

long_steve的博客 1611

精读C陷阱缺陷1

C陷阱缺陷》是2002年美国作者Andrew.Koenig所著,全书只有一百七十多页,是一本非常经典而且比较简洁的好书。前言中介绍了作者在本书中没有教如何使用C语言编程也没有提及数据结构算法,是收集整理了程序员易犯的各种错误,细心研读应该对自我修养的提升有很大帮助。

qq_46129738的博客 303
上一篇: wireshark网络分析笔记
下一篇: atoi函数理解字符存储
慎思明辨
博客等级 码龄12年 32粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值