zoukankan      html  css  js  c++  java
  • 阅读笔记《c陷阱与缺陷》《c和指针》

    《c陷阱与缺陷》笔记

            ——————2011/12 

     

    1. 表达式的结合:依次尽可能多的读取字符,直到读取下一个不能组成完整意义的字符(贪心法),或遇到空白(空格,tab,回车)停止。 (有的运算符从右到左结合)

     

    2. 声明表达式的意义: 一个声明(如: float f,g;),对表达式fg求值的结果为float型, 那么float ((a)); ((a))求值也为float行,所以afloat型。         一旦知道了如何声明一个变量,那么该变量的类型转换符也很容易知道:去掉声明中的变量名和分号,在把剩余部分用括号括起来即可。(例如:void (*fp)(); 类型转换符为(void (*)() 。调用地址为0处的该类型的函数:(*(void (*)())0)(); ),引入typedef后方便多了。

     

     

    3. 运算符优先级      ::作用域访问符高于一切

     

    算数,移位,关系,位,逻辑,条件,赋值(从右至左),逗号。

     

    4. 数组与指针

      int a[4]; int *pa; 数组名a表示该数组元素首部的地址( pa = a,pa存储的为数组a的首地址),但sizeof(a)的值却是整个数组的大小,并不为指针所占的内存大小。

    a[i]等价于*(a+i),他们均表示数组a的第i个元素的引用。

    int b[4][5]; int *pb; 数组b表示以4int[5]数组为元素的一维数组(没有真正的二维数组)

    b[3]表示数组b最后一个元素所指向的地址,即最后一个int型数组元素的起始地址,(pb = b[3],pb指向最后一个int型数组的首地址)         b表示以一维数组为元素的数组的首地址,指向的是int[5]型的数组,而pb是指向int型,所以pb=b会产生编译错误,因为类型不匹配。 那么定义一个指向int[5]型数组的指针则可以赋值,即int (*p) [5]; p=b则正确。

      (语义陷阱3.1:当不清楚时回头看看声明变量时是怎么定义的!!!)

     

    5. 外部变量与局部变量

      分清楚声明与定义,类型一定要匹配。外部变量自动赋初值0,局部变量声明后,必须初始化才能使用(局部int a;  printf(%d,a);将会出错,因为声明局部变量a之后未初始化,但是万能的指针能访问)。

     

    6. 强制让输出不进行缓冲:setbuf(stdout, (char *) 0 );

      调用库函数时一定要清楚的知道其返回类型,特别是用于判断语句时。

     

    7. 宏中一个表达式的每一个变量一定要用括号括起来,整个表达式也要用括号括起来。

      #define MAX(a,b)  ((a)>(b)?(a):(b))       倘若不加括号,那么调用2*MAX(3-2,2-1)+1;试试,宏定义时,还要注意第一个空格符不能随意出现。宏命名应该用大写(无论是函数还是变量)

     

    8. 在一个平台上写程序时,一定要注意各个基本类型占用的内存大小,选择适当的类型时,若考虑到移植性问题,则可用typedef来定义,这样如果一直到其他平台要更改这个类型时,只需改typedef一处即可。

     

    9. c之I/O接口

     

     

     

     

    《c和指针》笔记

          ——————2012/3 

     

    1. 用预处理来注释不要的代码。(方便)

       #if 0

       statements

       #endif

     

    2. struct{int a; char b; char c;};struct{char a; int b; char c;};占用的内存大小不同,取决于系统机器的整型长度,若整型为4个字节  ,那第一个占用8字节,第二个占用12字节。

     

    3. 指针函数主要用于回调函数和转移表。回调函数(在一个有num,name,pNext成员的学生链表中,查找一个给定的value,可用num,name两种查询,应定义两种比较函数和一个查询函数,将指向比较函数的指针作为参数传递给查询函数,采用函数回调方式);转移表(定义指向函数的指针数组,如:int (*f[])(parameters);每一个数组成员便是一个指向特定操作的函数的指针,这样可以避免庞大的switch操作)

    函数名可以作为函数形参数,参数传递时,编译器自动将该函数名转换为指向函数的指针,就如同数组名做形参一样。而函数的返回类型则不能是函数名,他不会自动转换为指针,所以必须定义为指向函数的指针,就如同函数的返回类型不能是数组,要用指向数组的指针一样。

     

    4. 字符串常量 

      "xyz"+1 表示字符y的地址。(因为常量"xyz"表示该字符常量的首地址。)  &"abcdef"[2]表示字符c的地址

     

    5. #if defined(File)             #if !defined(File)     

       #ifdef  File                  #ifndef     File

       每一对是等价的。但用#if可以嵌入其他表达式:  #if a<0 && defined(MAXSIZE)

     

    6. 可变参数函数列表<stdarg.h>

    一般不要使用。(在面向对象编程时容易导致接口模糊)

     

    7. c程序中加入汇编代码:

    _asm

    {

    mov ax,10

    }

     

  • 相关阅读:
    struts2 json返回试验
    ABCD四个人说真话的概率都是1/3。假如A声称B否认C说D是说谎了,那么D说过的那句话真话的概率是多少
    ABCD四个人说真话的概率都是1/3。假如A声称B否认C说D是说谎了,那么D说过的那句话真话的概率是多少
    大数据学习路线copy自淘宝
    大数据学习路线copy自淘宝
    大数据学习路线copy自淘宝
    在Action获取Scope对象
    在Action获取Scope对象
    动态Result配置
    动态Result配置
  • 原文地址:https://www.cnblogs.com/songcf/p/3042229.html
Copyright © 2011-2022 走看看