原创 读:Expert C Programming -- Deep C Secrets

2007-8-23 15:01 4581 7 7 分类: 软件与OS
代码:
    if(i==3)
    if(3==i)

dog one's steps

Chapter 1.
   const
 
Chapter 2.
    一个'L'的NUL用于结束一个ASCII字符串
    两个'L'的NULL用于表示什么也不指向(空指针).

    C语言中的符号重载


Symbol


Meaning


static


在函数内部,表示改变量的值在各个调用间一直保持连续性


(Inside a function, retains its value between calls)


在函数这一级,表示函数只对本文件可见


extern


用于函数定义,表示全局可见(属于冗余的)


用于变量,表示它定义在其他地方


void


作为函数的返回类型,表示不返回任何数值 void function()


在指针声明中,表示通用指针的类型 void *ptr;


位于参数列表中,表示没有参数   function(void)


*


乘法运算符


用于指针,间接引用  *ptr = 0 ;


在声明中,表示指针   char *ptr



位的AND操作符


取地址操作符


=


赋值符


==


比较运算符


<= 


小于等于运算符


<<=


左移复合赋值运算符


<

 


小于运算符


#include指令的左定界符


( )


在函数定义中,包围形式参数表


调用一个函数


改变表达式的运算顺序


将值转换成其他类型(强制类型转换)


定义带参数的宏


包围sizeof操作符的操作数(如果它是类型名) sizeof(int)


   
    C语言运算符优先级存在的问题       


优先级问题


表达式


人们可能误认为的结果


实际结果


.的优先级高于*


->操作符用于取消这个问题


*p.f


P所指向的字段f  (*p).f


The f field of what p points to


pf偏移,作为指针然后进行解除引用操作 *(p.f)


 


[ ]高于*


int *ap[ ]


ap是个指向int型数组的指针


int(*ap)[ ]


ap是个以指向int型的指针为元素的数组 int * (ap[ ])


函数( )高于*


int *fp( )


fp是个函数指针,该函数返回int int(*fp)( )


fp是个是个函数,返回int *


 int *(fp( ))


===!高于运算符


(val&mask!=0)


(val&mask)!=0


val&(mask!=0)


===!高于赋值符


c=getchar()!=EOF


(c=getchar())!=EOF


c=(getchar()!=EOF)


算术运算法高于移位运算符


msb<<4 + lsb


(msb<<4)+lab


msb<<(4+lsb)


逗号运算符在所有运算符中优先级最低


i=1,2


i=(1,2)


(i=1),2


             
Chapter 3.
       C语言的声明         


       There's some good news and some bad news associated with unions. The bad news is that the good news isn't all that good.


        理解C语言声明的优先级规则


A  声明从它的名字开始读取,然后按照优先级次序一次读取


B 优先级从高到低依次是:


    B.1 声明中被括号括起来的那部分.


    B.2 后缀操作符:


           括号( )表示这是一个函数,而方括号[ ]表示这是一个数组.


    B.3 前缀操作符: *表示这是一个"指向...的指针"


C 如果const和(或)volatile关键字的后面紧跟着类型说明符(如int,long等),那么它作用于类型说明符.在其他情况下const和(或)volatile关键字作用于它左边紧邻的指针星号.


typedef和宏文本替换的区别(2点):


 1.可以用其他的类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做.

    #define peach int

    unsigned peach i;/*没问题*/


    typedef int banana;

    unsigned banana i;/*错误!非法*/

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

    #define int_ptr int *

    int_ptr chalk , cheese;

经宏扩展,第二行变为 int * chalk , cheese; 这使得chalk为 int * 而cheese为int

    typedef char * char_ptr;

    char_ptr Bently , Rollce_Royce;

Bently和Rollce_Royce为同一类型.

Chapter 4.

声明和定义

声明相当于普通的说明:它说明的并非自身,而是描述其他地方创建的对象.可以出现多次.

定义相当于的特殊的说明:它为对象分配内存.只能出现在一个地方.

Chapter 4.

函数库链接的5个秘密:

1.动态库文件的扩展名是".so",静态库文件的扩展名是".a"

2.例如,通过-lthread选项,告诉编译器链接到"libthread.so",即使用"-l"就可把name扩展成libname.so

3.编译器期望在确定的目录找到库.

4.观察头文件,确认所使用的函数库.

5.与提取动态库中的符号相比,静态库中符号提取的方法限制更严.

Chapter 7.

const和volatile类型修饰符修改的是左边紧邻的项目.

地址对齐:访问一个8字节的double数据,其地址必须是8的整数倍.所以一个double型的数据只能存储在24,8008或32768,但不能存储在地址1006(因为它无法被8整除).

p188



文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条