第14章 结构和其他数据形式 14.6 指向结构的指针

至少有三个原因可以解释为什么使用指向结构的指针是个好主意。

第一,就像指向数组的指针比数组本身更容易操作(例如在一个排序问题中)一样,指向结构的指针通常都比结构本身更容易操作。

第二,在一些早期的实现中,结构不能作为参数被传递给函数,但指向结构的指针可以。

第三,许多奇妙的数据表示都使用了包含指向其他结构的指针的结构。

下面的例子,示例了如何定义一个指向结构的指针,以及如何使用这个指针访问结构的成员;

程序清单14.4  friends.c程序

//friend.c  --嵌套结构的例子
#include <stdio.h>
#define LEN 20

struct names {
    char first[LEN];
    char last[LEN];
};
struct guy {
    struct names handle;
    char favfood[LEN];
    char job[LEN];
    float income;
};
int main(void)
{
    struct guy fellow[2]={
        {{"Ewen","Villard"},
        "grilled salmon",
        "personality coach",
        58112.00
        },
        {{"Rodney","Swillbelly"},
        "tripe",
        "tabloid editor",
        232400.00
        }
    };
    struct guy *him;  //这是一个指向结构的指针
    printf("address #1: %p #2: %p\n",&fellow[0],&fellow[1]);
    him=&fellow[0];  //告诉该指针它要指向的地址;
    printf("Pointer #1: %p #2: %p\n",him,him+1);
    printf("him->income is $%.2f:(*him).income is $%.2f\n",him->income,(*him).income);
    him++;  /*指向下一个指针 */
    printf("him->favfood is %s: him->handle.last is %s\n",him->favfood,him->handle.last);
    return 0;
}

14.6.1  声明和初始化结构指针

声明很简单:

struct guy *him;

这个语法和您见过的其他指针声明一样。

这个声明不是建立 一个新的结构,而是意味着指针him现在可以指向任何现有的guy类型的结构。例如,如果barney是一个guy类型的结构,可以这样做:

him=&barney;

 和数组不同,一个结构的名字不是该结构的地址,必须使用&运算符。

在本例中,fellow是一个结构数组,就是说fellow[0]是一个结构,所以下列代码令him指向fellow[0],从而初始化了him:

him=&fellow[0];

头两行输出表明成功地执行了这个赋值语句。比较这两行输出,可以看出him指向fellow[0],him+1指向fellow[1]。注意him+1,地址上就加了84。在十六进制 中,ef8-ea4=54(十六进制)=84(十进制)。这是因为每个guy结构占有84字节的内存区域:names.fiest占20字节,names.last占20字节,favfood占20字节,job占20字节,income占4字节(即float在系统中的大小)。顺便提一下,在一些系统中,结构的大小有可能大于它内部各成员大小的和,那是因为系统对数据的对齐存储需求会导致缝隙。例如,系统有可能必须 把每个偶数地址的成员放在是4的倍数的地址上,这样的结构就可能在其内部存在存储缝隙。

14.6.2  使用指针访问成员

指针him现在正指向结构fellow[0]。如何使用指针him来取得fello[0]的一个成员呢?第三行输出展示了两种方法。

第一种方法,也是最常用的方法,使用一个新的运算符:->。下面的例子可以清楚的表明这个意思 :

him->income is fellow[0].income if him==&fellow[0]

换句话说,后跟->运算符的结构指针和后跟(.)运算符的结构名是一样的(不能使用him.income,因为him不是一个结构名)。

务必要注意到him是个指针,而him->income是被指向的结构的一个成员。在这种情况下,him->income是一个float变量。

指定结构成员值的第二个方法从下面的序列中得出:如果him=&fellow[0],那么*him=fellow[0],因为&和*是一对互逆的运算符。因此,可做以下替代:

fellow[0].income==(*him).income

必须要使用圆括号,因为.运算符比*的优先级高。

总之,如果him是指向名为barney的guy类型结构的指针,则下列表达式是等价的:

barney.income=(*him).income=him->income  //假设him=&barney

 

转载于:https://my.oschina.net/idreamo/blog/860303

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值