《C陷阱与缺陷》第一章

时间:2022-06-23 03:55:48

《C陷阱与缺陷》第一章
本章导读部分:
利用p->s="->";这个语句展示了相同符号在上下午环境不同的情况下解释是可以不同的。并通过if(x>big) big=x;这个例子加深了对词法分析的理解。
本章正文:
1.1,=与==。
使用if(a=b)所进行的判断是将b的值赋给a并判断a是不是为0;
使用if(a==b)是表示a和b是否相等;
本书一个比较具有代表性的例子

while(c=' '||c=='\t'||c=='\n')
c=getc(f);

此实例本意是遍历文件并且跳过空和一些换行符,制表符。但是由于第一个==写成了=则此程序变成了。将‘ ’||c=='\t'||c=='\n'表达式的值赋给了c,并判断c的值。由于c恒等于1则这会读取到文件最后。
如果真的想要实现在判断中使用=的情况应该写成:

if((x=y)!=0)

这样写就比较清楚意图了。
1.2,&和|不同于&&和||
这个具有基本语法的人都知道,&和|为二进制运算符,&&和||为逻辑判断运算符。
1.3,词法分析中的贪心法。
c语言中分析词法一般都是往多了分析。
如果/的后面跟着那第一个/并不会分析为除法。而是和组成/*用来注释语句。
本书几个代表性的例子为
(1)

a---b    //a-- -b

(2)

y=x/*p    // y=x (/*)p

(老版编译器由于支持=+代表+=则会出现a=-1解释为a =- 1即a=a-1而并不是a=(-1))
所以为了避免有可能发现这种情况还是加括号吧。
1.4,整型常量
在整型数前使用0开头的是八进制表示方法。
x=010;实际上x为8;
1.5,字符和字符串
用单引号包起来的一个字符实际上代表一个整数,整数值对应该字符在编译器中采用的字符集中的序列值。
因此'a'的含义与97严格一致
用双引号包起来的字符串,代表的是一个指向无名数组起始字符的指针。自动使用‘/0’当做结尾。
hello=”Hello\n“与hello[]={'H','e','l','l','o','\n','\0'}一致
整数型(16位或32位)一般可以容纳多个字符(8位)数值按编译器组合得到。
本书几个代表性的例子为
char *str='\n' 错误因为使用单引号包起来实际是个整数,不能赋给字符指针。
printf('\n') 以前版本的编译器可能不会报错,因为不会检查函数参数类型,现在的编译器会出现不可知的错误。
练习1-1:

#include <stdio.h>
using namespace std;
int main() {
    int ans = /*/*/0*/**/1;
    printf("%d\n", ans);
    return 0;
}

如果支持嵌套。则ans可以分解为 //0// 1;则输出为1
如果不支持嵌套。则ans可以分解为/
// 0 * // 1则01则输出为0
练习1-2:
我会允许嵌套注释。
练习1-3:
由贪心来说
a+++++b可以分解为 a ++ ++ + b则报语法错误。因为a++的结果为左