zoukankan      html  css  js  c++  java
  • 《征服C指针》读书笔记

    本文同时发布在我的个人博客上,欢迎访问~ www.seekingdream.cn

    在读完K&R之后,对C的认识就是指针、数组。网上的人们对指针也有些“敬而远之”的感觉。最近从同学处淘得《征服C指针》一书,首先映入眼帘的是封面的“毒舌程序员”这个称号。用这个周末的时间,把这本书读了一下,最大的感受确实是“毒舌”。下面细细谈谈自己的几点感受吧!

    1、看到这本书的时候,想到的是西游记。本书的作者就是西游记中的“孙悟空”,纵使其有百般武艺,却始终摆脱不了“如来”的五指山。哪谁是“如来”呢?自然是K&R.作者是在博人眼球呢,还是在借K&R来提高自己的名气呢?毕竟中国有句古话“看一个人有多优秀,要看他的对手是谁”。本书中作者处处指出K&R中的“错误点”,并且死死揪住这些点死死不放,不过也是,谁让K&R当时不严谨呢?

    2、个人感觉本书有点“虎头蛇尾”。在读完该书的前面2章的时候,带着一种崇敬的眼光来看,毕竟“原书畅销11年”,所以自己的收获也是比较大的。最让我感到高深的就是文中的第二章“C是怎么使用内存的”,作者确实是讲的比较深入。不过从第三章开始,作者在一直不断的重复C中的声明,并且一直在纠结于一些很细的语法点。从中可以看出作者确实是功力深厚,可是这是不是给人一种在卖弄的感觉呢?到本书的第四章,主要讲了“数组和指针的常用方法”,应该来说在应用方面还是不错的。至于第五章,鉴于网上对该章的评价不高,又由于自己本次的目的是深入了解指针,所以就直接跳过了。第六章则讲述了指针方面的一些陷阱和惯用用法。

    以上是自己读过本书的一点感受。

    下面是读该书时的笔记:

    1、先有了指针类型,因为有了指针类型,所以有了指针类型的变量和指针类型的值。
    2、在C语言标准中,关于main()函数的使用只有如下两种方式:
         int main(int argc,char *argv[])或者int main(void)
         尽管如此,在一些书中会出现void main(void)这样的写法,这是错误的。有些编译器会通过,但是也有一些会出现错误。
    3、对指针加减运算,标准只允许指针指向数组内的元素,或者超过数组长度的下一个元素。
    4、在C语言中对指针加1,地址的值会增加当前指针所指向数据类型的长度。
    5、当常量0处于应该作为指针使用的上下文中时,他就作为空指针使用。
    6、如果试图将数组作为函数参数进行传递,那就传递指向初始元素的指针。
    7、无论如何都要将数组进行值传递的时候,建议将数组整体整理成结构体成员。
    8、在下面声明的形参,都具有相同的意义
             int func(int *a) = int func(int a[]) = int func(int a[10])
    第二章:
    1、在如今的运行环境中,应用程序面对的是虚拟地址空间
    2‘、关于scanf:
    scanf()不是以行单位对输入内容进行解释,而是对连续字符流进行解释(换行字符也视为一个字符)。如果使用语句scanf("%d",&tmp),scanf连续地从流读入字符,并且对和格式说明符(%d)相匹配的部分进行变换处理。如果输入的不是整数,则出错。并且出错的字符会依旧残留在流中。
    如果想使用以下语句:
    while(scanf("%d",&hoge) !=-1) {
        /*操作*/
    }   则可以使用fgets()和sscanf()组合来代替,就可以避免上面提到的问题。
    (ps:关于fgets的文章可以参考下,不错。http://blog.csdn.net/jackin2/article/details/5573771)
    3、c语言中通过malloc()动态分配的内存区域,寿命到调用free()为止。
    4、在c中,正如数组在表达式中可以被解读成指针一样,”函数“也同时意味着”指向函数的指针“。通常,这个指针指向函数的初始地址
    5、自动变量的地址是在运行时被决定的,它属于链接器管辖范围以外的对象。自动变量重复使用内存区域。因此,自动变量的地址是不一定的。
    在C语言中,通常将自动变量保存在栈中。
    通过将自动变量分配在栈中,内存区域可以被重复利用,这样可以节约内存。
    6、C语言的参数是从后往前被堆积在栈中的。这样做是为了实现可变长参数这个功能。重要的是无论需要堆积多少参数,总能找到第一个参数的地址。
    7、malloc可以动态地(运行时)进行内存分配,并且可以通过任意的顺序释放。malloc分配的区域是堆,而不是栈。
    8、定义可变数组: 
    char *arr;
    arr = malloc(sizeof(char)*len);
    9、C语言默认地将没有声明的函数的返回值解释成int类型,那些运气好的程序,如果被迁移到int和指针长度不同的处理环境中,就会突然跑不起来。
    10、在C中不需要对malloc()的返回值进行强制类型转换,但是在C++中则必须要进行强制类型转换。因为C++可以将任意的指针赋给void*类型的变量,但不可以将void*类型的值赋给通常的指针变量。
    11、malloc()大体的实现是从操作系统一次性地取得比较大的内存,然后将这些内存”零售“给应用程序。
    12、free()之后,如果此时还有其他地址使用这部分内存,则内存不会立马释放。
    13、无论是整数还是浮点小数,内存上的表现形式都随着环境的不同而不同。
    14、在C语言编程过程中,一旦出现bug,请带着”指针就是地址“的观点去解决它--这种姿态在解决bug上是恰到好处的。 
    
    15、解读C声明
    (1)复杂C声明的解读:http://ashin.sinaapp.com/article/54/
    16、C中,数组是不能作为参数传递的。只能传递指向数组初始元素的指针。
    17、const修饰的是紧跟在它后面的单词。
    18、对于函数的形参,最外层的数组会被解读成指针,即使定义了元素个数,也会被无视。
    19、应该记住:数组和指针是不同的事物。一些常见的指针和数组的错误使用:
    (1)int *p; p[3]  此时的错误是:突然使用没有指向内存区域的指针。自动变量的指针在初期状态,值是不定的
    (2)char str[10];...str =“abc”;  此处的错误是:突然向数组赋值。数组既不是标量,也不是结构体,不能临时使用
    (3)int p[];此处的错误是使用空的[ ]声明局部变量。只有“在函数的声明中”,数组的声明才被解读成指针。
    20、在表达式中,数组可以被解读成指向其初始元素的指针。
          只有在声明函数的形参的时候,数组的声明才能解读成指针的声明。
    第四章
    21、如果需要通过函数返回值以外的方式返回值,将“指向T的指针”(如果想要返回的值得类型为T)作为参数传递给函数。
    22、想要将类型T的数组作为参数进行传递,可以考虑传递“指向T的指针”。可是,作为被调用方是不知道数组的元素个数的,所以在必要的情况下,需要使用其他方式进行参数传递。
    23、在需要获取类型T的可变长数组时,可以使用malloc()来动态地给“指向T的指针”分配内存区域。但此时需要程序员自己对数组的元素个数进行管理。
    24、指针可以指到数组的最后元素的下一个元素。
    第六章
    25、如果使用strncpy(),请注意它可能产生没有空字符结尾的字符串。
    备注:for(i = 0;i<LoopMax;i++){
              /*array[i] 会出现多次*/
         }
        for(p=&array[0];p!=&array[Loopmax];p++){
              /* 在这儿*p 进行各种各样的处理。*p会出现多次*/
        }
    K&R的TCPL中曾经描述了“一般情况下,使用指针的程序比使用数组要高效”,但是自己并不知道原因,现在《征服C指针》中有这方面的描述:array[i]相当于*(array+i)的加法运算,如果再一个for循环里面,则执行多次array的加法运算,此时必然效率低。如果用指针,则加法运算只有在循环结束的时候执行一次。
    这完全是"K&R时代的错误“,现在的编译器几乎没有差别。



  • 相关阅读:
    初步了解Ajax
    什么是applet
    FilterLog代码分析
    Async分析
    HttpServletRequest hrequest
    xml的定义用途
    企业级与应用级的区别
    未来规划
    黄金点游戏
    hashCode与eqauls
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3507387.html
Copyright © 2011-2022 走看看