C 语言中指针的操作非常灵活,它也能指向结构体变量对结构体变量进行操作。在学习结构指针之前,需要再次加深对指针的认识。声明指针变量时所使用的数据类型修饰符实际上的作用是定义指针访问内存的范围,如果指针定义为整型,那么该指针访问内存的范围就是整型变量在内存中所占用的空间大小。虽然每次尝试将指针变量所在存储的内存地址输出会发现,任何类型的内存地址长度都一样,但不同类型间不能相互复制,只有空值型除外。因此在使用指针操作结构体时,一定要确定指针所定义的数据类型与结构体的数据类型相同。

7.3.1 指向结构体类型变量的使用

定义结构体变量的一般形式是:

结构体名 *结构体变量名

结构体名作为指针变量的类型修饰符。引用结构体指针所指向的结构体变量成员需要使用“->”操作符,该操作中减号“-”和小于号“>”组合而成。如下例子所示:

typedef struct student stu_t;    // 将结构体 student 定义为数据类型

stu_t stu1 = {"Tom", "Math", 20090001, 87.5, 70.5, 93, 91}; // 定义结构体并初始化
stu_t *p; // 定义结构体指针
p = &stu1; // 将结构体变量地址赋给指针
p->no = 20090005; // 引用指针所指向结构体变量的成员

代码中使用了 typedef 命令,该命令用于定义新的数据类型修饰符。执行 typedef 命令后,stu_t 成为了 student 结构体类型修饰符,在代码中 stu_t 的作用等同于 struct student。指针 *p 被指向结构体变量 stu1,但指针 *p 并不是结构体变量,所以不能使用“.”符号引用结构体成员,只能使用“->”操作符。

在设计一些需要大量交换数据的程序时,需要动态为数据划分内存。当不再需要该数据时,可以从内存中释放,以节省程序运行时占用的内存空间。下例将演示为结构体指针动态分配内存的操作方法。

#include <stdio.h>
#include <stdlib.h> int main(void)
{
typedef struct student stu_t;
struct student
{
int no;
}; stu_t *p = (stu_t *)malloc(sizeof(stu_t));
p->no = 2009; printf("%d", p->no); free(p); return 0;
}

在为结构体动态分配内存空间时,使用 sizeof()函数计算结构体 stu_t 在内存中所需要的空间,然后使用 malloc() 函数将 sizeof() 函数返回的数量在内存中划分出来,malloc() 函数的返回值是该内存空间的首地址,所以用强制转换表达式“(stu_t *)”将 malloc() 返回的地址转换为stu_t 类型的指针。

7.3.2 指向结构体类型数组的指针的使用

结构体类型数组本质上是作为数组存在,数组的元素是结构体变量。结构体数组的名称即是指向该数组第一个数组元素的指针。结构体数组元素之间不能直接相互复制数据,下面将介绍通过指针直接访问内存空间复制结构体数组元素的方法。

#include <string.h>
#include <stdio.h> int main(void)
{
typedef struct student stu_t;
struct student
{
char name[60];
char dept[50];
long no;
float score[4];
}; stu_t stu_a[2] = {"TOM", "Math", 2009001, 87.5, 70.5, 93, 91}; // 初始化结构体数组第 1 个元素
stu_t *p = stu_a; // 为结构体指针划分内存空间
memcpy(p + 1, p, sizeof(stu_t)); // 将数组第 1 个元素复制给数组第 2 个元素
puts((p + 1)->name); // 用指针引用数组第 2 个元素的数组成员 return 0;
}

程序中定义了结构体数组 stu_a,在初始化时为其第 1 个元素赋值。定义指针 *p 时,用数组名stu_a 为指针 *p 赋值,指针 *p 指向了数组 stu_a 第 1 个元素。memcpy() 函数的作用是将内存中从指针 *p 指向的地址开始长度为 sizeof(stu_t)的数据,复制到内存中指针 *p + 1 指向的地址开始长度为 sizeof(stu_t) 的空间里。由此可见,对指针 *p + 1 进行的操作,并非简单的将内存地址作为整型数据进行加 1 运算,1 代表的是 sizeof(stu_t) 的长度的内存区间所跨越地址的差值。

