沙河口区实验小学三年五班有54名学生,期末考试科目为数学、语文、英语,现需要统计该班学生成绩,要求:按学号输入学生各科成绩,输出学生的学号、总分、平均分,请选择合适的程序设计语言完成。(学号为1-54)
上代码
#include <stdio.h>
int main() {
int scores[54][3]; // 存储54个学生3门科目的成绩
for (int i = 1; i <= 54; i++) { // 学号1-54
printf("请输入学号%d的数学成绩: ", i);
scanf("%d", &scores[i-1][0]);
printf("请输入学号%d的语文成绩: ", i);
scanf("%d", &scores[i-1][1]);
printf("请输入学号%d的英语成绩: ", i);
scanf("%d", &scores[i-1][2]);
}
for (int i = 1; i <= 54; i++) {
int sum = 0;
for (int j = 0; j < 3; j++) {
sum += scores[i-1][j]; // 求总分
}
float avg = sum / 3.0; // 求平均分
printf("学号%d的总分是%d,平均分是%.2f\n", i, sum, avg);
}
}
scores = {} # 存储学生成绩,key是学号,value是各科成绩列表
for i in range(1, 55): # 学号1-54
math = int(input(f'请输入学号{i}的数学成绩: '))
chinese = int(input(f'请输入学号{i}的语文成绩: '))
english = int(input(f'请输入学号{i}的英语成绩: '))
scores[i] = [math, chinese, english] # 存储各科成绩
for i in range(1, 55):
sum_score = sum(scores[i]) # 求总分
avg_score = sum_score / 3 # 求平均分
print(f'学号{i}的总分是{sum_score},平均分是{avg_score}') # 输出学号、总分、平均分
int a[5], *p; // a存放了数组的首地址
p=a; // 数组首地址赋给p
p++; // 向下移动4个字节
指针与数组名都是地址,因此可以混合使用访问数组元素。
int *pa=a; 和 int *pa=&a[0];(// a的首地址)两者完全等价!
pa和a可以混合使用的图片说明,前面一列是地址(a和pa都表示地址),加*表示里面的元素。指针还可以移动,如图2。
a[i]
pa[i] // pa和a可以混合使用,pa和a都表示首地址
*(a+i) // 表示地址的前面加一个*,就代表该地址里面的元素
*(pa+i) // pa和a混合使用
&a[i] // 加取地址符号就表示地址
&pa[i]
(a+i) // *和&互为逆运算,因此前面没有了符号
(pa+i)
注意(区别):
数组名是指针常量,不是指针变量,因此不能给数组名赋值!但指针可以。例如:pa=pa+1这是可以的,但是不能有a=a+1这种操作,任何修改数组名的操作都是错误的!
程序1:用指针访问数组,计算数组的元素之和。
/* 用指针访问数组,计算数组的元素之和 */
#include<stdio.h>
#include<stdlib.h>
int main()
{
int iarray[10]={0,2,4,6,8,10,12,14,16,18},*p=iarray;
int i,sum=0;
for(i=0;i<10;i++)
{
sum+=*p;
p++; // sum+=*iarray; iarray++是错误的!数组名不能进行自增操作!
}
printf("sum is %d\n",sum);
system("pause");
return 0;
}
注意:p++并不是简单的加1,而是加了它的基类型所占的字节数,即移动了sizeof(int)=4个字节。sizeof()宏定义可获取所占字节数。
指针快速访问数组,但也只能逐个处理,不能一次性处理所有元素。
for(i=0;i<4;i++)
{
scanf_s(“%d”,&a[i]); // 输入
printf(“%d”,a[i]); // 输出
}
for(p=a;p<(a+4);p++)
{
scanf_s(“%d”,p); // 用指针输入,p本身是个地址,不用再加取地址符号
printf(“%d”,*p); // 用指针输出
}
void main() // 定义和初始化
{
int sum1,sum2,sum3,sum4,sum5;
int iarray[]={1,3,2,5,2,56,34,2,7,60};
int *iptr;
int size,n;
sum1=sum2=sum3=sum4=sum5=0;
size=sizeof(iarray)/sizeof(*iarray);
}
第一种:数组名和下标的方式
for(n=0;n<size;n++)
{
sum1+=iarray[n];
}
第二种:通过移动指针,逐个元素的访问
iptr=iarray;
for(n=0;n<size;n++)
{
sum2+=*iptr;
}
第三种:通过指针和间接地址的方式,访问数组的所有元素
iptr=iarray;
for(n=0;n<size;n++)
{
sum3+=*(iptr+n);
}
第四种:通过指针,引用下标的方式,按照数组的方式访问数组所有元素
iptr=iarray;
for(n=0;n<size;n++)
{
sum4+=iptr[n];
}
第五种:通过数组名加偏移量的方式
for(n=0;n<size;n++)
{
sum5+=*(iarray+n);
}
第一种:通过数组名获得首地址(数组名)
第二种:通过数组的第一个元素来获得首地址(首个元素地址),这里指针变量p是通过数组名获得指向数组a的第一个元素。
第一种:直接访问(数组名+下标变量,如a[1])
第二种:指针加偏移量的间接地址访问,如*(p+i)
第三种:用数组名做地址值(指针值)的间接地址访问,如与a[i]等价的语句为*(a+i)
第四种:将指针变量看做数组名,再加下标变量,如p[i]。
总结:
数组名是表示数组元素的连续空间的首地址,可以看做一个“常量”指针,它的值不能被修改,即不能修改其指向。数组元素可通过 下标法来引用,也可通过指针来引用,还可以混合使用。同样地,指针也可以当做一个数组名来使用。(方便、灵活、易混淆、易出错)
#include<bits/stdc++.h>
using namespace std;
struct node
{
int yw,ss,yy,zf;
}a[100005];
int main(){
for(int i=1;i<=54;i++)
{
cin>>a[i].yw>>a[i].ss>>a[i].yy;
a[i].zf=a[i].yw+a[i].ss+a[i].yy;
}
for(int i=1;i<=54;i++)
{
printf("%d %d %.1lf\n",i,a[i].zf,a[i].zf/3);
}
return 0;
}