首页 > 其他分享 >指向结构体类型数据的指针

指向结构体类型数据的指针

时间:2024-03-24 12:58:06浏览次数:18  
标签:变量 指向 struct name stu num 类型 指针

一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量.用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素。

1指向结构体变量的指针

下面通过一个简单例子来说明指向结构体变量的指针变量的应用。

例11.3指向结构体变量的指针的应用。

# include <string. h>

main ( )

{struct student

{long num;

char name[20];

char sex;

float score;

};

struct student stu_1;

struct student* p;

p=&stu_1;

stu_1.num=89101;

strcpy(stu_1. name,"Li Lin" );

stu_1.sex='M' ;

stu_1.score=89.5;

printf ("No. :%ld\nname:%s\nsex:%c \nscore:%f\n",stu_1. num,stu_ 1. name, stu_ 1. sex,

stu-1.score);

printf ("No. :%ld\nname:%s\nsex:%c\nscore:%f\n",( * p).num,( * p). name,( *p),sex,

(*p).score);

在主函数中声明了struct student类型,然后定义一个struct student类型的变量 stu-1。同时又定义一个指针变量p,它指向一个 struct student类型的数据。在函数的执行部分将结构体变量stu_1的起始地址赋给指针变量p,也就是使p指向stu-1(见图11.7),然后对stu_1的各成员赋值。第一个printf函数是输出stu_1的各个成员的值。用stu_1.num表示stu-1中的成员num,余类推。第二个printf函数也是用来输出stu-1各成员的值,但使用的是(*p).num 这样的形式。(*p)表示p指向的结构体变量,(*p).num 是p指向的结构体变量中的成员num。注意*p两侧的括弧不可省,因为成员运算符“.”优先于“*”运算符,*p.num 就等价于*(p.num)了。

程序运行结果如下:

No:89101

name:Li Lin

sex:M

score:89.500000

No:89101

name;Li Lin

sex:M

score:89.500000

可见两个printf函数输出的结果是相同的。

在C语言中,为了使用方便和使之直观,可以把(*p).num 改用p->num 来代替,它表示p所指向的结构体变量中的num成员。同样,(*p).name 等价于p-> name。也就是说,以下三种形式等价:

  1. 结构体变量.成员名
  2. (*p).成员名
  3. p->成员名

上面程序中最后一个printf函数中的输出项表列可以改写为

p->num,p->name,p->sex,p->score

其中一>称为指向运算符。

请分析以下几种运算:

p->n 得到p指向的结构体变量中的成员n的值。

p->n++ 得到p指向的结构体变量中的成员n的值,用完该值后使它加1。

++p->n 得到p指向的结构体变量中的成员n的值加1,然后再使用它。

2指向结构体数组的指针

以前已经介绍过,可以使用指向数组或数组元素的指针和指针变量。同样,对结构体数组及其元素也可以用指针或指针变量来指向。

例11.4指向结构体数组的指针的应用。

struct student

{int num;

char name[20];

char sex;

int age;

}

struct student stu[3]={{10101."Li Lin",'M',18},(10102,"Zhang Fun",' M',19}.{10104,

"Wang Min",'F’,20}}:

main()

{struct student *p;

printf(" No. Name sex age\n");

for (p=stu;p<stu+3;p++)

printf ("%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);

}

运行结果如下:

p是指向 struct student结构体类型数据的指针变量。在for语句中先使p的初值为stu,也就是数组stu 的起始地址,见图11.8中p的指向。在第一次循环中输出stu[0]的各个成员值。然后执行p++,使p自加1.p加1意味着p所增加的值为结构体数组stu的一个元素所占的字节数(在本例中为2+20+1+2=25 字节)。执行p++后p的值等于stu+1,p指向stu[1]的起始地址,见图11.8中p'的指向。在第二次循环中输出stu[1]的各成员值。在执行p++后.p的值等于stu+2,它的指向见图10.8中的p"。再输出stu[2]的各成员值。在执行p++后,p的值变为stu+3,已不再小于stu+3了,不再执行循环。

注意以下两点:

  1. 如果p的初值为stu,即指向第一个元素,则p加1后p就指向下一个元素的起始地址。

例如:

(++p)->num 先使p自加1,然后得到它指向的元素中的num成员值(即10102)。

(p++)->num 先得到p->num 的值(即10101),然后使p自加 1,指向 stu[1].请注意以上二者的不同。

(2)程序已定义了p是一个指向struct student类型数据的指针变量,它用来指向一个 struct student型的数据(在例11.4中p的值是stu数组的一个元素(如stu[0],stu[1])的起始地址),不应用来指向stu数组元素中的某一成员。例如,下面的用法是不对的:

p=stu[1].name1

编译时将给出“警告”信息,表示地址的类型不匹配。不要认为反正p是存放地址的,可以将任何地址赋给它。如果要将某一成员的地址赋给p,可以用强制类型转换,先将成员地址转换成p的类型。例如:

p= (struct student* )stu[0].name;

此时.p的值是stu[0]元素的 name成员的起始地址。可以用“printf("%s",p);"输出stu[0]中成员 name 的值,但是P仍保持原来的类型,如果执行“printf("%s",p+1);".则会输出stu[1]中 name的值。执行p+1时,p的值增加了结构体struct student的长度。

3用结构体变量和指向结构体的指针作函数参数

将一个结构体变量的值传递给另一个函数,有3个方法:

(1)用结构体变量的成员作参数。例如,用stu[1].num或stu[2]. name作函数实参,将实参值传给形参。用法和用普通变量作实参是一样的,属于“值传递”方式,应当注意实参与形参的类型保持一致。

(2)用结构体变量作实参。老版本的C系统不允许用结构体变量作实参,ANSIC取看了这一限制。但是用结构体变量作实参时,采取的是“值传递”的方式,将结构体变量所占的内存单元的内容全部顺序传递给形参。形参也必须是同类型的结构体变量。在函数胃用期间形参也要占用内存单元。这种传递方式在空间和时间上开销较大,如果结构体的规模很大时,开销是很可观的。此外,由于采用值传递方式,如果在执行被调用函数期间改变了形参(也是结构体变量)的值,该值不能返回主调函数,这往往造成使用上的不便。因此一般较少用这种方法。

(3)用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给

形参

例11.5 有一个结构体变量stu,内含学生学号、姓名和3门课的成绩。要求在main函数中赋以值,在另一函数print中将它们打印输出。

今用结构体变量作函数参数。

#include <string.h>

#define FORMAT " %d\n%s\n%f\n%f\n%f\n"

struct student

{int num ;

char name[20];

float score[3];

}

main()

{void print(struct student );

struct student stu;

stu.num=12345;

strepy(stu, name,"Li Li");

stu. score[0]=67.5;

stu. score[1]=89;

 stu.score[2]=78.6;

print(stu);

}

void print (struct student stu)

{

printf(FORMAT,stu.num,stu.name, stu. score[0],stu.score[1].stu. score[2]);

printf("\n" );

}

运行结果为:

12345

Li Li

67.500000

89.000000

标签:变量,指向,struct,name,stu,num,类型,指针
From: https://blog.csdn.net/office_lgirl/article/details/136946546

相关文章

  • Struts2中type类型有哪些?Struts2默认能解决get和post提交方式的乱码问题吗?Struts2中如
    Struts2中type类型有哪些?Struts2中type类型指的是结果类型,用于指定Action执行完成后如何返回结果给客户端。Struts2框架提供了多种结果类型,以满足不同的业务需求和页面跳转方式。以下是一些常见的Struts2结果类型:dispatcher:这是默认的结果类型,相当于servlet的forward,即服......
  • 基础算法--双指针练习总结
    Acwing部分练习:799.最长连续不重复子序列暴力未AC(53points):#include<iostream>usingnamespacestd;constintN=1e5+5;intn,a[N];boolcheck(intl,intr){for(inti=l;i<=r;i++){for(intj=i;j<=r;j++){if(i!=j&&a[i]==a[j]){......
  • 参数"news"隐式具有'any'类型 解决方法
    代码functionchangePage(news){router.push({name:'detail',//path:'news/detail',query:{id:news.id,title:news.title,content:news.content,}})}方法1在报错参数后加上:anyfunction......
  • 20240322,结构类型,枚举,
     一,枚举1.1常量符号化 程序中用符号表达数字,增加程序的可读性?#include<stdio.h>//能跑,但是报错不推荐将字符串转为CHAR**constintred=0;constintyellow=1;constintgreen=2;//为撒在前面?intmain(intargc,charconst*argv[]){ //两个参数,整数,字符串数组......
  • long数据类型跨平台问题
    源代码#include<iostream>intmain(){ std::cout<<"sizeoflong:"<<sizeof(long)<<std::endl; return0;}Windowslong->32位Linuxlong->64位建议跨平台程序尽量采用跨平台库,如Boostnamespaceboost{using::int8_t;......
  • 如何判断是哪一种类型的VPP项目
    判断VPP是那种类型,可以通过查找到Cognex安装目录下的VPPVersion.exe然后再命令行键入如下来显示VPP的类型以及包含工具的版本信息C:\ProgramFiles\Cognex\VisionPro\bin>VPPversion--helpCognexVisionProVersionUtility-v1.0VPPVersion.exeOptions:-v,--verbose......
  • 智能指针详解
    文章目录前言unique_ptrshared_ptrweak_ptr前言智能指针本质上来讲是一个存储指向堆内存指针的类,目的就是帮助我们管理内存,一旦使用了智能指针就就尽量使用new产生的指针,因为智能指针只维护同类型指针的引用计数,混用很容易造成内存重复释放的问题unique_ptrstd:......
  • mysql中的数据类型大全纯干货------------时间日期类型
    简介(类型预览):在mysql8.0版本中支持的类型主要有:YEAR类型表示年DATE类型表示年,月,日TIME类型表示时,分,秒DATETIME类型表示年,月,日,时,分,秒TIMESTAMP类型通常表示带时区的年,月,日,时,分,秒数据类型单位占用字节格式下限上限YEAR年1YYY或YY19012155TIME时间3H......
  • 1.变量与数据类型、输出与输入
    C语言语法知识点1.变量与数据类型、输出与输入C中每个变量都有特定的类型,类型决定了变量存储的大小。变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。有以下几种基本的变量类型:类型char字符型,1字节(1字节8位,即1字节=8bit)int整型,4字节......
  • ☆【前后缀】【双指针】Leetcode 42. 接雨水
    【前后缀】【双指针】Leetcode42.接雨水解法1前后缀分解解法2双指针---------------......