Linux C 深入分析结构体指针的定义与引用
关于结构体的基础知识,网上书上都一大堆,这里就不赘述了,下面我们要学习的是结构体指针。
介绍结构体指针之前,先给大家看一个小程序:
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- struct Man
- {
- char name[10];
- };
- int main()
- {
- struct Man N;
- N.name = "qiang";
- printf("%s\n",N.name);
- }
这段程序很简单,就是给结构体成员赋值,这里结构体成员是个数组,大家看看这种赋值方式有没有错,我们编译一下:
- fs@ubuntu:~/qiang/struct$ gcc -o struct4 struct4.c
- struct4.c: In function ‘main’:
- struct4.c:13:9: error: incompatible types when assigning to type ‘char[10]’ from type ‘char *’
- fs@ubuntu:~/qiang/struct$
13行报错,就是赋值那行,报错原因是“字符分配的类型是不兼容的类型”
我们看看这句N.name = "qiang",右边是字符串常量,这里其实是字符串的首地址,就是一个地址,我们以前 char a[] = "qiang"没错啊,为什么这里报错了,我们看看左值,N.name, name 是数组名,是代表数组的首地址啊,但是我们要记住,这里name是个地址常量,是不能给常量赋值的,所以会报错,那我们如何给一个结构体中的字符数组赋值呢?我们这里用strcpy(N.name,"qiang") ! 当然我们N.name[1] = 'q',这样是可以的。
下面开始讲结构体指针:
一、指向结构体类型变量的使用
首先让我们定义结构体:
- <span style="color:#000000;">struct stu
- {
- char name[20];
- long number;
- float score[4];
- };
- </span>
再定义指向结构体类型变量的指针变量:
struct stu *p1, *p2 ;
定义指针变量p1、p2,分别指向结构体类型变量。引用形式为:指针变量→成员;这里我们要注意,非结构体指针引用类型是 结构体类型变量 . 成员;
下面我们看一个例子:
对指向结构体类型变量的正确使用。
输入一个结构体类型变量的成员,并输出:
- #include <stdlib.h>
- #include <stdio.h>
- struct data
- {
- int day,month,year;
- };
- struct stu
- {
- char name[20];
- long num;
- struct data birthday; /*嵌套的结构体类型成员*/
- };
- int main()
- {
- struct stu *student; /*定义结构体类型指针*/
- student = malloc(sizeof(struct stu)); /*为指针变量分配安全的地址*/
- printf("Input name,number,year,month,day:\n");
- scanf("%s",student->name); /*输入学生姓名、学号、出生年月日*/
- scanf("%ld",&student->num);
- scanf("%d%d%d",&student->birthday.year,&student->birthday.month,
- &student->birthday.day);
- printf("\nOutputname,number,year,month,day\n");
- /*打印输出各成员项的值*/
- printf("%8s %5ld %d//%d//%d\n",student->name,student->num,
- student->birthday.year,student->birthday.month,
- student->birthday.day);
- }
执行结果如下:
- fs@ubuntu:~/qiang/struct/tmp$ ./struct1
- Input name,number,year,month,day:
- xiao
- 10086
- 2012
- 12
- 22
- Outputname,number,year,month,day
- xiao 10086 2012//12//22
- fs@ubuntu:~/qiang/struct/tmp$
程序中使用结构体类型指针引用结构体变量的成员,需要通过C提供的函数malloc()来为指针分配安全的地址。函数sizeof()返回值是计算给定数据类型所占内存的字节数。指针所指各成员形式为:
- student->name
- student->num
- student->birthday.year
- student->birthday.month
- student->birthday.day
二、指向结构体类型数组的指针的使用
定义一个结构体类型数组,其数组名是数组的首地址,这一点前面的课程介绍得很清楚。
定义结构体类型的指针,既可以指向数组的元素,也可以指向数组,在使用时要加以区分。
上个例子中定义了结构体类型,根据此类型再定义结构体数组及指向结构体类型的指针
- struct data
- {
- intday,month,year;
- };
- struct stu/*定义结构体*/
- {
- char name[20];
- long num;
- struct data birthday;/*嵌套的结构体类型成员*/
- };
- struct stustudent[4],*p; /*定义结构体数组及指向结构体类型的指针*/
使p=student,此时指针p就指向了结构体数组student。
p是指向一维结构体数组的指针,对数组元素的引用可采用三种方法。
1)地址法
student+i和p+i均表示数组第i个元素的地址,数组元素各成员的引用形式为:
(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i与&student[i]意义相同。
2)指针法
若p指向数组的某一个元素,则p++就指向其后续元素。
3)指针的数组表示法
若p=student,我们说指针p指向数组student,p[i]表示数组的第i个元素,其效果与student[i]等同。对数组成员的引用描述为:p[i].name、p[i].num等
指向结构体数组的指针变量的使用:
- #include <stdio.h>
- #include <malloc.h>
- struct data/*定义结构体类型*/
- {
- int year,month,day;
- };
- struct stu/*定义结构体类型*/
- {
- char name[20];
- long num;
- struct data birthday;
- };
- int main()
- {
- int i;
- struct stu *p,student[4]={{"liying",1,1978,5,23},{"wangping",2,1979,3,14},
- {"libo",3,1980,5,6},{"xuyan",4,1980,4,21}};
- /*定义结构体数组并初始化*/
- p = student;/*将数组的首地址赋值给指针p,p指向了一维数组student*/
- printf("Outputname,number,year,month,day\n");
- for(i = 0;i < 4;i++)/*采用指针法输出数组元素的各成员*/
- printf("%8s %6ld %d//%d//%d\n",(p+i)->name,(p+i)->num,
- (p+i)->birthday.year,(p+i)->birthday.month,
- (p+i)->birthday.day);
- return 0;
- }
执行结果如下:
- fs@ubuntu:~/qiang/struct/tmp$ ./struct2
- Outputname,number,year,month,day
- liying 1 1978//5//23
- wangping 2 1979//3//14
- libo 3 1980//5//6
- xuyan 4 1980//4//21
- fs@ubuntu:~/qiang/struct/tmp$
附:给大家看一个有意思的程序:
写出一个模拟时钟程序
分析:我们知道时间有时 分 秒 组成,这里用结构体表示
代码如下:
- #include <stdio.h>
- #include <unistd.h>
- #include <malloc.h>
- #include <string.h>
- typedef struct Clock
- {
- int hour;
- int minute;
- int second;
- }Clock;
- update(Clock *p)
- {
- p->second++;
- if(p->second == 60)
- {
- p->second = 0;
- p->minute++;
- }
- if(p->minute == 60)
- {
- p->minute = 0;
- p->hour++;
- }
- if(p->hour == 24)
- p->hour = 0;
- }
- Display(Clock *p)
- {
- printf("\r%02d:%02d:%02d",p->hour,p->minute,p->second);//%02d中0 输出数值时指定左面不使用的空位置自动填0,达到00:00:00效果
- fflush(stdout);//前面曾经讲过,printf属于行缓冲,遇到\n或程序结束才会输出,这里没有\n,所以用fflush刷新;
- }
- int main()
- {
- Clock *clock;
- clock = (Clock *)malloc(sizeof(Clock));
- memset(clock,'\0',sizeof(Clock));//时钟初始化
- while(1)
- {
- sleep(1);
- update(clock);
- Display(clock);
- }
- free(clock);
- return 0;
- }
执行结果如下:
- fs@ubuntu:~/qiang/struct$ ./clock
- 00:00:01
- fs@ubuntu:~/qiang/struct$ ./clock
- 00:00:55
这里是个动态效果,大家可以打印出来看一下
Linux C 深入分析结构体指针的定义与引用相关推荐
- c语言中结构体数组的引用,【C语言入门教程】7.2 结构体数组的定义和引用
7.2 结构体数组的定义和引用 当需要使用大量的结构体变量时,可使用结构体定义数组,该数组包含与结构体相同的数据结构所组成的连续存储空间.如下例所示: struct student stu_a[50] ...
- 【C语言入门教程】7.1 结构体类型变量的定义和引用
前面学习了变量和数组这些简单的数据结构,它们的特点是必须使用规定的数据类型.例如数组被定义为整型后,它的所有存储单元都是由整型构成.现实生活中某一类事物的共同属性可能是由不同的数据类型组成的集合,或者 ...
- Nwafu-Oj-1444 Problem l C语言实习题七——2.结构体数组的定义与引用
问题 : C语言实习题七--2.结构体数组的定义与引用 时间限制: 1 Sec 内存限制: 128 MB 提交: 4459 解决: 2011 [提交][状态][讨论版] 题目描述 定义一个职工结构 ...
- c语言中结构体变量的作用,C语言 结构体 类型变量的 定义 和 引用
前面学习了变量和数组这些简单的数据结构,它们的特点是必须使用规定的数据类型.例如数组被定义为整型后,它的所有存储单元都是由整型构成.现实生活中某一类事物的共同属性可能是由不同的数据类型组成的集合,或者 ...
- C语言中结构体变量的定义及引用
一.结构体变量的定义 1.结构体类型与结构体变量分开定义 一般形式如下: struct<结构体名><结构体变量名>; eg:struct student student1,st ...
- C语言结构体指针的定义和初始化
第一种方法:定义结构体,传入函数时取地址. typedef struct {int top; int bottom; int left; int right; }RECT_S;RECT_S pstRu ...
- C++学习笔记25——结构体的定义和使用,结构体数组,结构体指针
结构体 结构体的基本概念 结构体属于用户自定义的数据类型,允许用户存储不同的数据类型 结构体的定义和使用 语法:struct 结构体名 {结构体成员列表}: 通过结构体创建变量的方式有三种: stru ...
- C++之指针探究(九):结构体指针
前文:C++之指针探究(八):指针函数和函数指针 相关博文:C++之结构体探究 结构体指针的定义 (1) C语言中的结构体是一种非基本数据类型,可以将多种数据组合为新的数据类型: (2) 定义 ...
- 【C语言】结构体指针与结构体数组
目录 一.结构体指针 二.结构体数组 1.结构体数组的定义 2.结构体数组的初始化 3.结构体数组的引用 4.结构体数组指针 一.结构体指针 与一般指针类似结构体也可以使用结构体指针进行引用使用.结构 ...
最新文章
- Robot Framework自动化测试(六)--- robotremoteserver使用
- 如何学好算法与程序设计
- 5天玩转C#并行和多线程编程 —— 第四天 Task进阶
- [转]技巧:Vim 的纵向编辑模式
- [渝粤教育] 西南科技大学 单片机原理与应用 在线考试复习资料(2)
- java中bean对象_JAVA中PO,BO,VO,DTO,POJO,Entity,JavaBean,JavaBeans各个对象的区别,以及lombo、jpa简介及用法...
- Python爬虫偷懒神器 — 快速构造请求头!
- Qt第一印象——Qte与Qt
- 实用小程序,快速求A类不确定度(物理实验),保留六位
- JDBC连接池原理及分析
- DM8整合java的jpa框架(附整合源码)
- 什么是单页应用SPA
- linux下kegg注释软件,KEGG pathway注释过程
- 一款非常强大的vlc多媒体视频播放器:VLC Media Player for mac
- 钉钉微应用H5的调试方法
- java socket 连接异常_JAVA Socket连接服务器时可能抛出的异常
- 完美世界暴力裁员:工作996、生病被关小黑屋,有摄像头监控!
- //css 层叠样式表(Cascading Style Sheets)
- Android百度AI植物识别教程,微信开发+百度AI学习:植物识别(示例代码)
- Android Gradle 7.x新版本的依赖结构变化
热门文章
- Xamarin开发IOS笔记:切换输入法时输入框被遮住
- VSFTP的主动模式和被动模式
- linux的搜索和时间
- JavaScript窗体控制函数
- Linux DHCP Server 配置给FIT AP 使用的option
- how to get the space size of some tables in one database?
- 回归分析假设_回归分析假设的最简单指南
- linux bash命令_Ultimate Linux命令行指南-Full Bash教程
- 协方差意味着什么_“零”到底意味着什么?
- mybatis-generator-gui如何打包成exe