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. Google Guava vs Apache Commons for Argument Validation

    It is an established good practice to validate method arguments at the beginning of the method body. ...

  2. UVa 11998 Broken Keyboard (数组模拟链表问题)

    题目链接: 传送门 Broken Keyboard #include<bits/stdc++.h> using namespace std; char str[100010]; int m ...

  3. Character literal must contain exactly one character -- 一天一点小知识

    编程语言高度抽象化以后,错误也越来越让人难以理解了, NET编程最常见的一个错误, Object not set to the reference ,过了好久,才明白过来, 就是不明白为啥微软不说   ...

  4. shell 中 &&和||的方法

    Shell && 和 || shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中.当 $? == 0 时,表示执行成功:当 $? == 1 时 ...

  5. linux学习笔记-dump命令的使用

    http://blog.chinaunix.net/uid-29797586-id-4458302.html

  6. gnuplot使用2

    设置图中连线的颜色.宽度.连线样式等 set style line 每个显示终端都有默认的线类型和点类型集合,可以通过在命令行输入: test查看,如下图显示了在wxt终端模式下默认的线的集合和点的集 ...

  7. uC/OS-II中includes块

    /*************************************************************************************************** ...

  8. Centos7安装Oracle12c

    环境: CentOS7@VMware12,分配资源:CPU:2颗,内存:4GB,硬盘空间:30GB Oracle12C企业版64位 过程纪要: root身份安装依赖包: compat-libstdc+ ...

  9. MySQL------如何将SQLServer文件数据迁移到MySQL

    转载: http://blog.csdn.net/zhangdaiscott/article/details/46412453

  10. easyUI数据表格datagrid之笔记2

    /**========================================= * 追加在表格尾部 */function append(){ editIndex = $('#dg').dat ...