文章目录
一、结构体指针
通过定义好的结构体“模型”不但可以定义对象,也可以定义用于指向对象的就结构体指针变量,当然还可以定义结构体对象的数组。
如果要使用结构体指针变量访问对象的话,首先要使用*符号获得对象的类型,再使用.符号去访问对象内的成员数据。
//[例1-1]测试结构体指针变量
#include<stdio.h>
typedef struct _SWork
{
int nNumb; //工号
char sName[20]; //姓名
float fSala; //工资
}SWork;
int main()
{
SWork w1 = { 1008,"张珊",8632.35f };
SWork w2 = { 1009,"李思思"};
SWork *p = &w1;
printf("p指向的对象内的数据为:%d,%s,%0.2f\n", (*p).nNumb, (*p).sName, (*p).fSala);
p = &w2;
printf("p指向的对象内的数据为:%d,%s,%0.2f\n", (*p).nNumb, (*p).sName, (*p).fSala);
(*p).fSala = 8888.88f;
printf("w2象内的数据为:%d,%s,%0.2f\n", w2.nNumb, w2.sName, w2.fSala);
return 0;
}
从例子1-1中可以看出,使用结构体指针变量调用对象内的数据似乎很麻烦,因为不但要使用*和.符号还要使用小括号把它包起来。因此,C语言为结构体指针变量专门定制了一个->指针符号,使用这个箭头模样的符号来调用成员变量代码变得简洁多了。
//[例1-2]测试结构体指针符号
#include<stdio.h>
typedef struct _SWork
{
int nNumb; //工号
char sName[20]; //姓名
float fSala; //工资
}SWork;
int main()
{
SWork w1 = { 1008,"张珊",8632.35f };
SWork w2 = { 1009,"李思思"};
SWork *p = &w1;
printf("p指向的对象内的数据为:%d,%s,%0.2f\n", p->nNumb, p->sName, p->fSala);
p = &w2;
printf("p指向的对象内的数据为:%d,%s,%0.2f\n", p->nNumb, p->sName, p->fSala);
p->fSala = 8888.88f;
printf("w2象内的数据为:%d,%s,%0.2f\n", w2.nNumb, w2.sName, w2.fSala);
return 0;
}
二、结构体数组
当使用结构体数组做参数时,实际上同其他数组做参数一样,都会被编译器在内部转为指针变量。
代码如下(示例):
//[例2-1]测试结构体数组
#include<stdio.h>
#include <stdlib.h>
typedef struct _SWork
{
int nNumb; //工号
char sName[20]; //姓名
float fSala; //工资
}SWork;
//数组做参数就是等价于指针
//void Input(SWork p[], int nCount)
void Input(SWork* p, int nCount)
{
int i = -1;
while (++i < nCount)
{
puts("请输入工号、姓名和工资(%d-%d):",i+1,nCount);
scanf("%d%s%f", &p[i].nNumb, p[i].sName, &p[i].fSala);
}
}
void Print(const SWork *p,int nCount)
{
int i = -1;
puts("工号\t姓名\t工资");
while (++i < nCount)
printf("%d\t%s\t%0.2f\n", p[i].nNumb, p[i].sName, p[i].fSala);
}
int main()
{
SWork ws[5];
Input(ws,_countof(ws));
Print(ws, _countof(ws));
return 0;
}
在例2-1的Input和Print函数中,都使用的是指针的下标法来访问主调函数中的数组元素。
可以在Input和Print函数中,使用指针法来实现对来源数组中的每个元素的数据读写。如下所示:
//[例2-2]测试指针法访问结构体数组
#include<stdio.h>
#include <stdlib.h>
typedef struct _SWork
{
int nNumb; //工号
char sName[20]; //姓名
float fSala; //工资
}SWork;
void Input(SWork* p, int nCount)
{
int i = -1;
while (++i < nCount)
{
printf("请输入工号、姓名和工资(%d-%d):\n",i+1,nCount);
scanf("%d%s%f", &p->nNumb, p->sName, &p->fSala);
++p;
}
}
void Print(const SWork *p,int nCount)
{
puts("工号\t姓名\t工资");
while (nCount--)
printf("%d\t%s\t%0.2f\n", p->nNumb, p->sName, p->fSala),++p;
}
int main()
{
SWork ws[5];
Input(ws,_countof(ws));
Print(ws, _countof(ws));
return 0;
}
使用指针法访问数组元素时,循环过程可以节省下标变量的使用
三、练习有关结构体例子
1、当输入一个年月日后, 输出该日是这一年的第几天。
定义一个普通结构体包含年月日,在main函数中定义一个结构体对象,
#include <stdio.h>
struct SDate
{
int nYear;
int nMonth;
int nDay;
};
int main()
{
int a[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
SDate d;
printf("请输入一个日期(年月日):");
scanf_s("%d%d%d", &d.nYear, &d.nMonth, &d.nDay);
int sum = d.nDay;
int i = 0;
while (++i<d.nMonth)
{
sum += a[i-1];
}
if (d.nMonth>2)
{
if (d.nYear % 4 == 0 && d.nYear % 100 || d.nYear % 400 == 0)
++sum;
}
printf("%d年%d月%d日是第%d天\n", d.nYear, d.nMonth, d.nDay, sum);
return 0;
}
2、定义一个普通结构体包含年月日,在main函数中定义一个结构体对象
2、定义一个普通结构体包含年月日,在main函数中定义一个结构体对象。 (使用输出型参数)开发一个函数,对主调函数带入的对象输入年月日。
void Input(…输出型参数…) (使用输入型结构体参数)开发一个函数, int Calc(…输入型参数…);
对主调函数代入的结构体对象进行计算输出该日是这一年的第几天,在函数中计算结果。 在主调函数中打印。
#include <stdio.h>s
struct SDate
{
int nYear;
int nMonth;
int nDay;
};
void Input(struct SDate* p)
{
printf("请输入一个日期(年月日):");
scanf_s("%d%d%d", &p->nYear, &p->nMonth, &p->nDay);
}
int Calc(const SDate* p)
{
int a[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int sum = p->nDay;
int i = 0;
while (++i < p->nMonth)
{
sum += a[i - 1];
}
if (p->nMonth > 2)
{
if (p->nYear % 4 == 0 && p->nYear % 100 || p->nYear % 400 == 0)
sum++;
}
return sum;
}
int main()
{
SDate d;
Input(&d);
int n = Calc(&d);
printf("%d年%d月%d日是第%d天\n", d.nYear, d.nMonth, d.nDay, n);
return 0;
}
3、键盘输入5个用户的数据,包括:姓名和电话号码。要求按姓名排序后输出全部数据。
(用结构体数组完成)
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
struct SScore
{
int nNumb;
char sName[20];
float fMath;
float fChin;
float fEng;
};
void Input(SScore* p, int nLen)
{
int i = 0;
while (i<nLen)
{
printf("请输入与第%d个学生信息:", ++i);
scanf_s("%d%s%f%f%f", &p->nNumb, p->sName, (int)sizeof(p->sName),
&p->fMath, &p->fChin, &p->fEng);
++p;
}
}
void Sum(SScore* p, int nLen)
{
int i = -1;
float fMath = 0.0f, fChin = 0, fEng = 0;
float fMax = 0.0;
const SScore* q = p;
while (++i<nLen)
{
fMath += p->fMath;
fChin += p->fChin;
fEng += p->fEng;
float sum = p->fMath + p->fChin + p->fEng;
if (fMax < sum) //更新算法
{
fMax = sum;
q = p;
}
++p;
}
printf("数学平均分:%0.1f\n", fMath/nLen);
printf("语文平均分:%0.1f\n", fChin/nLen);
printf("英语平均分:%0.1f\n", fEng/nLen);
printf("总分最高是:%d\t%s\t%0.1f\t%0.1f\t%0.1f\n", q->nNumb,q->sName,
q->fMath,q->fChin,q->fEng);
}
int main()
{
SScore s[2];
Input(s, _countof(s));
Sum(s, _countof(s));
return 0;
}
4、从键盘上输入10个学生的数据,包括:学号、姓名、三门课的成绩。
要求输出3门课的平均成绩及最高学分学生成绩。
(使用结构体数组完成)
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
//每个结构体名称前面加s有的公司用_开头 编码规范
struct SInfo
{
char sName[20];
char sTel[20]; //longlong
};
void Input(SInfo* p, int nLen)
{
int i = 0;
while (i < nLen)
{
printf("请输入与第%d个员工信息:", ++i);
scanf_s("%s%s", p->sName, (int)sizeof(p->sName),
p->sTel, (int)sizeof(p->sName));
++p;
}
}
void Sort(SInfo* p, int nLen) // const的指针,改变实参数组的数据
{
int i = nLen;
while( --i > 0) //循环4次 1...4
{
int j = -1;
while (++j<i)
{
//0...3
//if (p[j].sName >p[j+1].sName) //错误 :比较地址
if(_stricmp(p[j].sName , p[j + 1].sName)>0)
{
SInfo t = p[j];
p[j] = p[j + 1];
p[j + 1] = t;
}
}
}
}
void Print(const SInfo* p, int nLen)
{
while (nLen--)
{
printf("%-16s%s\n", p->sName, p->sTel);
p++;
}
}
int main()
{
SInfo ar[3] = {0};
Input(ar,_countof(ar));
Sort(ar, _countof(ar));
Print(ar, _countof(ar));
return 0;
}