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时代的错误“,现在的编译器几乎没有差别。



  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3507387.html
Copyright © 2011-2022 走看看