文档章节

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

idreamo
 idreamo
发布于 2017/03/16 06:32
字数 1039
阅读 10
收藏 1

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

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

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

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

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

程序清单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

 

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
C语言-第八章、构造数据类型

8_1 结构体的概念和结构体变量 _1.1 结构体的概念 C语言中允许用户自己构造由不同数据类型的数据所组成的集合体,称为结构体。结构体属于数据类型,每一个结构体有一个名字,称为结构体名。一...

南风末
2016/11/05
7
0
C语言基础-13-结构体

C语言的核心部分都说得七七八八了,相信大家已经对C语言的基本数据类型(charintfloat)、数组、指针都很熟悉了,今天来学习C语言中另外一种数据类型:结构体。在iOS开发中,结构体是经常用到的...

Corwien
2016/03/16
10
0
《深入理解LINUX网络内幕》读书笔记1

一个在线看Linux源码的网站http://lxr.free-electrons.com,需要翻墙 第二章 关键数据结构 本章讲述以下两个重要数据结构: struct sk_buff:存储所有网络分层的包头、有效载荷,其他内部信息...

andy_han
2014/07/08
0
0
二十一、结构体

说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略 C语言的核心部分都...

长平狐
2013/03/28
276
0
二十三、typedef

说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略 这讲介绍C语言中很...

长平狐
2013/03/28
141
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux输入法fcitx的安装问题

Fcitx 总共要安装的包如下 fcitxfcitx-binfcitx-config-commonfcitx-config-gtk | fcitx-config-gtk2fcitx-datafcitx-frontend-allfcitx-frontend-gtk2fcitx-frontend-gtk3......

CHONGCHEN
今天
4
0
网络基础

前言: 最近整理一些以前的学习笔记(有部分缺失,会有些乱,日后再补)。 过去都是存储在本地,此次传到网络留待备用。 计算机网络的功能: 1.数据通信; 2.资源共享; 3.增加数据可靠性; 4....

迷失De挣扎
今天
7
0
spring boot升级到spring cloud

1、先升级spring boot 版本到2.1.3 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEAS......

moon888
今天
12
0
从蓝鲸视角谈DevOps

DevOps源于Development和Operations的组合 常见的定义 DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变...

嘉为科技
今天
1
0
微服务设计 笔记

微服务设计 一、微服务架构理论 1.六边形架构 1)六边形架构(Hexagonal Architecture),又称为端口和适配器架构风格;使用适配器与外界进行交互,外界通过应用层API与内部进行交互。 2)经典...

啃不动地大坚果
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部