总结一下这次考试遇到的各种问题…
题目: 用的是codeblocks
总共6个函数,逐个分析…
错误一 inputname函数调用
name是个地址,还是首地址;name【】【】是个数据。前面加&才是地址,我会用三个例子说明
(二维数组错误)
错误代码
1.
void inputname(char dname[][16]) //1 输入一个人的名字
{
printf("请输入名字\n");
scanf("%s",dname);
}
int i,j;
inputname(Name);
//inputscore(score);
for (i=0;i<6;i++)
printf("结果%s 数字 %d\n",Name[i][16],i);/*这里只能显示第i行的第16个字母,这是最重要的错误*/
// printf("结果%s",Name[0][16]); null
puts(Name);//name的首地址 可以输出
正确代码:
for (i=0;i<6;i++)
printf("结果%s 数字 %d\n",&Name[i][0],i);
运行结果
- 会逐个输出,int数组可以用,char类型二维数组不建议用这种方法
int i,j;
inputname(Name);//Name是Name的首地址,可作为参数
//inputscore(score);
for (i=0;i<6;i++)
for(j=0;j<16;j++)
printf("结果%c 数字 %d\n",Name[i][j],i);//必须是%c
// printf("结果%s",Name[0][16]); null
puts(Name);
3.
void inputname(char dname[][16]) //形参为地址,形参中的16代表列数
{
printf("请输入名字\n");
scanf("%s",dname); //首地址
}
int i,j;
for( i=0;i<6;i++)
{
printf("第 %d 人\n",(i+1));
inputname(&Name[i][0]);//第i行的首地址,地址为参数才能正常进入函数
}
for (i=0;i<6;i++)
puts(&Name[i][0]);//一定要是地址为参数,从第0个字母开始打印
printf("结果%s",&Name[i][0]);//这句和上一句同样作用
错误二 inputescore函数
&score[2]=score+2//二者皆为地址值
二维数组行不能省略
第一次代码
void inputscore(int dscore[][8])//2 这边的[]没报错
{
for(int i=0;i<8;i++)
{
printf("请输入第%d次分数",i+1);
scanf("%d",&dscore[][i]);// 这边的【】一直报错
while(dscore[i]<60||dscore[i]>100)//
{printf("输入无效,重新输入");
scanf("%d",&dscore[i]);}
}
}
方案:将 二维数组入口参数改成一维数组
void inputscore(int dscore[8])//长度为8的一位数组
{
for(int i=0;i<8;i++)
{
printf("请输入第%d次分数",i+1);
scanf("%d",&dscore[i]);// 将数据输入这个人的分数数组
while(dscore[i]<60||dscore[i]>100)//循环限制分数的 条件,满足条件则退出循环,不满足则一直死循环
{printf("输入无效,重新输入");
scanf("%d",&dscore[i]);}
}
}
main()
{
inputscore(&score[0][0]);//将二维数组的第0行首地址作为参数,可以运行!
for (i=0;i<6;i++)
for (j=0;j<8;j++)
printf("结果%d\n",score[i][j]);}
结果:
成功
方法四
void inputscore(int dscore[][8],int num)//2 输入一个人的八个分数的数组
{
for(int i=0;i<8;i++)
{
printf("请输入第%d次分数",i+1);
scanf("%d",&dscore[num][i]);// 将数据输入这个人的分数数组
while(dscore[num][i]<60||dscore[num][i]>100)
{printf("输入无效,重新输入");
scanf("%d",&dscore[num][i]);}
}
}
inputenameandscore函数
这个函数就是调用上面两个函数
void inputnameandscore()//3
{
for(int i=0;i<6;i++)//6个人
{
printf("第 %d 人\n",(i+1));
inputname(&Name[i][0]);//第i行的首地址
inputscore(&score[i][0]);//第i行的首地址
}
}
calculatescore处理数据函数
这个函数没问题
int calculatescore(int dscore[8])
{
int i, j, t,averagenum=0;
for (i=0; i<7; i++)
for (j=0; j<7-i; j++)
if ( dscore[j] > dscore[j+1] )
{t=dscore[j]; dscore[j]=dscore[j+1]; dscore[j+1]=t; }
for(i=1;i<7;i++)
{
averagenum=averagenum+dscore[i];
}
averagenum=averagenum/6;
return averagenum;
}
最后的main函数
在这边上网查了一下
二维数组之间转换数据
#include<STDIO.H>
#include<string.h>
int main()
{
char c[4][10]={"Thank","You","Very","Much"};
char tmp[10];
strcpy(tmp, c[1]);
strcpy(c[1],c[2]);
strcpy(c[2], tmp);
printf("%s\n%s\n",c[1],c[2]);
return 0;
}
顿时明白了
int main()
{
while(1)
{
int finall[6],t,i;
char *d[16];//这个地方有没有*号运行都可以,暂时没搞懂
inputnameandscore(); //输入每个人的姓名 八次成绩
for( i=0;i<6;i++)
{
finall[i]= calculatescore(&score[i][0]); //计算每个人的最终成绩,每一行的首地址作为入口参数
}
for (int i=0; i<5; i++)
for (int j=0; j<5-i; j++)
if ( finall[j] < finall[j+1] )
{t=finall[j]; finall[j]=finall[j+1]; finall[j+1]=t;
strcpy(d,Name[j]); strcpy(Name[j],Name[j+1]); strcpy(Name[j+1],d);
//这边很重要,也是卡在这边出现问题,利用上面查到的方法,可以知道将二维数组写成
//一位数组的形式Name[j]完全可以把对应的一整行数据复制过去
}
for( i=0;i<6;i++)
{
printf("%d : %s %d \n",i+1, &Name[i][0] , finall[i] );
//输出数组要取首地址,name要加&
}
}
}
总结
- 二维数组a[3][4]第二行的首地址是一个一维数组a[1],类比于一维数组a[3]的首地址为a
- 输出二维数组每一行的正确姿势:
输出的是首地址
for (i=0;i<6;i++)
printf("结果%s 数字 %d\n",&Name[i][0],i);
- 输入二维数组每一行
输入的也是首地址
for( i=0;i<6;i++)
{
printf("第 %d 人\n",(i+1));
inputname(&Name[i][0]);//第i行的首地址,地址为参数才能正常进入函数
}
而不是这样输入
for(int i=0;i<8;i++)
{
printf("请输入第%d次分数",i+1);
scanf("%d",&dscore[][i]);// 这边的【】一直报错
}
- 调用函数
入口参数限制了数组长度为8,每一行都看作一个一维数组
void inputscore(int dscore[8])//长度为8的一位数组
main()
{
for (i=0;i<6;i++)
inputscore(&score[i][0]);//将二维数组的第0行首地址作为参数,可以运行!
for (i=0;i<6;i++)
for (j=0;j<8;j++)
printf("结果%d\n",score[i][j]);}
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char Name[6][16];
int score[6][8],k;
void inputname(char dname[][16]) //1 输入一个人的名字
{
printf("请输入这个人的名字\n");
scanf("%s",dname);
}
void inputscore(int dscore[8])//2 输入一个人的八个分数的数组
{
for(int i=0;i<8;i++)
{
printf("请输入第%d次分数",i+1);
scanf("%d",&dscore[i]);// 将数据输入这个人的分数数组
while(dscore[i]<60||dscore[i]>100)//循环限制分数的 条件,满足条件则退出循环,不满足则一直死循环
{printf("输入无效,重新输入");
scanf("%d",&dscore[i]);}
}
}
void inputnameandscore()//3
{
for(int i=0;i<6;i++)
{
printf("第 %d个人的数据:名字和八个分数\n",(i+1));
inputname(&Name[i][0]);
inputscore(&score[i][0]);
}
}
int calculatescore(int dscore[8])
{
int i, j, t,averagenum=0;
for (i=0; i<7; i++)
for (j=0; j<7-i; j++)
if ( dscore[j] > dscore[j+1] )
{t=dscore[j]; dscore[j]=dscore[j+1]; dscore[j+1]=t; }
for(i=1;i<7;i++)
{
averagenum=averagenum+dscore[i];
}
averagenum=averagenum/6;
return averagenum;
}
/* int findscore(char dname[][16])
{
int a;
for(int i=0;i<6;i++)
{
if(strcmp(dname[6][16],Name[i][16]))
a=i;
}
return calculatescore(score[a][8]);
}*/
int main()
{
while(1)
{
int finall[6],t,i;
char d[16];
inputnameandscore(); //输入每个人的姓名 八次成绩
for( i=0;i<6;i++)
{
finall[i]= calculatescore(&score[i][0]); //计算每个人的最终成绩
}
for (int i=0; i<5; i++)
for (int j=0; j<5-i; j++)
if ( finall[j] < finall[j+1] )
{t=finall[j]; finall[j]=finall[j+1]; finall[j+1]=t;
strcpy(d,Name[j]); strcpy(Name[j],Name[j+1]); strcpy(Name[j+1],d);
// d[16]=Name[j][16];Name[j][16]=Name[j+1][16];Name[j+1][16]=d[16];
}
for( i=0;i<6;i++)
{
printf("%d : %s %d \n",i+1, &Name[i][0] , finall[i] );//输出数组要取首地址
}
}
}