C语言学习笔记(三四)

C语言学习第三十四天。

4.11.3 条件包含
还可以使用条件语句对预处理本身进行控制,这种条件语句的值时在预处理执行的过程中进行计算。这种方式为在编译过程中根据计算所得的条件值选择性地包含不同代码提供了一种手段。
#if语句对其中的常量整型表达式(其中不能包含sizeof、类型转换运算符或enum常量)进行求值,若该表达式的值不等于0,则包含其后的各行,知道遇到#endif、#elif或#else语句为止(预处理器语句#elif类似于else if)。在#if语句中可以使用表达式define(名字),该表达式的值遵循下列规则:当名字已经定义,其值为1;否则,其值为0.
例如,为了保证hdr.h文件的内容只被包含一次,可以将该文件的内容包含在下列形式的条件语句中:

    #if !define(HDR)
    #define HDR

    /* hdr.h文件的内容放在这里 */

    #endif

第一次包含头文件hdr.h时,将定义名字HDR;此后再次包含该头文件时,会发现该名字已经定义,这样将直接跳转到#endif处。类似的方式也可以用来避免多次重复包含同一文件。如果多个头文件能够一致地使用这种方式,那么每个头文件都可以将它所依赖的任何头文件包含进来,用户不必考虑和处理头文件之间的各种依赖关系。
下面的这段预处理代码首先测试系统变量SYSTEM,然后根据该变量的值确定包含那个版本的头文件:

    #if SYSTEM == SYSV
        #define HRD "sysv.h"
    #elif SYSTEM == BSD
        #define HDR "bsd.h"
    #elif SYSTEM == MSDOS
        #define HDR "msdos.h"
    #else
        #define HDR "default.h"
    #endif
    #include HDR

C语言专门定义了两个预处理语句#ifdef与#ifndef,它们用来测试某个名字是否已经定义。上面有关#if的第一个例子可以改写为下列形式:
    #ifndef HDR
    #define HDR

    /* hdr.h文件的内容放在这里 */

    #endif

5.1 指针与地址
指针是一种保存变量地址的变量。在C语言中,指针的使用非常广泛,原因之一是,指针常常是表达某个计算的唯一途径,另一个原因是,同其他方法比较起来,使用指针通常可以生成更高效、更紧凑的代码。

通常的机器都有一系列连续编号或编址的存储单元,这些存储单元可以单个进行操纵,也可以以连续成组的方式操纵。通常情况下,机器的一个字节可以存放一个char类型的数据,两个相邻的字节存储单元可以存储一个short(短整型)类型的数据,而4个相邻的字节存储单元可存储一个long(长整型)类型的数据。指针是能够存放一个地址的一组存储单元(通常是两个或4个字节)。

一元运算符&可用于取一个对象的地址,因此下列语句:

    p = &c;

将把c的地址赋值给变量p,我们称p为“指向”c的指针。地址运算符&只能应用于内存中的对象,即变量于数组元素。它不能作用于表达式、常量或register类型的变量。

一元运算符*是间接寻址或间接引用运算符。当它作用于指针时,将访问指针多指向的对象。我们在这里假定x于y是整数,而ip是执行int类型的指针。下面的代码段说明了如何在程序中声明指针以及如何使用运算符&和*:

    int x = 1, y = 2, z[10];
    int *ip; /* ip是指向int类型的指针  */

    ip = &x;    /* ip现在指向x */
    y = *ip;   /* y的值现在为1 */
    *ip = 0;  /* x的值现在为0 */
    ip = &z[0];  /* ip现在指向z[0] */

指针的声明如下:

    int *ip;

这样声明是为了便于记忆。该声明语句    表明表达式*ip的结果是int类型。这种声明变量的语法与声明该变量所在表达式的语法类似。指针只能指向某种特定类型的对象,也就是说,每个指针都必须指向某种特定的数据类型。
如果指针ip指向整型变量x,那么在x可以出现的任何上下文中都可以使用*ip,因此,语句

    *ip = *ip + 10;

将把*ip的值增加10。
一元运算符*和&的优先级比算术运算符的优先级高,因此,复制语句

    y = *ip + 1

将把*ip指向的对象的值取出并加1,然后再将结果赋值给y,而下列赋值语句    :

    *ip += 1

则将ip指向的对象的值增加1,它等同于

    ++*ip


    (*ip)++

语句的执行结果。语句(*ip)++中的圆括号是必需的,否则,该表达式将对ip进行加1运算而不是对ip指向的对象进行加1运算,者是因为,类似于*和++这样的一元运算符遵循从右至左的结合顺序。
由于指针也是变量,所以再程序中可以直接使用,而不必通过间接引用的方法使用。例如,如果iq是另一个指向整型的指针,那么语句

    iq = ip

将把ip中的值拷贝到iq中,这样,指针iq也将指向ip指向的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值