博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第14章 结构和其他数据形式 14.6 指向结构的指针
阅读量:6273 次
发布时间:2019-06-22

本文共 2276 字,大约阅读时间需要 7 分钟。

hot3.png

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

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

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

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

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

程序清单14.4  friends.c程序

//friend.c  --嵌套结构的例子#include 
#define LEN 20struct 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

你可能感兴趣的文章
Ruby on Rails入门——macOS 下搭建Ruby Rails Web开发环境
查看>>
Kafka 设计与原理详解
查看>>
[外挂7] 井字棋外挂 博弈算法
查看>>
国家代码查询
查看>>
弯道超车,换一个思路,避免addEventListener为同一个元素重复赋予事件
查看>>
布隆过滤器
查看>>
C#中使用Redis不同数据结构的内存占有量的疑问和对比测试
查看>>
配置druid内置的log实现
查看>>
[LeetCode] Meeting Rooms II 会议室之二
查看>>
泛型与非泛型的区别
查看>>
ASP.NET MVC:WebPageBase.cs
查看>>
Xen虚拟机的创建和启动
查看>>
Design Pattern: Factory Method 模式
查看>>
改善C#程序的建议7:正确停止线程
查看>>
数据库SQL优化大总结之 百万级数据库优化方案(转)
查看>>
瘦了!光荣!都是忙工作忙的!
查看>>
使用嵌入式关系型SQLite数据库存储数据
查看>>
初步学习pg_control文件之十五
查看>>
使用Notepad++开发C#,一个复杂点的csscript脚本
查看>>
jQuery的Internal DSL
查看>>