一、 结构体类型指针
1、结构体指针变量
以读方式访问形参的函数,仅出于性能的考虑,可以地址方式传参,避免结构复制所带来的开销。 为防止在函数中意外地修改实参,可以用常量指针定义参数。
2、指针引用结构体成员的三种形式
①结构体变量名.成员名 ②(*p).成员名 ③p- >成员名
p->n
p->n++
++p->n
二、 指向结构体变量的结构体指针变量
1、结构体指针变量的指向和输出
结构体变量的指针是该结构体变量所占据内存段的起始地址。 例1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
int main(int argc,char const *argv[])
{
struct stu
{
int x;
float y;
char a[4];
}ww,*p;
p=&ww;
ww.x=10;
ww.y=20;
strcpy(ww.a,"abc");
printf("%d\n",*p);
printf("%f\n",(*p).y);
printf("%s\n",p->a);
printf("%c\n",p->a[0]);
while(1);
return 0;
}
例2:
#include <stdio.h>
typedef struct date
{
int year;
int month;
int day;
}DATE;
struct student
{
char name[128];
int age;
DATE birthday;
}s1={"小云",21,{1996,9,21}};
typedef struct student STU;
void show(const STU *st)
{
printf("姓名:%s\n",st->name);
printf("年龄:%d\n",st->age);
printf("生日:%d年%d月%d日\n",st->birthday.year,
st->birthday.month,st->birthday.day);
}
void grow(STU *st)
{
st->age++;
}
void main()
{
STU s2={"小舞",18,{1996,10,5}};
STU *ps=&s2;
STU *pt;
grow(&s2);
printf("%d %d\n",ps->age,ps->birthday.year);
show(&s2);
printf("%s\n",s1.name);
pt=&s1;
show(pt);
}
例3:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char const *argv[])
{
struct student
{
long int num;
char name[20];
char sex;
};
struct student stu_1;
struct student *p;
p=&stu_1;
stu_1.num=9901;
strcpy(stu_1.name,"Li Min");
stu_1.sex='M';
printf("No:%ld name:%s sex:%c \n",stu_1.num,stu_1.name,stu_1.sex);
printf("No:%ld name:%s sex:%c \n",(*p).num,(*p).name,(*p).sex);
printf("No:%ld name:%s sex:%c \n",p->num,p->name,p->sex);
while(1);
return 0;
}
2、结构体指针变量作为形参
用指向结构体类型数据的指针作为函数的参数-把结构体变量的值由一个函数传递给另一个函数。 (1)用结构体的成员作为函数参数。把结构体成员的数值传给形参。(单向值传递) (2)用结构体变量作为函数参数,把整个结构体变量传给形参。(单向值传递) (3)用指向结构体变量的指针作为实参,将结构体变量的地址传给形参。(双向地址传递) 例1:
#define FORMAT "%d\n%s\n%f\n%f\n%f\n"
struct student
{
int num;
char name[20];
float score[3];
}stu={12345,"Li li",67.5,89,78.6};
int main(int argc,char const *argv[])
{
void print(struct student *);
print(&stu);
while(1);
return 0;
}
void print(struct student *p)
{
printf(FORMAT,p->num,(*p).name,(*p).score[0],p->score[1],p->score[2]);
}
三、 指向结构体数组的结构体指针变量
结构体数组的元素可以用指针或指针变量来指向、进行引用。 例1:
#include <stdio.h>
#include <stdlib.h>
struct student
{
int num;
char name[20];
char sex;
int age;
};
struct student stu[3]={
{10101,"LiLin",'M',18},
{10102,"ZhangHua",'M',19},
{10103,"WangPin",'F',20}
};
int main(int argc,char const *argv[])
{
struct student *p;
printf(" NO: Name Sex Age\n");
for(p=stu;p<stu+3;p++)
{
printf("%5d %8s %2c %d\n",p->num,(*p).name,p->sex,(*p).age);
}
while(1);
return 0;
}
p定义为结构体student的指针变量,则p++ 指向的是结构体数组的下一个元素,而不是结构体的下一个成员。由于定义的是指向结构体的指针,因此它只能指向结构体,而不能指向结构体的成员。如果一定要指向一个非结构体数据,则可以使用强制类型转换。
如:
p=(struct student *)&stu[0].age;
例2:
#include <stdio.h>
#include <stdlib.h>
typedef struct student
{
char name[10];
int ino;
int age;
}STU_T;
void print(STU_T *p,int len)
{
STU_T *p2;
printf("%d\n",len);
for(p2=p;p2<p+len;p2++)
{
printf("%s,%d,%d\n",p2->name,p2->ino,p2->age);
}
}
void main()
{
int len=0;
STU_T stu1={"admin",1000,15};
STU_T stus[4]={
{"admin1",1001,15},
{"admin2",1002,16},
{"admin3",1003,17},
{"admin4",1004,18}
};
STU_T *p=NULL;
p=&stu1;
len=sizeof(stus)/sizeof(stus[1]);
print(stus,len);
printf("%s,%d,%d\n",stu1.name,stu1.ino,stu1.age);
printf("%s,%d,%d\n",p->name,p->ino,p->age);
printf("%s,%d,%d\n",stu1.name,(*p).ino,p->age);
while(1);
return 0;
}
例3:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int id;
int score;
char name[128];
void (*printfo)(int,char*,int);
};
void printfoReal(int id,char *name,int score)
{
printf("我的姓名:%s,学号:%d,成绩:%d\n",name,id,score);
}
void initStus(struct student stus[],int total)
{
int i;
for(i=0;i<total;i++)
{
printf("请输入第%d学生的学号: ",i+1);
scanf("%d",&(stus[i].id));
printf("请输入第%d学生的姓名: ",i+1);
scanf("%s",stus[i].name);
printf("请输入第%d学生的成绩: ",i+1);
scanf("%d",&(stus[i].score));
stus[i].printfo=printfoReal;
}
}
void findDatas(struct student stus[],int total,struct student *pbest,struct student *pworst)
{
int i;
*pbest=*pworst=stus[0];
for(i=0;i<total;i++)
{
if((*pbest).score<stus[i].score)
{
*pbest=stus[i];
}
if(pworst->score>stus[i].score)
{
*pworst=stus[i];
}
}
}
void putStus(struct student stus[],int total)
{
int i;
for(i=0;i<total;i++)
{
stus[i].printfo(stus[i].id,stus[i].name,stus[i].score);
}
}
int main(int argc,char const *argv[])
{
int i;
int total=3;
struct student best;
struct student worst;
struct student stus[10];
#if 0
printf("请输入班级总人数: ");
scanf("%d",&total);
struct Student stus[total];
#endif
initStus(stus,total);
putStus(stus,total);
findDatas(stus,total,&best,&worst);
printf("最高成绩\n");
best.printfo(best.id,best.name,best.score);
printf("最低成绩\n");
worst.printfo(worst.id,worst.name,worst.score);
while(1);
return 0;
}
例4:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int id;
int score;
char *name;
void (*printfo)(int,char*,int);
};
void printfoReal(int id,char *name,int score)
{
printf("我的姓名:%s,学号:%d,成绩:%d\n",name,id,score);
}
void initStus(struct student *stus,int total)
{
int i;
for(i=0;i<total;i++)
{
printf("请输入第%d学生的学号: ",i+1);
scanf("%d",&(stus->id));
printf("请输入第%d学生的姓名: ",i+1);
stus->name=(char *)malloc(128);
scanf("%s",stus->name);
printf("请输入第%d学生的成绩:",i+1);
scanf("%d",&((*stus).score));
stus->printfo=printfoReal;
stus++;
}
}
void findDatas(struct student *pstus,int total,struct student *pbest,struct student *pworst)
{
int i;
*pbest=*pworst=*pstus;
for(i=0;i<total;i++)
{
if((*pbest).score<pstus->score)
{
*pbest=*pstus;
}
if(pworst->score>pstus->score)
{
*pworst=*pstus;
}
pstus++;
}
}
void putStus(struct student *pstus,int total)
{
int i;
for(i=0;i<total;i++)
{
pstus->printfo(pstus->id,pstus->name,pstus->score);
pstus++;
}
}
int main(int argc,char const *argv[])
{
int total=3;
struct student best;
struct student worst;
struct student stus[10];
#if 0
printf("请输入班级总人数: ");
scanf("%d",&total);
struct student stus[total];
#endif
initStus(stus,total);
putStus(stus,total);
findDatas(stus,total,&best,&worst);
printf("最高成绩\n");
best.printfo(best.id,best.name,best.score);
printf("最低成绩\n");
worst.printfo(worst.id,worst.name,worst.score);
while(1);
return 0;
}
四、指向结构体类型函数的结构体指针变量(结构体类型指针作为返回值)
例:
#include <stdio.h>
#include <stdlib.h>
typedef struct student
{
char name[10];
int ino;
int age;
}STU_T;
STU_T *get()
{
static STU_T stus[3]={
{"admin1",1000,15},
{"admin2",1001,16},
{"admin4",1004,18}
};
return &stus[1];
}
void main()
{
int len=0;
STU_T stus[3]={0};
STU_T *p=NULL;
len=sizeof(stus)/sizeof(stus[1]);
p=get();
printf("%s %d %d\n",p->name,(*p).ino,p->age);
}
五、动态分配内存的结构体指针变量
例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int id;
int score;
char name[128];
void (*printfo)(int,char*,int);
};
void printfoReal(int id,char *name,int score)
{
printf("我的姓名:%s,学号:%d,成绩:%d\n",name,id,score);
}
int main(int argc,char const *argv[])
{
struct student stu1;
struct student *stu2;
stu2=(struct student *)malloc(sizeof(struct student));
stu1.id=10;
stu1.score=85;
strcpy(stu1.name,"lili");
stu1.printfo=printfoReal;
stu2->id=11;
stu2->score=86;
strcpy(stu2->name,"lily");
stu2->printfo=printfoReal;
stu1.printfo(stu1.id,stu1.name,stu1.score);
stu2->printfo(stu2->id,stu2->name,(*stu2).score);
while(1);
return 0;
}
编辑 2020-06-16 12:30 首次编辑 增改 2021-07-22 23:47 内容结构修改
注:本文旨于作为自己的学习笔记,不作他用。
|