【C语言入门教程】7.3 结构体指针的定义和引用的更多相关文章

  1. 【C语言入门教程】7.1 结构体类型变量的定义和引用

    前面学习了变量和数组这些简单的数据结构,它们的特点是必须使用规定的数据类型.例如数组被定义为整型后,它的所有存储单元都是由整型构成.现实生活中某一类事物的共同属性可能是由不同的数据类型组成的集合,或者 ...

  2. 【C语言入门教程】7.2 结构体数组的定义和引用

    7.2 结构体数组的定义和引用 当需要使用大量的结构体变量时,可使用结构体定义数组,该数组包含与结构体相同的数据结构所组成的连续存储空间.如下例所示: struct student stu_a[50] ...

  3. 智能合约语言 Solidity 教程系列6 - 结构体与映射

    写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本系列文章一部分是参考Solidity官方文档(当前最新版 ...

  4. C#结构体指针的定义及使用详解(intptr的用法)

    在解析C#结构体指针前,必须知道C#结构体是如何定义的.在c#中同样定义该结构体. C#结构体指针之C#结构体的定义: [StructLayout(LayoutKind.Sequential)] pu ...

  5. C语言入门(15)——结构体与数据抽象

    大多数的计算机运算是对现实世界的模拟,如果想用计算机来模拟现实世界需要用到数据抽象的方法.所谓抽象是从实际的人.物.事和概念中抽取所关心的共同特征,,忽略非本质的细节,吧这些特征用各种概念精确的加以描 ...

  6. C语言入门(14)——结构体

    整数.字符.布尔值.浮点数这些数据类型都具有单一的值,这些可称为基本数据类型.但字符串是一个例外,它由很多字符组成,像这种由基本类型组成的数据类型称为复合数据类型,正如表达式和语句有组合规则一样,由基 ...

  7. 【C语言入门教程】4.9 指向指针的指针

    指针变量可以指向另一个指针变量,这种操作并不是将一个指针变量所指向的内存地址传递给另一个指针变量,而是定义一种指向指针类型的指针变量,可将其称为双重指针.双重指针的定义形式为: 数据类型 **变量名: ...

  8. C++ 结构体指针的定义

    struct node { …… } ; struct node *p1, *p2 ; typedef struct node { …… }Node; typedef Node* pNode; typ ...

  9. 【C语言入门教程】目录/大纲

    第一章 C语言编程基础 1.1 基本程序结构 1.2 函数库 和 链接 1.3 C语言“32个”关键字 第二章 数据类型.运算符和表达式 2.1 数据类型(5种基本数据类型),聚合类型与修饰符 2.2 ...

随机推荐

  1. Linux下安装py-leveldb

    1.下载源代码 svn checkout http://py-leveldb.googlecode.com/svn/trunk/ py-leveldb-read-only 2.安装辅助工具 sudo ...

  2. gnuplot配置HOME目录

    http://blog.csdn.net/jspenliany/article/details/39828261 本人使用gnuplot绘图,使用console version的来进行处理的时候,经常 ...

  3. su su- sudo的区别

    linux su命令参数及用法详解(linux切换用户命令) su的作用是变更为其它使用者的身份,超级用户除外,需要键入该使用者的密码   linux su 命令 建议大家切换用户的时候 使用 su ...

  4. SSH(Struts Spring Hibernate开发框架)

    Spring(Model) Spring的核心思想是IoC和AOP,Spring使得管理对象更加方便,极大的降低组件之间的耦合度,实现了软件各层之间的解耦. Struts(View) 使用Struts ...

  5. java8 中的时间和数据的变化

    java8除了lambda表达式之外还对时间和数组这两块常用API做想应调整, Stream 有几个常用函数: store 排序 (a,b)-> a.compareTo(b)  排出来的结果是正 ...

  6. 日志分析 第一章 ELK介绍

    1 ELK各组件介绍? ELK Stack是elasticsearch.logstash.kibana是三个开源软件的组合, fielbeat是一个轻量级日志收集工具,类似于Linux系统中tail ...

  7. win7下如何建立ftp服务器

    前段时间正在做一个项目,需要上传东西到ftp服务器,纠结于如何建立ftp服务器.经过一番摸索.终于成功建立ftp服务器.现将我的经验跟大家分享一下.不足之处还望多多指点! 步骤/方法 首先在本地机器上 ...

  8. JAVA 5.17习题

    1.编写并测试一个代表地址的Address类,地址信息由国家.省份.城市.街道.邮编组成,并可以返回完整的地址信息. //======================================= ...

  9. ecshop变量介绍

    获得商品的信息,get_goods_info($goods_id) 获取前10销量排名,get_top10()

  10. JNDI全面总结

    JNDI全面总结原理: 在DataSource中事先建立多个数据库连接,保存在数据库连接池中.当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池 ...