结构指针可以细分为指向结构变量的指针和指向结构数组的指针。
指向结构变量的指针
前面使用了名为“结构变量名称.成员名称”的方法引用了结构变量的成员,除了这种方法之外,还可以使用指针。
如上所述,student1表示结构变量student1的起始地址,即student1中第一个条目的地址。 如果指针变量p定义为指向该地址,p可以指向结构变量student1的任何成员。
那么,这个指针变量是被定义为什么类型的呢? 只能定义为结构类型,而指向哪个结构类型的结构变量定义为什么结构类型? 例如,对于指向struct STUDENT类型的结构变量,指针变量必须定义为struct STUDENT*类型。
用指针修改前面的程序。
#包含
#包含
struct AGE
{
年;
int month;
输入日期;
(;
struct STUDENT
{
char name[]; //名称
int num; //学号
struct AGE birthday; //生日
浮动比例; //分数
(;
入主(void ) )。
{
struct STUDENT student1; 结构student结构类型中的结构变量student1*/
struct STUDENT *p=NULL; 指向struct STUDENT结构类型的指针变量p*/
p=student1; /*p结构变量student1的起始地址,即第一个成员的地址*/
strcpy () p ).name,“简单门”; //(p ).name等效于student1.name
(p ).birthday.year=;
(p ).birthday.month=;
(p ).birthday.day=;
(p ).num=;
(p ).score=;
printf(name:%s(n ),) p ).name; //(p ).name不能写成p
printf(birthday:%d-%d-%d(n ),(p ).birthday.year,(p ).birthday.month,) p ).birthday
printf(num:%d(n ),) p ).num );
打印(score : %.1f (n ),) p ).score;
返回;
}
输出结果如下。
name :简单玄关
birthday : 1989-3-29
num : 1207041
score : 100.0
要用指针引用结构变量的成员,请执行以下操作:
(指针变量名) .成员名称
*请注意,p两边的括号不能省略。 如果省略*p两边的括号,*p.num将等效于*(p.num ),因为成员运算符“.”的优先级高于指针运算符“*”。
从这个程序也可以看出,指针变量p指向了结构变量student1的第一个成员的地址,即字符数组name的第一个地址,所以p和(*p ).name等价。
但是,“等效”只是表示同一存储单元的地址,其类型不同。 指针变量p是struct STUDENT*类型,(p ).name是char*类型。 所以不能用strcpy把(p ).name变成p。 用%s输入或输出时,输入参数或输出参数也只能写为() p ).name,不能写为p。
同样,student1和student1.name表示同一内存单元的地址,但类型不同。 student1是struct STUDENT*型,student1.name是char*型,所以在初始化p时,请输入“p=student1; 不能写“p=student1.name”。 因为p是struct STUDENT*类型,所以不能将char*类型的student1.name指派给p。
另外,为了易用性和直观性,使用指针引用结构变量成员的方法:
(指针变量名) .成员名称
可以直接使用:
指针名称-成员名称
相反,它们是等价的。 其中-是指结构成员的运算符,优先级与结构成员运算符“.”的优先级相同。 p-num意思是指针变量p所指示的结构变量
中的 num 成员。p->num 最终代表的就是 num 这个成员中的内容。下面再将程序用“->”修改一下:
# include
# include
struct AGE
{
int year;
int month;
int day;
};
struct STUDENT
{
char name[]; //姓名
int num; //学号
struct AGE birthday; /*用struct AGE结构体类型定义结构体变量birthday, 生日*/
float score; //分数
};
int main(void)
{
struct STUDENT student1; /*用struct STUDENT结构体类型定义结构体变量student1*/
struct STUDENT *p = NULL; /*定义struct STUDENT结构体类型的指针变量p*/
p = &student1; /*p指向结构体变量student1的首地址, 即第一项的地址*/
strcpy(p->name, "单纯的大门");
p->birthday.year = ;
p->birthday.month = ;
p->birthday.day = ;
p->num = ;
p->score = ;
printf("name : %sn", p->name); //p->name不能写成p
printf("birthday : %d-%d-%dn", p->birthday.year, p->birthday.month, p->birthday.day);
printf("num : %dn", p->num);
printf("score : %.1fn", p->score);
return ;
}
[转]C语言字节对齐问题详解
C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...
Linux C 语言之 Hello World 详解
目录 Linux C 语言之 Hello World 详解 第一个 C 语言程序 程序运行原理 编译,链接 运行时 链接库 编译器优化 Hello World 打印原理 stdout, stdin 和 ...
C语言解决约瑟夫问题详解的代码
将开发过程中比较重要的一些内容做个收藏,下面的内容是关于C语言解决约瑟夫问题详解的内容,希望能对码农有帮助. #pragma once #include class PRO ...
C语言字节对齐问题详解
引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...
C语言预处理器命令详解【转】
本文转载自:http://www.cnblogs.com/clover-toeic/p/3851102.html 一 前言 预处理(或称预编译)是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所 ...
C语言字节对齐问题详解(对齐、字节序、网络序等)
首先说明一下,本文是转载自: http://www.cnblogs.com/clover-toeic/p/3853132.html 博客园用的少,不知道怎么发布转载文章,只能暂时这样了. 引言 考虑下 ...
C语言字节对齐问题详解【转】
引言 转自:http://www.cnblogs.com/clover-toeic/p/3853132.html 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 ...
c语言文件操作函数详解
一.文件操作注意点: 1 打开文件时,如果打开方式加“+”,表示该文件可以“写” ; 2 退出程序一般用exit函数,正常退出参数为0,非正常退出参数为正零值 ; 3 文件的读写操作:按字符.字符串. ...
C语言链表各类操作详解
链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...
【C语言】printf函数详解
C语言printf函数详解 一.相关基础知识 请求printf()打印变量的指令取决于变量的类型,例如打印整数用%d符号,打印字符用%c符号,这些符号称为转换说明(conversion specifi ...
随机推荐
QoS 测量 (目标,方法,协议)
本文翻译自ITU-T的Technical Paper:
spring+mybatis的优缺点
mybatis的优缺点: 优点: 1. 易于上手和掌握. 2. sql写在xml里,便于统一管理和优化. 3. 解除sql与程序代码的耦合. 4. 提供映射标签,支持对象与数据库的orm字段关系映射 ...
【转】android应用开发全程实录-你有多熟悉listview?---不错
原文网址:http://www.cnblogs.com/noTice520/archive/2011/12/05/2276379.html 今天给大家带来 ...
CCF系列之日期计算(201509-2)
试题编号: 201509-2 时间限制: 1.0s 内存限制: 256.0MB 问题描述 给定一个年份y和一个整数d,问这一年的第d天是几月几日? 注意闰年的2月有29天.满足下面条件之一的是闰年: ...
pipe size设置
我所用的软件架构,使用pipe来实现线程之间的大量数据的传输.在实际操作中,pipe中传输的是数据的指针,而不是数据本身. 但是在调试过程中,我发现,如果我尝试往pipe里面write10000个指 ...
[Leetcode]237. Delete Node in a Linked List -David_Lin
Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...
[转] Form 表单数据处理 简单教程 formidable 使用心得
入门,聪慧的季节见笑 表单数据一种是get方式, 另一种是post 方式 1.get方式 对于get方式,node处理起来非常简单 如以下代码: var urlParsed = url.parse(requ ...
Unity中的定时器与延时器
JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...
随机数的组合问题(JavaScript描述)
随机数的组合问题在面试时是经常考的,比如之前我就被问到:“有一个可以生成1-5的随机数函数,怎样把它扩大到1-7?” 在解决这个问题之前,先来看看另外一个比较简单的问题:“有一个可以生成1-7的函数, ...