指针也可以指向一个结构体,定义的形式一般为:

struct 结构体名 *变量名;

下面是一个定义结构体指针的实例:

  1. struct stu{
  2. char *name; //姓名
  3. int num; //学号
  4. int age; //年龄
  5. char group; //所在小组
  6. float score; //成绩
  7. } stu1 = { "Tom", 12, 18, 'A', 136.5 };
  8. //结构体指针
  9. struct stu *pstu = &stu1;

也可以在定义结构体的同时定义结构体指针:

  1. struct stu{
  2. char *name; //姓名
  3. int num; //学号
  4. int age; //年龄
  5. char group; //所在小组
  6. float score; //成绩
  7. } 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语言中的唯一用途。

上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。

【示例】结构体指针的使用。

  1. #include <stdio.h>
  2. int main(){
  3. struct{
  4. char *name; //姓名
  5. int num; //学号
  6. int age; //年龄
  7. char group; //所在小组
  8. float score; //成绩
  9. } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
  10. //读取结构体成员的值
  11. printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
  12. printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
  13. return 0;
  14. }

运行结果:
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

【示例】结构体数组指针的使用。

  1. #include <stdio.h>
  2. struct stu{
  3. char *name; //姓名
  4. int num; //学号
  5. int age; //年龄
  6. char group; //所在小组
  7. float score; //成绩
  8. }stus[] = {
  9. {"Zhou ping", 5, 18, 'C', 145.0},
  10. {"Zhang ping", 4, 19, 'A', 130.5},
  11. {"Liu fang", 1, 18, 'A', 148.5},
  12. {"Cheng ling", 2, 17, 'F', 139.0},
  13. {"Wang ming", 3, 17, 'B', 144.5}
  14. }, *ps;
  15. int main(){
  16. //求数组长度
  17. int len = sizeof(stus) / sizeof(struct stu);
  18. printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
  19. for(ps=stus; ps<stus+len; ps++){
  20. printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
  21. }
  22. return 0;
  23. }

运行结果:

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 分以下的人数。

  1. #include <stdio.h>
  2. struct stu{
  3. char *name; //姓名
  4. int num; //学号
  5. int age; //年龄
  6. char group; //所在小组
  7. float score; //成绩
  8. }stus[] = {
  9. {"Li ping", 5, 18, 'C', 145.0},
  10. {"Zhang ping", 4, 19, 'A', 130.5},
  11. {"He fang", 1, 18, 'A', 148.5},
  12. {"Cheng ling", 2, 17, 'F', 139.0},
  13. {"Wang ming", 3, 17, 'B', 144.5}
  14. };
  15. void average(struct stu *ps, int len);
  16. int main(){
  17. int len = sizeof(stus) / sizeof(struct stu);
  18. average(stus, len);
  19. return 0;
  20. }
  21. void average(struct stu *ps, int len){
  22. int i, num_140 = 0;
  23. float average, sum = 0;
  24. for(i=0; i<len; i++){
  25. sum += (ps + i) -> score;
  26. if((ps + i)->score < 140) num_140++;
  27. }
  28. printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
  29. }

运行结果:
sum=707.50
average=141.50
num_140=2

