C语言案例1.docx
《C语言案例1.docx》由会员分享,可在线阅读,更多相关《C语言案例1.docx(19页珍藏版)》请在冰豆网上搜索。
![C语言案例1.docx](https://file1.bdocx.com/fileroot1/2023-6/22/63904736-1fe1-4751-9a79-92a4e8b78bf3/63904736-1fe1-4751-9a79-92a4e8b78bf31.gif)
C语言案例1
1设计题目
假设给定班级各科考试平均成绩的原始资料如下:
数学:
75
物理:
80
外语:
83
政治:
85
体育:
86
人数:
30
要求统计出全班学期总平均成绩以及得分最低的科目和该科目的成绩。
要求输出的结果如下:
原始信息如下:
数学:
75
物理:
80
外语:
83
政治:
85
体育:
86
人数:
30
平均成绩:
0
最低分数科目的成绩:
0
最低分数的科目:
全班各科平均成绩如下:
数学:
75
物理:
80
外语:
83
政治:
85
体育:
86
统计结果如下:
人数:
30
平均成绩:
81
最低分数科目的成绩:
75
最低分数的科目:
数学
2设计要求
实现本设计功能的方法很多,这里给出4种难易程度不同的要求,以便加深对数组和指针知识的理解。
对存放原始数据的要求如下:
(1)使用整型数组a存放数学、物理、外语、政治、体育、人数、平均成绩、最低分数科目的成绩。
(2)使用字符串数组name存放人数、平均成绩、最低分数科目的成绩、最低分数的科目。
(3)使用字符串数组MeanLow存放人数、平均成绩、最低分数科目的成绩、最低分数的科目。
1.使用数组实现
使用数组和指针数组实现。
这个实验主要是理解数值型数组和字符串数数组的异同。
2.使用分配的内存实现
要求将数组a的内容存入到分配的内存中,使用指针实现对内存的存取和计算。
3.将数组内容全部存入内存
如何为字符分配内存,并将字符数组的内容也存入所分配的内存中,使用这些指针实现设计要求。
4.使用字符指针指向字符数组
这个题目的要求超出一般的教材,但对理解指针很有用途。
3参考程序
本课程设计的4个题目是循坏渐进的,虽然有些超出教材范围,但难度不大。
为了便于理解,将给出必要的解释。
3.1使用数组实现
1.设计整数数组
从要求可知,数组a中的数学、物理、外语、政治、体育、人数已知,但平均成绩和最低分数科目的成绩为未知。
可以设计为:
inta[8]={75,80,83,85,86,30};
这种初始化方法使得到最后两个元素的值为0。
它与
inta[8]={75,80,83,85,86,30,0,0};
的作用是等效的。
2.设计字符串数组
设计如下两个字符串数组:
char*MeanLow[4]={“人数”,“平均成绩”,“最低分数科目的成绩”,“最低分数的科目”};
charname[6][5]={“数学”,“物理”,“外语”,“政治”,“体育”};
字符串数组name预留的最后一个元素位置用来存储最低分数的科目名称,
这由计算得到。
它们本身的长度都是4(一个中文占两个字符的位置),每个字符串还需要一个结束符,所以将长度设计为5。
因为人数、平均成绩、最低分数科目的成绩、最低分数的科目等字符串的长度不一样长,所以使用字符串指针数组MeanLow来实现。
3.计算
计算比较容易。
通过数组a求平均值和最小值,因为分数最大值为100,所
以可将最小值min初始化为100。
for(i=0;i<5;i++)
{
sum=sum+a[i];
if(min>a[i])min=a[i];
}
a[6]=sum/5;
a[7]=min;
根据min,从它在a中的位置,检索name中的名称,将它存入name[5]中。
对多维字符串数组name而言,只要指出左边的代号即可。
for(i=0;i<5;i++)
if(min==a[i])
{
strcpy(name[5],name[i]);
break;
}
库函数strcpy在头文件string.h中定义。
4.输出结果
输出分3次完成。
第1次输出成绩,使用数组a和name实现。
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],a[i]);
第2次输出统计结果,使用数组MeanLow和a实现。
注意数组a和MeanLow中字符串的对应关系。
for(i=0;i<53;i++)
printf(“%s%d\n”,MeanLow[i],a[i+5]);
第3次是单独输出最低分数的科目名称,它们的对应关系也是已知的。
printf(“%s:
%s\n”,MeanLow[3],name[5]);
5.完整的源程序
#include
#include
voidmain()
{
inti,sum=0,min=100;
inta[8]={75,80,83,85,86,30};
char*MeanLow[4]={“人数”,“平均成绩”,“最低分数科目的成绩”,
“最低分数的科目”};
charname[6][5]={“数学”,“物理”,“外语”,“政治”,“体育”};
printf(“原始信息如下:
\n”);
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],a[i]);
for(i=0;i<3;i++)
{
printf(“%s:
%d\n”,MeanLow[i],a[i+5]);
}
printf(“%s:
\n”,MeanLow[i]);
//计算
for(i=0;i<5;i++)
{
sum=sum+a[i];
if(min>a[i])min=a[i];
}
a[6]=sum/5;
a[7]=min;
for(i=0;i<5;i++)
if(min==a[i])
{
strcoy(name[5],name[i]);
break;
}
printf(“\n全班各科平均成绩如下:
\n”);
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],a[][i]);
printf(“\n统计结果如下:
\n”);
for(i=0;i<3;i++)
{
printf(“%s:
%d\n”;MeanLow[i],a[i+5]);
}
printf(“%s:
%s\n”,MeanLow[3],name[5]);
}
3.2使用分配的内存实现
虽然要求使用指针实现对内存内容的存取和计算,但也可以设计一个整型指针p,先用它实现计算,然后再用来申请内存。
1.使用指针和数组的关系求平均值和最小值
假设声明指针p,则可以让指针指向数组的首地址,然后使用指针下标进行
计算。
P=a;//数组名就是数组的首地址//
for(i=0;i<5;i++)
{
sum=sum+p[i];
if(min>p[i])min=p[i];
}
a[6]=sum/5;
a[7]=min;
2.申请内存空间
需要对申请的内存空间进行判别,只有确认申请无误之后,才能使用。
为了存储数组a的内容,需要申请8个存储int数据的空间。
p=(int*)malloc(8*sizeof(int));
if(p==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
3.将数组内容复制到申请的内存空间
将数组a的内容逐个复制即可。
for(i=0;i<8;i++)
**(p+i)=a[i];
4.求最低分数的科目名称
道理与上一个的设计一样,只是使用内存存储的内容进行判别而已。
for(i=0;i<5;i++)
if(min==*(p+i))
{
strcpy(name[5],name[i]);
break;
}
5.输出结果
实现方法与上节一样,只是将使用数组的数据改为使用内存中的数据,不再赘述。
6.完整的源程序
#include
#include
#include
voidmain()
{
inti,*p,min=100,sum=0;
inta[8]={75,80,83,85,86,30};
char*MeanLow[4]={“人数”,“平均成绩”,“最低分数科目的成绩”,
“最低分数的科目”};
charname[6][5]={“数学”,“物理”,“外语”,“政治”,“体育”};
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],a[i]);
for(i=0;i<3;i++)
{
printf(“%s:
%d\n”,MeanLow[i],a[i+5]);
}
//计算,复用p
P=a;
for(i=0;i<5;i++)
{
sum=sum+p[i];
if(min>p[i])min=p[i];
}
a[6]=sum/5;
a[7]=min;
//分配内存地址
P=(int*)malloc(8*sizeof(int));
if(p==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
//存储
for(i=0;i<0;i++)
*(p+i)=a[i];
//填写最低分数的科目名称
for(i=0;i<5;i++)
if(min==*(p+i))
{
strcpy(name[5],name[i]);
break;
}
printf(“\n全班各科平均成绩如下:
\n”)
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],*(p+i));
printf(“\n统计结果如下:
\n”);
for(i=0;i<3;i++)
{
printf(“%s:
%d\n”,MeanLow[i],*(p+i+5));
}
printf(“%s:
%s\n”,MeanLow[3],name[5]);
//释放内存
free(p);
}
7.小结
(1)在分配内存时,一定要判别申请是否有效,不用时需要及时释放所申请的内存空间。
(2)数组的名称就是数组的首地址
(3)数组与指针之间有一定的关系和算法。
程序中没有使用++p和--p之类的操作,可以使用这些技术改写程序。
3.3将数组内容全部存入内存
教科书中涉及的都是为字符串分配内存,也就是一维字符串数组。
如何为两维字符数组分配内存?
如何为字符串指针数组分配内存?
这就是本课程设计的内容。
1.数据存入申请内存的方法
仔细研读下面的程序及其输出结果,就会发现程序中虽然申请了内存,但并没有将信息直接存入内存。
#include
#include
voidmain()
{
inti;
chars[]=“wearehere!
”;
chars2[]=“wesdsgfdhgdhdjhd”;
char*p;
p=(char*)malloc(12);
if(p==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
printf(“p=%u,s=%u\n”,p,s);//申请的内存和数组s的首地址不同
p=s;//这里不是给申请的内存单元赋值
//下面的演示并不是从分配的内存取内容
for(i=0;i<6;i++,p++)
{
printf(“%c”,p);
}
printf(“\n%s\n”,p);
p=p-6;
printf(“p=%u,s=%u\n,p,s);//改变了p的内容
printf(“p=%s\n,p);//输出p的内容
for(i=0;i<12;i++)//改变a的内容
{
s[i]=s2[i];
}
printf(“p=%s\n”,p);//内容一样
printf(“s=%s\n”,s);
}
程序运行结果如下:
p=4390976,s=1245036
Weare
here!
p=1245036,s=1245036
p=Wearehere!
p=wesdsgfdhgdh
s=wesdsgfdhgdh
由此可见,这里是一种假象,并没有将内容存入申请的内存中。
下面的程序改正了上面程序中的错误。
#include
#include
#include
viodmain()
{
chars[]=“Wearehere!
”;
chars2[]=“wesdsgfdhgdhdjhd”;
char*p;
intI;
p=(char*)malloc(12);
if(p==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
for(i=0;i<12;i++)//将数据正确存入申请的内存区域
{
*(p+i)=s[i];
}
for(i=0;i<6;i++)
{
printf(“%c”,*p);
}
printf(“\n%s\n”,p);
p=p-6;
printf(“p=%u,s=%u\n”,p,s);
for(i=0;i<12;i++)//不会改变内存区域的数据
{
s[i]=s2[i];
}
printf(“p=%s\n”,p);
printf(“s=%s\n”,s);
free(p);
}
程序输出结果如下:
Weare
here!
p=4390976,s=1245040
p=Wearehere!
s=wersdsgfdhgdh
仔细对比这两个程序,有助于加深对申请内存的理解。
由此可见,并不能简单的使用“=”号,通过这两个字符串数组对所申请的内存区域赋值,所以也就没有必要再保存这两个字符串数组。
申请内存空间,每个字符串作为一个存储单位。
2.为字符串申请内存空间
对于原来由字符串数组name提供的数据,可以设计一个字符指针数组,为每个指针数组元素申请一个存储空间,再将相应的字符串存入该内存区域。
同理,也设计一个字符串指针数组,用字符串指针数组为它们申请内存空间,存放原来由MeanLow提供的字符串。
为了便于对照,下面给出程序变量生命部分的完整内容:
3.用pcn申请内存空间
使用循环语句申请6处空间,然后再逐个为前5处区域赋值。
//为科目名称申请内存
for(i=0;i<6;i++)
{
pen[i]=(char*)malloc(4*sizeof*(char));
if(pcn[i]==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
}
//赋值
strcpy(pcn[0],“数学”);
strcpy(pcn[1],“物理”);
strcpy(pcn[2],“外语”);
strcpy(pcn[3],“政治”);
strcpy(pcn[4],“体育”);
4.用pcm申请内存空间
为了简单起见,为各个元素申请等长的存储空间。
//申请内存
for(i=0;i<4;i++)
{
pcm[i]=(char*)malloc(20);
if(pcm[i]==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
}
//赋值
strcpy(pcm[0],“人数”);
strcpy(pcm[1],“平均成绩”);
strcpy(pcm[2],“最低分数科目的成绩”);
strcpy(pcm[3],“最低分数的科目”);
5.求最低分数的科目名称
//填写最低分数的科目名称
for(i=0;i<5;i++)
if(min==*(p+i))
{
strcpy(pcn[5],pcn[i]);
break;
}
6.完整的源程序
下面是完整的程序清单,为了保证输出结果相同,调整了部分程序的位置。
#include
#include
#include
viodmain()
{
intI,*p,min=100,sum=0;
inta[8]={75,80,83,85,86,30};
char*pcn[6],*pcm[4];
//为科目名称申请内存
for(i=0;i<6;i++)
{
pcn[i]=(char*)malloc(4*sizeof(char));
if(pcn[i]==NULL)
{
printf(“内存分配错误“);
exit
(1);
}
}
//赋值
strcpy(pcn[0],“数学”);
strcpy(pcn[1],“物理”);
strcpy(pcn[2],“外语”);
strcpy(pcn[3],“政治”);
strcpy(pcn[4],“体育”);
printf(“%s:
%d\n”,pcn[i],*(p+i));
3.完整的源程序
#include
#include
voidmain()
{
intI,sum=0,min=100.*p;
char**pcm;
char(*pcn)[5];
inta[8]={75,80,83,85,86,30};
char*MeanLow[4]={“人数”,“平均成绩”,最低分数科目的成绩”,“最低分数的科目”};
charname[5][5]={“数学”,“物理”,“外语”,“政治”,“体育”};
for(i=0;i<5;i++)
printf(“%s:
%d\n”,name[i],a[i]);
for(i=0;i<3;i++)
{
printf(“%s:
%d\n”,MeanLow[i],a[i+5]);
}
printf(“%s:
\n”,MeanLow[i]);
//计算
p=a;
for(i=0;i<5;i++)
{
sum=sum+p[i];
if(min>p[i])min=p[i];
}
a[6]=sum/5;
a[7]=min;
p=(int*)malloc(8*sizef(int));
if(p==NULL)
{
printf(“内存分配错误”);
exit
(1);
}
pcm=MeanLow;
pcn=name;
//输出信息
printf(“\n全班各科平均成绩如下:
\n”);
for(i=0;i<8;i++)
*(p+i)=a[i];
for(i=0;i<5;i++)
{
printf(“%s:
%d\n”,pcm[i],*(p+i+5));
}
free(p);
}
3.4评价标准
不一定要求做完这些课题设计,可以灵活机动。
但不管做多少,置针于数组的关系不因该出现错误,指针申请内存也是判分的重点。
如果在这两方面出现一个错误,都不能超过80分。
如果两者均错,亦不及格处理。
全部作对,85-88分。
有创意的加分。