文章目录

  • 一、结构体指针
  • 二、结构体数组
  • 三、练习有关结构体例子
  • 1、当输入一个年月日后, 输出该日是这一年的第几天。
  • 2、定义一个普通结构体包含年月日,在main函数中定义一个结构体对象
  • 3、键盘输入5个用户的数据,包括:姓名和电话号码。要求按姓名排序后输出全部数据。
  • 4、从键盘上输入10个学生的数据,包括:学号、姓名、三门课的成绩。



一、结构体指针

通过定义好的结构体“模型”不但可以定义对象,也可以定义用于指向对象的就结构体指针变量,当然还可以定义结构体对象的数组。
如果要使用结构体指针变量访问对象的话,首先要使用*符号获得对象的类型,再使用.符号去访问对象内的成员数据。

//[例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;
}