C语言结构体和指针的更多相关文章

  1. 关于C语言结构体,指针,声明的详细讲解。——Arvin

    关于结构体的详细分析 只定义结构体 struct Student { int age; char* name; char sex;//结构体成员 };//(不要忘记分号) Student是结构体的名字 ...

  2. c语言结构体&常指针和常量指针的区别

    结构体: 关系密切但数据类型不尽相同, 常指针和常量指针的区别: char * const cp : 定义一个指向字符的指针常数,即const指针,常指针. const char* p : 定义一个指 ...

  3. (八)C语言结构体和指针

    指针也可以指向一个结构体变量.定义的一般形式为: struct 结构体名 *变量名; 前面已经定义了一个结构体 stu: struct stu { char *name; int num; char ...

  4. c语言结构体指针初始化

    今天来讨论一下C中的内存管理. 记得上周在饭桌上和同事讨论C语言的崛起时,讲到了内存管理方面 我说所有指针使用前都必须初始化,结构体中的成员指针也是一样 有人反驳说,不是吧,以前做二叉树算法时,他的左 ...

  5. c语言中较常见的由内存分配引起的错误_内存越界_内存未初始化_内存太小_结构体隐含指针

    1.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.1结构体成员指针未初始化 struct stude ...

  6. C语言结构体指针初始化(转)

    reference: https://www.cnblogs.com/losesea/archive/2012/11/15/2772526.html 今天来讨论一下C中的内存管理. 记得上周在饭桌上和 ...

  7. 将c语言的结构体定义变成对应的golang语言的结构体定义,并将golang语言结构体变量的指针传递给c语言,cast C struct to Go struct

    https://groups.google.com/forum/#!topic/golang-nuts/JkvR4dQy9t4 https://golang.org/misc/cgo/gmp/gmp. ...

  8. 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

    原文链接:C语言结构体里的成员数组和指针 复制例如以下: 单看这文章的标题,你可能会认为好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Lar ...

  9. C语言结构体指针(指向结构体的指针)详解

    C语言结构体指针详解 一.前言 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组. *a).b 等价于 a->b. "."一 ...

随机推荐

  1. Selenium常用操作汇总二——如何把一个元素拖放到另一个元素里面(转)

    Q群里有时候会有人问,selenium  webdriver怎么实现把一个元素拖放到另一个元素里面.这一节总一下元素的拖放. 下面这个页面是一个演示拖放元素的页面,你可以把左右页面中的条目拖放到右边的 ...

  2. 高通 双MIC 设置

    android O中设置双MIC降噪,需要在build.prop添加属性"ro.vendor.audio.sdk.fluencetype"属性. 属性值位于hardware/qco ...

  3. Json转换工具类(基于google的Gson和阿里的fastjson)

    在项目之中我们经常会涉及到字符串和各种对象的转换,为此特地整理了一下常用的转换方法 一.基于com.google.code.gson封装的json转换工具类 1. 在pom.xml文件里面引入gson ...

  4. ZooKeeper系列

    Zookeeper系列(一) ZooKeeper系列(二) ZooKeeper系列(三) ZooKeeper系列(四)

  5. B/S模式实现批量打包apk

    界面流程 界面例如以下: 这是一个使用html编写的界面,界面分为两半.两个frame.左边为操作栏,右边为控制台输出. 打包流程: 选择须要打包的渠道后,点击打包,等待server打包,并把日志输出 ...

  6. iOS :UIPickerView reloadAllComponets not work

    编辑信息页面用了很多选择栏,大部分都用 UIPickerView 来实现.在切换数据显示的时候, UIPickerView 不更新数据,不得其解.Google 无解,原因在于无法描述自己的问题,想想应 ...

  7. 两台linux服务器之间实现挂载

    https://blog.csdn.net/lpp_dd/article/details/78743862 两台linux服务器之间实现挂载: 服务端: 1.首先需要在主机上设置允许挂载的目录 (1) ...

  8. tablediff工具实用

    1. tablediff 是什么? tablediff 实用工具用于比较两个非收敛的表中的数据,它对于排除复制拓扑中的非收敛故障非常有用. 2. tablediff 用哪些用法? 1) . 在充当复制 ...

  9. linux echo命令

    该篇文章转载于:http://www.cnblogs.com/ZhangShuo/articles/1829589.html linux的echo命令, 在shell编程中极为常用, 在终端下打印变量 ...

  10. nodejs包管理工具npm

    用Node.js安装模块 在某个项目中单独安装的时候,npm会下载所有的文件到你项目中的一个叫做node_modules的文件夹内 全局模块会被安装到{prefix}/lib/node_modules ...