《C程序设计语言》笔记----第二章 类型、运算符与表达式

    技术2022-05-19  23

     

    2章 类型、运算符与表达式

    1.数据类型及长度

    C语言只提供了下列几种基本数据类型:

    char     字符型,占用一个字节,可以存放本地字符集(ANSI)中的一个字符

    int      整型,通常反映了所有机器中整数的最自然长度

    float     单精度浮点型

    double   双精度浮点型

    此外,还可以在这些基本数据类型之前加一些限定符。shortlong两个限定符用于限定整型。int通常代表特定机器中整数的自然长度,如32位的计算机,int类型长度就为4个字节。short类型通常为16位,即2个字节,long类型通常为32位,int类型可以为16位或32位。个编译器可以根据硬件特性自主选择合适的类型长度,但要遵循以下限制:shortint类型至少为16位,而long类型至少为32位,并且short类型不得长于int类型,而int类型不得长于long类型。

     

    signedunsigned可用于限定char类型和任何整型,分别表示有符号数和无符号数。

     

    long double类型表示高精度浮点数。同整型一样,浮点型的长度也取决于具体的实现。

     

     

    2.常量

    long类型的常量以字母lL结尾,如123456789L。如果一个整数太大以至于无法用int类型表示时,也就被当做long类型处理。无符号常量以字母uU结尾,如123U。后缀ulUL表明是unsigned long类型。

     

    浮点数常量包含一个小数点(123.4)或一个指数(1e-2,表示1×10-2),也可以两者都有。没有后缀的浮点数常量为double类型。后缀fF表示float类型,而后缀lL则表示long double类型。

     

    整型数出了用十进制表示还可以用八进制和十六进制表示。带前缀0的整型常量表示八进制形式;前缀为0x0X,表示十六进制形式。八进制和十六进制的常量也可以使用后缀L表示long类型,使用后缀U表示unsigned类型。例如,0XFUL是一个unsigned long类型的常量,其值等于十进制15

     

    一个字符常量是一个整数。

    下面使用八进制和十六进制表示一个字符

    ‘/111’,表示一个字符,它的值是八进制0111,即十进制的73

    注意,只有斜线后边的数字个数小于等于3大于等于2,且每一位都在0-7之间它才表示一个八进制数。

    ‘/x11’,表示一个字符,它的值时十六进制0x11,即十进制的17

     

    ANSI C语言中的全部转义字符序列如下:

    /a  响铃符             //  反斜杠

    /b  退格符             /?  问号

    /f  换页符             /’   单引号

    /n  换行符             /”  双引号

    /r  回车符             /ooo 八进制数

    /t  横向制表符         /xhh 十六进制数

    /v  纵向制表符

     

    常量表达式是仅仅包含常量的表达式。这种表达式在编译时求值。他可以出现在任何常量可出现的地方。

     

    字符串常量也叫字符串字面值。是有双引号括起来的0个或多个字符组成的字符序列。

    编译时可以讲多个字符串常量连接起来,如下:

    “hello, ”  “world”

    等价于

    “hello, world”

    两个字符串之间可以存在多个空格。

     

    枚举常量是另外一种另外一种类型的常量。枚举是一个常量整数值的列表,例如:

    enum Boolean{NO, YES}; /* 声明一个枚举变量*/ enum Boolean b; /* 为枚举变量赋值*/ b = NO; /* 等价于: enum Boolean b = NO; */ 

     

    枚举为建立常量值与名字之间的关联提供了一种便利的方式。相对于#define语句来说,枚举的优势在于常量值可以自动生成。尽管可以声明enum类型的变量,但编译器不检查这种类型的变量中存储的值是否为该枚举的有效值。不过,枚举变量提供这种检查,因此枚举比#define跟具有优势。此外,调试程序可以以符号形式打印出枚举变量的值。

     

     

    1.   声明

    C语言中所有变量都必须先声明后使用。

    从概念上讲,外部变量和静态变量是在程序开始执行之前进行初始化,并且初始化表达式必须是常量表达式。若没有显式为外部变量和静态变量初始化,那么默认会被初始化为0。而对于自动变量,若为显式初始化,则它的值为未定义值(无效值)。

     

    任何变量的声明都可以使用const限定符限定。该限定符指定变量的值不能被修改。对于数组而言,const限定符指定数组所有元素的值都不能被修改。const限定符也可配合数组参数使用,它表明函数不能修改数组元素的值。

     

    4.运算符

    运算符按照优先级大小由上向下排列,在同一行的运算符具有相同优先级。第二行是所有的一元运算符。  

    运算符

    解释

    结合方式

    () [] -> .

    括号(函数等),数组,两种结构成员访问

    由左向右

    ! ~ ++ -- + - * & (类型) sizeof

    逻辑非,位运算非,增量,减量,正负号,间接,取地址,类型转换,求大小

    由右向左

    * / %

    乘,除,取模

    由左向右

    + -

    加,减

    由左向右

    << >>

    左移,右移

    由左向右

    < <= >= >

    小于,小于等于,大于等于,大于

    由左向右

    == !=

    等于,不等于

    由左向右

    &

    按位与

    由左向右

    ^

    按位异或

    由左向右

    |

    按位或

    由左向右

    &&

    逻辑与

    由左向右

    ||

    逻辑或

    由左向右

    ? :

    条件

    由右向左

    = += -= *= /= 

    &= ^= |= <<= >>=

    各种赋值

    由右向左

    ,

    逗号(顺序)

    由左向右

     

    我们要记住以下几点:

    u       任何单目运算符的优先级高于双目运算符的优先级

    u       何逻辑运算符的优先级要低于任何关系运算符

    u       移位运算符的优先级比算术优先级低,但是比关系运算符高

    u       逗号运算符的优先级最低,而赋值运算符的优先级仅高于逗号运算符

     

    一个小例子:

    printf("%d/n", 0<3<2);

    输出结果为:1

    为什么?

    因为关系运算符结合性是从左到右,那么0<3<2等价于(0<3)<20<3的值为1,然后1<2,所以最后的结果为1,即为真。

     

    按位运算符

    一元运算符~用于求整数的二进制反码,即分别将操作数各二进制位上的1变为0,0变为1.例如:

    x = x & ~077;

    x的后6位设置为0。注意表达式x&~077与机器无关,他比形式为x&0177700的表达式要好,因为后者假定x16位的数值。这种可移植的方式并没有增加额外的开销,因为~077是常量表达式,可以在编译时求值。

     

    下面是几个有意思的函数:

     

    /* getbits函数:返回x中从p位开始的n位,左边第一位是第0位*/ unsigned getbits(unsigned x, int p, int n) { return ~(~0<<n) & (x >> (sizeof(x)*8-p-n)); } /* 统计x中值为1的二进制位数*/ int bitcount(unsigned x) { int b; for (b=0; x!=0; x>>=1) if (x & 01) ++b; return b; } 

     


    最新回复(0)