Expert C Programming总结(二)


  1. “声明的形式和使用的形式相似”这种用法可能是C的独创。至今为止一个比较好的声明指针的方法是: int &p;  它至少提示p 是一个整形数的地址。这种语法现已被C++采纳,用于表示参数的传址调用(引用)。

 

  2.  如果想要把什么东西的类型强制转换为指向数组的指针,就不得不使用下面的语句来表示这个强制类型转换:

       char (*j) [20];

       j = (char (*) [20]) malloc(20);

     如果把想好两边看上去的明显多余的括号拿掉,代码就会变成非法。

  

   3. 变量名的声明应该与类型的声明分开。

   4. 参数传递的问题:

       (1) 有些C语言书籍声称“在调用函数时,参数按照从右到左的次序压到堆栈中。”这种说法过于简单了。  参数在传递时首先尽可能的放在寄存器中(追求速度)。注意,int型变量i跟只包含这个int型成员的结构变量s在参数传递时的方式可能完全不同。一个int型参数一般会被传递到寄存器中,而结构参数则有可能被传递到堆栈中。第二点要注意的是,结构中放置数组,如:struct s_tag { int a[100] ;}; 

 现在,可以把数组当作第一等级的类型,用赋值语句拷贝整个数组,已传值调用的方式把它传递到函数,或者把它作为函数的返回类型。 

   (2)  在典型情况下,并不会频繁地对整个数组进行赋值操作。但是如果需要这样做,可以通过把它放入结构中来实现。


  5. 联合(union):在内存中的存储,所有的成员都从偏移地址零开始存储。这样,每个成员的位置都重叠在一起:在某个时刻,只有一个成员真正存储于该地址。

   

 6. union一般被用来节省空间的。因为这些数据项是不可能同时出现的,如果同时存储他们,显然颇为浪费。


 7. 关于枚举:

       枚举具有一个优点:#define 定义的名字一般在编译时被丢弃,而枚举的名字则通常一直在调试器中可见,可以在调试代码时使用它们。


 8. 前缀操作符:*表示“指向... 的指针”。  如果const和volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符。在其他情况下,const和volatile关键字作用于它左边紧邻的指针星号。


 9. typedef为数据类型创建别名,而不是创建新的数据类型,可以对任何类型进行typedef声明。

   (1) typedef和宏文本替换之间存在一个关键性的区别。把typedef堪称是一个彻底的“封装”类型——在声明它之后不能再往里面增加别的东西。

  如:typedef int banana;

         unsigned banana i ; // 错误,非法。

   (2)在连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变量均为同一种类型,而用#define定义的类型则无法保证。如下:

      #define int_ptr int *

     int_ptr  a , b ;

     a 为指针,b为int类型变量。

   而typedef则不会这样。


  10. 操作typedef第提示:

        不要为了方便起见对结构使用typedef。 这样做的唯一的好处是能使你不必书写“struct”关键字,但这个关键字可以向你提示一些信息。

       typedef应该用在: (1)数组,结构,指针以及函数的组合类型。

              (2)可移植类型。当你需要一种至少20比特的类型时,可以对它进行typedef操作typedef的提示声明。这样,当把代码移植到不同的平台时,要选择正确的类型如:short,int ,long时,只要在typedef中进行修改就可以了。无需每个声明都去加以修改。


  11. 错误思想:“数组定义等同于指针的外部声明”  如: 文件一: int a[10];  文件二:extern int *a;  

  

 12. 区分定义和声明:

       声明相当于普通的声明:它所说明的并非自身,而是描述其他地方的创建的对象。 

       定义相当于特殊的声明:它为对象分配内存。


 13. 编译器为每个变量分配一个地址(左值)。这个地址在编译时可知。而且该变量在运行时一直保存在这个地址。相反,存储于变量的值(它的右值)只有在运行的时候才可知。如果需要用到变量中存储的值,编译器就发出指令从指定的地址读入变量值并将它存于寄存器中。


  14. 定义指针时,编译器并不为指针所指向的对象分配空间,它只分配指针本省的空间,除非在定义时,同时赋给指针一个字符串常量进行初始化。 注意只有对字符串常量才是如此。不能指望为浮点数之类的常量分配空间。

    如:float *p = 3.14;     //错误。


  15. 链接器确认main函数为初始进入点,把符号引用绑定到内存地址,把所有的目标文件集中在一起,再加上库文件,从而产生可执行文件。



 





你可能感兴趣的:(c,struct,存储,语言,float,编译器)