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. java server

    A easy ajax for java: http://directwebremoting.org/dwr/index.html

  2. Xcode中插件在Xcode更新之后解决方法

    >新的解决方法地址:这里 但凡是更新了Xcode的版本,之前安装的Xcode的插件都不会使用,例如:XAlign或者猫神的VVDocument-Xcode插件 解决方法有很多而且很多地方都贴出来 ...

  3. POJMatrix(二维树状数组)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 22058   Accepted: 8219 Descripti ...

  4. CSS3-canvas绘制线性渐变

    <!doctype html><html><head><meta charset="utf-8"><title>canv ...

  5. easyUI的控件

    CSS类定义: div easyui-window                               window窗口样式 属性如下: 1)       modal:是否生成模态窗口.tru ...

  6. SQL Server编程(02)自定义函数

    在编程过程中,我们通常把特定的功能语句块封装称函数,方便代码的重用.我们可以在SQL Server中自定义函数,根据函数返回值的区别,我们自定义的函数分两种:标量值函数和表值函数. 自定义函数的优点: ...

  7. 使用js进行string和json之间转换的方法

    在数据传输过种中,json是以文本,即字符串的形式传递,字符串形似Json对象: var str1 = '{ "name": "Amy", "sex& ...

  8. git命令拾遗

    要随时掌握工作区的状态,使用git status命令. 如果git status告诉你有文件被修改过,用git diff可以查看修改内容. HEAD指向的版本就是当前版本,因此,Git允许我们在版本的 ...

  9. ----------jqery和js如何判断checkbox是否选中 --------两个单选按钮如何选一个,且用jquery获取被选的值

    jqery和js如何判断checkbox是否选中 jquery: <div id="divId" class="divTable"> <div ...

  10. Linux 下 Oracle 内核参数优化

    数据库的性能优化涉及到整个数据库运行环境的方方面面,诸如操作系统,Oracle自身,存储,网络等等几个大块.而操作系统则是Oracle稳定运行与最大化性能的基石.本文主要描述基于Linux系统下 Or ...