XY

没有任何借口!!!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Pointers On C_读书笔记(一)

Posted on 2008-03-17 22:26  路缘  阅读(502)  评论(0编辑  收藏  举报
1.快速上手
    逻辑上删掉一段代码最好不要用注释,而是用【#if 0   statements #endif】
    如果有些声明需要用于几个不同的源文件中,则可以把相应的声明放在同一个头文件中,避免多个地方复制,方便维护。使用时用#include引入头文件即可。
    
2.基本概念
3.数据
4.语句

    C不存在专门的赋值语句,如【x = y + 3;】确切的说是表达式,而不是赋值语句,因为直接写【y + 3;】也是合法的。
    C不具备布尔类型,而是用整型来代替。零值表示“假”,非零表示“真”。
    else子句从属于最靠近它的不完整的if语句。
    for循环可以写成while循环的形式,但两者再遇到continue时却有不同,for循环不会跳过条件调整部分,而while循环则会。其次是for循环的操纵循环的语句都在一处,而while循环则是分散开的。
5.操作符和表达式
    <<和>>:左移操作符,右边空出来的位补零。右移分逻辑移位和算术移位,其中逻辑移位,则空出位补零。算术移位所空出的位的移入由原先值的符号决定。而具体是执行逻辑移位还是算术移位由编译器决定,所以用了>>就意味着程序不可移植。
6.指针
    
把指针比喻成门牌号的比喻非常不错。但在解释指向指针的指针时,这个比喻的局限性就体现出来了,因为房子的内容不能再是一个门牌号。
    值的类型并不由值本身决定,而是由值的使用方式决定。
    注意【int * a;  *a=12;】这种类型的错误,要养成个习惯,在对指针进行间接访问之前,确保已经对指针进行初始化。 
    指针可以作为左值使用,对指针的间接访问也可以作为左值使用,因为它标识了一个明确的内存位置。
    实例:
Code


    指针运算:指针算法并不依赖于指针的类型,如,一个char指针p,p + 1指向下一个char,若p是一个指向float型的指针,则p+1指向下一个float。  因为指针再与一个整数在执行加法前,会根据合适的大小进行调整。比如若float占据4字节,则p+3,实际加到到指针上的整数值为12,也就是p+(3*4)
                 其次指针的算术运算仅限于两种形式,
                  第1种:指针 +或- 整数
                  第2种:指针 - 指针。只有当两个指针指向同一数组中的两个元素时才允许相减,其结果是有符号整型值,表示两个指针在内存中的距离(是以数组元素长度为单位,不是以字节为单位,因为减法运算的结果将会除以数组元素类型长度)。指向不同数组元素的指针相减,没有任何意义,程序员应避免这种情况出现。
                 指针的关系运算(<、>、>=、<=)跟指针减法一样,只有在指向同一数值中的元素时,指针的关系运算才有意义。

7.函数
   ADT和黑盒:这点还不是很清晰,待补充。。。
    递归:递归的开销比较大,只是有时候用递归,代码显得更清晰而已,像计算阶乘和菲波那契数等在用递归比起用迭代循环时,可读性上并不占优势,而性能更是相差甚远,所以我们完全可以考虑用迭代循环的方式来解决。

8.数组
   数组名通常表示指针常量,但在两种情况下不用指针常量来表示,也就是是作为sizeof操作符或单目操作符&的操作数时。sizeof返回整个数组的长度,而不是指向数组指针的长度。取地址操作符是得到一个指向数组的指针,而不是指向某个指针常量值的指针。
  指针和下标:下班不会比指针更有效率,但指针有时比下标更有效率。看下面两小段程序
           使用下标int array[10], a;
                           for(a = 0;  a<10;  a += 1)
                                array[a] = 0;
           使用指针: int array[10], *ap;
                           for(ap = array;  a < array + 10; ap++)
                                *ap = 0;
           在两种方式的代码中都涉及了乘法,一种是对下标表达式求值时,取得a的值并与整型长度(4)相乘。后一种的ap++,也涉及了乘法,即1和整型长度相乘,而区别在于使用指针的乘法仅在程序编译时执行一次,而使用下标并不是这样。
         多维数组的存储方式,如int array[3][6],其存储形式为【[][][][][][]   [][][][][][]   [][][][][][]】,记住这一点很重要,则关系到指向某数组元素的指针再进行算术运算时的结果。 
    数组指针:int matrix[3][10], *pm = matrix;这条语句存在问题,matrix 其实是指向第1行10个元素的指针数组,而声名指针数组应该用如下方式:
                  int {*pm}[10] = matrix;
    其次要注意指针数组和矩阵的差别,比如在存储许多字符串时,可以联想到不同的情况两者不同的优势。
9.字符串
    strlen返回的值是size_t类型的值,是无符号整数类型。所以形如if(strlen(x) - strlen(y) >=0 )会出乎你的意料,因为无符号类型的值不肯能为负,所以该语句的判断总是为真。如果把strlen的返回值强制转换为int,可消除此问题。
    程序员再复制字符串时要保证目标字符数组的空间大于源目标字符串的长度,因为若发生多余,多余的字符仍会被复制,并覆盖目标数组后面的内存,strcpy无法解决这个问题,仍何情况下覆盖未知的内存值,都将是危险的。