指向结构指针(C Primer Plus 第六版)

简介: 指向结构指针(C Primer Plus 第六版)

前言


这节会学到->运算符和struct结构 学完这些,再去学数据结构就很简单了! 加油!

资源在这

image.png


一、指向结构的指针


喜欢使用指针的人一定很高兴能使用指向结构的指针。至少有4个理由可以解释为何要使用指向结构的指针。第一,就像指向数组的指针比数组本身更容易操控(如,排序问题)一样,指向结构的指针通常比结构本身更容易操控。第二,在一些早期的C实现中,结构不能作为参数传递给函数,但是可以传递指向结构的指针。第三,即使能传递一个结构,传递指针通常更有效率。第四,一些用于表示数据的结构中包含指向其他结构的指针。

good,指针真不错!


实例


#include <stdio.h>
#define LEN 20
struct names                    //定义结构体names
{
    char first[LEN];
    char last[LEN];
};
struct guy                      //定义结构体guy
{
    struct names handle;
    char favfood[LEN];
    char job[LEN];
    float income; 
};
int main(void)
{
    struct guy fellow[2] = {    
        //这是一个结构嵌套,guy结构里嵌套了names结构
        //初始化结构数组fellow,每个元素都是一个结构变量
        {{"Ewen","Villard"},
        "girlled salmon",
        "personality coach",
        68112.00
        },
        {{"Rodney","Swillbelly"},
        "tripe",
        "tabloid editor",
        432400.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);//68112.00
    //指向下一个结构,him加1相当于him指向的地址加84。names结构占40个字节,favfood占20字节,handle占20字节,float占4个字节,所以地址会加84
    him++;     
    printf("him->favfood is %s: him->handle.last is %s\n",him->favfood,him->handle.last);
    //因为有了上面的him++,所以指向的是favfood1[1],
    return 0;
}
输出结果为
PS D:\Code\C\结构> cd "d:\Code\C\结构\" ; if ($?) { gcc structDemo02.c -o structDemo02 } ; if ($?) { .\structDemo02 }
address #1:000000000061FD70 #2:000000000061FDC4
pointer #1:000000000061FD70 #2:000000000061FDC4
him->income is $68112.00:(*him).income is $68112.00
him->favfood is tripe: him->handle.last is Swillbelly

这个例题看懂了,自我感觉指针学的算是有个基本了解了!给自己点赞哦!


1.1 声明和初始化结构指针


声明结构指针很简单

struct guy * him;

声明结构指针很简单:struct guy * him; 首先是关键字 struct,其次是结构标记 guy,然后是一个星号(*),其后跟着指针名。这个语法和其他指针声明一样。 该声明并未创建一个新的结构,但是指针him现在可以指向任意现有的guy类型的结构。例如,如果barney是一个guy类型的结构,可以这样写: him = &barney; 和数组不同的是,结构名并不是结构的地址,因此要在结构名前面加上&运算符。 在本例中,fellow是一个结构数组,这意味着fellow[0]是一个结构。所以,要让 him指向fellow [ 0],可以这样写:

him = &fellow[0];

输出的前两行说明赋值成功。比较这两行发现,him指向fellow[0],him + 1指向fellow[1]。注意,him加1相当于him指向的地址加84。在十六进制中,874 - 820 = 54(十六进制)= 84 (十进制),因为每个guy结构都占用84字节的内存: names.first占用20字节,names.last占用20字节,favfood占用20字节,job占用20字节,income占用4字节(假设系统中float占用4字节).顺带一提,在有些系统中,一个结构的大小可能大于它各成员大小之和。这是因为系统对数据进行校准的过程中产生了一些“缝隙”。例如,有些系统必须把每个成员都放在偶数地址上,或4的倍数的地址上。在这种系统中,结构的内部就存在未使用的“缝隙”。


1.2 用指针访问成员


指针him指向结构变量fellow[0],如何通过him获得fellow[0]的成员的值?第1种方法也是最常用的方法:使用->运算符。该运算符由一个连接号(-)后跟一个大于号(>)组成。我们有下面的关系:

如果him == &barney,那么him->income 即是barney.income如果him == &fellow [ 0],那么him->income 即是 fellow [ 0 ] .income

换句话说,->运算符后面的结构指针和.运算符后面的结构名工作方式相同(不能写成him.income,因为him不是结构名)。 这里要着重理解him是一个指针,但是 him->income是该指针所指向结构的一个成员。所以在该例中,him->income是一个float类型的变量。 第2种方法是,以这样的顺序指定结构成员的值:如果him == &fellow[0],那么him == fellow[0]因为**&和***是一对互逆运算符。因此,可以做以下替代:

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

必须要使用圆括号,因为.运算符比*运算符的优先级高。 总之,如果him是指向guy类型结构barney的指针,下面的关系恒成立: barney.income == (*him).income == him->income //假设him == &barney


相关文章
|
13天前
|
编译器 vr&ar C语言
C primer plus 学习笔记 第10章 数组和指针
C primer plus 学习笔记 第10章 数组和指针
|
1月前
|
C++
来自C++ Primer 5的函数指针的定义,调用等
来自C++ Primer 5的函数指针的定义,调用等
19 0
|
8月前
|
编译器 数据库 C语言
4.1 C/C++ 使用结构与指针
C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。
36 0
|
存储 C语言
《C和指针》读书笔记(第十章 结构和联合)(下)
《C和指针》读书笔记(第十章 结构和联合)(下)
|
存储 C语言 C++
《C和指针》读书笔记(第十章 结构和联合)(上)
《C和指针》读书笔记(第十章 结构和联合)(上)
每日一题—— 判断一个链表是否为回文结构(快慢指针,对撞指针)
每日一题—— 判断一个链表是否为回文结构(快慢指针,对撞指针)
|
存储 XML JSON
【C语言】结构体——我就是秩序的创建者!(结构体数组、结构体指针、嵌套、匿名、字面量、伸缩型数组、链式结构)
【C语言】结构体——我就是秩序的创建者!(结构体数组、结构体指针、嵌套、匿名、字面量、伸缩型数组、链式结构)
指针和多维数组的关系(C Primer Plus第六版)
指针和多维数组的关系(C Primer Plus第六版)
43 0
|
12天前
|
安全 程序员 编译器
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
【C语言基础】:深入理解指针(二)
|
2天前
|
存储 C语言
C语言的函数返回值和指针
C|函数返回值(区分各类值)和指针(区分各类存储空间)的细节