现在的位置: 首页 > 综合 > 正文

Expert C Programming读书笔记III

2017年12月15日 ⁄ 综合 ⁄ 共 1998字 ⁄ 字号 评论关闭
其实看了很多了,一直没有笔记。

The Early Bug gets() the Internet Worm
本段主要讨论了缓冲区溢出造成的安全隐患。在栈上展开数组的时候,由于C语言对数组边界的检查几乎没有,所以很可能导致栈的溢出,进而使得别有用心的人执行一些非法代码。Finger是一个例子。解决的办法是,向数组赋值的时候(特别是字符串)限制一次读入数据的长度。

Sins of Omissions
1、在参数parse的时候,可能出现的是没有详细分析整体,而只分析了部分。特别的,unix用-作为参数起始符,这样将文件名以-开始会造成麻烦。
2、空格的作用
 i./[空格][换行]和/[换行]带来两个不同的结果。特别的,在长字符串中,用/作为换行衔接,这样就不能在/后加上空格。
 ii.对于y+++++x,只能用y++ + ++x形式,否则编译器会理解为((y++)++)+x从而产生错误。
 iii.*x/*y不能编译,只能用*x/ *y
 iv.个人补充一个c++方面的问题:graph_traits<adjacency_matrix<...> >这里必须写成> >而不是>>,除非等到c++0x出来。

C++ Comments
C++的//符号并没有解决/* */带来的问题。

Compiler Date Corrupted
这一节主要讲的是,不要返回本地堆栈内的东西,否则会因为函数返回清栈而导致返回值崩坏。
解决:
1、返回data segment里面的内容。
 i.定义的常数值
 ii.全局变量
2、返回一个函数内的static成员。(注:这样在多线程下会出现问题,除非采用加锁或者pthread_key_create)
3、返回堆上指针。这样需要擦屁股。
4、最好的方法是,把申请内存的任务交给调用方。

Lint Should Never Have Been Separated Out
要经常使用Lint。现在常有的Lint包括Win下的PC-Lint(2900文法币)和Lin下的FlexeLint(8900文法币),都买不起。尝试oint中,编译不通过。

第三章 C语言中的声明

Syntax Only a Compiler Could Love
对于int* p[3];,要注意到*的优先级高于[]的优先级,所以是an array contains 3 pointer to integer。而int(*p)[3]是an pointer to an array with 3 ints.
const int==int const
但是const int*=指针能移动但是不能更改数值,int* const=指针能更改数值但是不能移动。

A Word About structs
struct tag{...} a,b,c;中tag是tag声明,而abc是具体对象。
有的C书(例如傻子谭的书)提到,函数的参数是right to left入栈的,这素扯蛋。struct一定入栈,但是int等参数可能通过寄存器传递。

A Word About unions
union的一个有趣的用法是:
union union_tag {
    int_32 A;
    struct { char c1,c2,c3,c4; } partical_data;
}

A Word About enums
enum里面的数据是按照前一个数据加一的。

The Precedence Rules
求解C中的复杂对象声明。见书。

typedef Can be your friend
对于形如void (*signal(int,void (*) (int)) (int),容易推导出含义为:a pointer to a function takes int and function void (*) (int) as parameter and return a pointer to a function takes int and return void.
采用typedef void (*fun_argument) (int); 可以简化为fun_argument signal(int,fun_argument);
typedef一行只要定义一个类型,并且typedef应该放在最前面。

Difference between typedef and #define
例如:typedef int* intp_tag; #define int* intp_def;
intp_def a,b; // a is int* while b is int
intp_tag a,b; // both a and b are int*

typdef struct foo { ... foo; } foo;
第一个foo是struct用到的,称作tag,第二个foo是成员变量名,第三个是类型名。
第一个foo使用的时候必须前面加上struct标明是struct。
第三个foo则不需要加上struct,因为它是类型名。

typdef应当用于以下三种用处,而不应用于struct的缩写:
1、组合function,array,structs
2、可能用到的跨平台类型。
3、类型转换。

 

抱歉!评论已关闭.