C语言结构体指针(指向结构体的指针)详解
当一个指针变量指向结构体时,我们就称它为结构体指针。C语言结构体指针的定义形式一般为:
struct 结构体名 *变量名;
下面是一个定义结构体指针的实例:
- //结构体
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 };
- //结构体指针
- struct stu *pstu = &stu1;
也可以在定义结构体的同时定义结构体指针:
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&
,所以给 pstu 赋值只能写作:
struct stu *pstu = &stu1;
而不能写作:
struct stu *pstu = stu1;
还应该注意,结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量:
struct stu *pstu = &stu;
struct stu *pstu = stu;
获取结构体成员
通过结构体指针可以获取结构体成员,一般形式为:
(*pointer).memberName
或者:
pointer->memberName
第一种写法中,.
的优先级高于*
,(*pointer)
两边的括号不能少。如果去掉括号写作*pointer.memberName
,那么就等效于*(pointer.memberName)
,这样意义就完全不对了。
第二种写法中,->
是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员;这也是->
在C语言中的唯一用途。
上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。
【示例】结构体指针的使用。
- #include <stdio.h>
- int main(){
- struct{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
- //读取结构体成员的值
- printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
- printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
- return 0;
- }
运行结果:
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
【示例】结构体数组指针的使用。
- #include <stdio.h>
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }stus[] = {
- {"Zhou ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"Liu fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- }, *ps;
- int main(){
- //求数组长度
- int len = sizeof(stus) / sizeof(struct stu);
- printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
- for(ps=stus; ps<stus+len; ps++){
- printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
- }
- return 0;
- }
运行结果:
Name Num Age Group Score Zhou ping 5 18 C 145.0 Zhang ping 4 19 A 130.5 Liu fang 1 18 A 148.5 Cheng ling 2 17 F 139.0 Wang ming 3 17 B 144.5
结构体指针作为函数参数
结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。
【示例】计算全班学生的总成绩、平均成绩和以及 140 分以下的人数。
- #include <stdio.h>
- struct stu{
- char *name; //姓名
- int num; //学号
- int age; //年龄
- char group; //所在小组
- float score; //成绩
- }stus[] = {
- {"Li ping", 5, 18, 'C', 145.0},
- {"Zhang ping", 4, 19, 'A', 130.5},
- {"He fang", 1, 18, 'A', 148.5},
- {"Cheng ling", 2, 17, 'F', 139.0},
- {"Wang ming", 3, 17, 'B', 144.5}
- };
- void average(struct stu *ps, int len);
- int main(){
- int len = sizeof(stus) / sizeof(struct stu);
- average(stus, len);
- return 0;
- }
- void average(struct stu *ps, int len){
- int i, num_140 = 0;
- float average, sum = 0;
- for(i=0; i<len; i++){
- sum += (ps + i) -> score;
- if((ps + i)->score < 140) num_140++;
- }
- printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
- }
运行结果:
sum=707.50
average=141.50
num_140=2
C语言结构体指针(指向结构体的指针)详解相关推荐
- 数组指针——指向数组对象的指针
转载自:数组指针 数组指针--指向数组对象的指针 数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element).数组中的所有元素在内存中是连续排列的,整个数组占用的 ...
- 电大计算机C语言1253,1253《C语言程序设计》电大期末精彩试题及其问题详解
1253<C语言程序设计>电大期末精彩试题及其问题详解 (34页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实用文档&l ...
- C++中数组和指针的关系(区别)详解
C++中数组和指针的关系(区别)详解 本文转自:http://c.biancheng.net/view/1472.html 博主在阅读后将文中几个知识点提出来放在前面: 没有方括号和下标的数组名称实际 ...
- 对C语言 结构数组 指向结构变量的指针 指向结构数组的指针
一.结构数组的定义 数组的元素可以是结构类型的.结构数组的每一个元素都是具有相同的结构类型的下标结构变量.在实际应用中,经常用结构数组来表示具有相同数据结构的一个群体. 如:一个班的学生的档案,一个车 ...
- 【C 语言】字符串 一级指针 内存模型 ( 指定大小字符数组 | 未指定大小字符数组 | 指向常量字符串的指针 | 指向堆内存的指针 )
文章目录 一.字符串 一级指针 内存模型 1.指定大小字符数组 2.未指定大小字符数组 3.指向常量字符串的指针 4.指向堆内存的指针 一.字符串 一级指针 内存模型 #include <std ...
- 单链表-逆置单链表(修改指针指向且三个指针)
题意: 采用带头结点的单链表,设计一个算法将其就地逆置,所谓"就地"是指辅助空间O(1). 这里可以有两种方法做: 1.头插法且双指针 2.改变指针指向且三指针 两方法共同点: 头 ...
- C++基类指针指向派生类(指针)
我们常用基类指针指向派生类对象来实现多态性. 私有继承不允许基类指针指向派生类 基类指针只能访问到基类中含有的公有成员. 当用基类指针指向派生类对象在动态分配堆上内存的时候,析构函数必须是虚函数! 成 ...
- 父类指针指向子类对象,子类指针不能指向父类对象
class Parent { public:int a };class Child :public Parent { public:int b; }Parent类占内存大小范围:int a; 占4个字 ...
- 结构光之格雷码编码加相移算法详解与实现(多种编码程序)
格雷码+相移法既可以减少格雷码的编码位数,加快解码速度,也可以弥补单纯的相移法和格雷码法的对不连续位置难以重建的缺点. 操作过程如下: 采用格雷码与相移结合的时间编码方法,具体的编码方法为:首先向被测 ...
- 结构专业规范大全_钢结构大全图文详解,手把手教你钢结构识图,反正我收藏了!...
钢结构大全图文详解,手把手教你钢结构识图,反正我收藏了! 钢结构是由钢制材料组成的结构,是主要的建筑结构类型之一.结构主要由型钢和钢板等制成的梁钢.钢柱.钢桁架等构件组成,并采用硅烷化.纯锰磷化.水洗 ...
最新文章
- 深度强化学习研究笔记
- 数据结构Java07【二叉排序树(添加查找删除-节点)】
- 3D姿态估计——ThreeDPose项目简单易用的模型解析
- 对 makefile 中 override 优先级的学习体会
- 【SRH】------node创建简单的服务器
- 锐起无盘服务器内存盘,关于锐起无盘的缓存原理以及使用方法
- centos8解压war包
- layui整合Echart
- matlab simulink节点,ROS与Matlab语言入门教程-从Simulink中创建单独的ROS节点
- Java8 Collectors.joining() 详解
- 我家厨房--冬阴功汤和青椒炒腊肠
- 树的基本概念(定义、基本术语、性质)
- Burp Suite使用介绍(二)
- 2008年奥巴马胜选演讲
- 建站公司服务器管理系统,使用宝塔服务器管理软件为Windows系统服务器快速搭建建站环境...
- 致焦虑于找实习的“你”
- html制作热力图制作,首页热力图.html
- https根据key/crt文件生成中间件证书pem
- npm 安装less插件_LESS - 插件
- GEO2R:对GEO数据库中的数据进行差异分析