修改程序清单10.7的rain.c程序,用指针进行计算(仍然要声明并初始化数组)。
# include
# define MONTHS 12
# define YEARS 5
int main(void){
const float rain[YEARS][MONTHS] ={
{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
};
const float (*r)[MONTHS] = rain;
int year;
int month;
float subtot,total;
printf("YEAR RAINFALL(inches)\n");
for(year=0, total = 0;year<YEARS;++year){
for(month=0, subtot =0;month<MONTHS;++month)
subtot += r[year][month];
printf("%5d %15.1f\n",2010+year,subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n", total/YEARS);
printf("MONTHLY AVERAGES: \n\n");
printf("Jan\tFeb\tMar\tApr\tMay\tJun\tJul\tAug\tSep\tOct\tNov\tDec\n");
for(month = 0;month < MONTHS; ++month){
for(year = 0,subtot=0;year<YEARS;++year)
subtot += r[year][month];
printf("%.1f\t",subtot/YEARS);
}
printf("\n");
return 0;
}
编写一个程序,初始化一个double类型的数组,然后把该数组的内容拷贝到3个其他数组中(在main()中声明这4个数组)。使用带数组表示法的函数进行第1份拷贝。使用带指针表示法和指针递增的函数进行第2份拷贝。把目标数名、源数组名和待拷贝的元素格式作为前两个函数的参数,第3个函数以目标数组名、源数组名和指向源数组最后一个元素后面的元素指针。也就是说,给定以下声明,则函数 调用如下所示:
# include
void copy_arr(double t[], const double* s, int n){
for(int i=0;i<n;++i){
t[i] = s[i];
}
}
void copy_ptr(double* t, const double *s, int n){
double *m = t;
while(m<t+5){
*m++ = *s++;
}
}
void copy_ptrs(double* t, const double *s, const double* e){
while(s<e){
*t++ = *s++;
}
}
int main(void){
double source[5] = {1.1,2.2,3.3,4.4,5.5};
double target1[5];
double target2[5];
double target3[5];
copy_arr(target1, source,5);
copy_ptr(target2, source,5);
copy_ptrs(target3, source,source+5);
printf("数组模式:\n");
for(int i=0;i<5;++i)
printf("%.2lf\t", target1[i]);
printf("\n指针模式:\n");
for(int i=0;i<5;++i)printf("%.2lf\t", target2[i]);
printf("\n多指针模式:\n");
for(int i=0;i<5;++i)printf("%.2lf\t", target3[i]);
printf("\n");
return 0;
}
编写一个函数,返回存储在int类型数组中的最大值,并在一个简单的程序中测试该函数。
# include
int find_max(const int* s, int n){
int tmp = s[0];
for(int i=1;i<n;++i){
tmp = tmp>s[i]?tmp:s[i];
}
return tmp;
}
int main(void){
int source[5] = {1,2,3,4,5};
printf("数字元素分别为:");
for(int i=0;i<5;++i)
printf("%d\t", source[i]);
printf("\n最大值为:%d\n", find_max(source,5));
return 0;
}
编写一个函数,返回存储在double类型数组中最大值的下标,并在一个简单的程序中测试该函数。
# include
int find_max(const double* s, int n){
int tmp = s[0];
int id = 0;
for(int i=1;i<n;++i){
if(tmp<s[i]){
tmp = s[i];
id = i;
}
}
return id;
}
int main(void){
double source[5] = {1.0,2.0,3.0,4.0,5.0};
printf("数字元素分别为:");
for(int i=0;i<5;++i)
printf("%.2lf\t", source[i]);
printf("\n最大值id为:%d\n", find_max(source,5));
return 0;
}
编写一个函数,返回存储在double类型数组中最大值和最小值的差值,并在一个简单的程序中测试该函数。
# include
double find_max(const double* s, int n){
int mx = s[0];
int mn = s[0];
int id = 0;
for(int i=1;i<n;++i){
mx = mx>s[i]?mx:s[i];
mn = mn<s[i]?mn:s[i];
}
return mx-mn;
}
int main(void){
double source[5] = {1.0,2.0,3.0,4.0,5.0};
printf("数字元素分别为:");
for(int i=0;i<5;++i)
printf("%.2lf\t", source[i]);
printf("\n最大值与最小值的差值为:%.2lf\n", find_max(source,5));
return 0;
}
编写一个程序,把double类型数组中的数据倒序排列,并在一个简单的程序中测试该程序
# include
void find_max(double* s, int n){
double t;
for(int i=0, j=n-1;i<j;++i,--j){
t = s[i];
s[i] = s[j];
s[j] =t;
}
}
int main(void){
double source[5] = {1.0,2.0,3.0,4.0,5.0};
printf("数字元素分别为:");
for(int i=0;i<5;++i)
printf("%.2lf\t", source[i]);
find_max(source,5);
printf("\n排序后为:");
for(int i=0;i<5;++i)
printf("%.2lf\t", source[i]);
return 0;
}
编写一个程序,初始化一个double类型的二维数组,使用编程练习2中的一个拷贝函数把该数组中的数据拷贝至另一个二维数组中(因为二维数组是数组的数组,所以可以使用处理一维数组的拷贝函数来处理数组中的每个子数组)。
# include
void copy_ptr(const double* s, double *t, int n){
for(int i=0;i<n;++i) *t++ = *s++;
}
int main(void){
double source[][5] = {
{1.0,2.0,3.0,4.0,5.0},
{6.0,7.0,8.0,9.0,10.0}
};
double t[2][5];
for(int i=0;i<2;++i) copy_ptr(source[i],t[i],5);
printf("数字元素分别为:\n");
for(int i=0;i<2;++i){
for(int j=0;j<5;++j)printf("%.2lf\t", t[i][j]);
printf("\n");
}
return 0;
}
使用编程练习2中的拷贝函数,把一个内含7个元素的数组中第3~5个元素拷贝至内含3个元素的数组中。该函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,只需要是数组元素的地址和待处理元素的个数)。
# include
void copy_ptr(const double* s, double *t, int n){
for(int i=0;i<n;++i) *t++ = *s++;
}
int main(void){
double source[5] = {1.0,2.0,3.0,4.0,5.0};
double t[3];
copy_ptr(source+2,t,3);
printf("数字元素分别为:\n");
for(int j=0;j<3;++j)printf("%.2lf\t", t[j]);
printf("\n");
return 0;
}
编写一个程序,初始化一个double类型的35二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要 编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意NM(如果编译器不支持变长数组,就使用C函数处理N*5的数组)。
# include
void copy_ptr(int r,int c, const double s[r][c], double t[r][c]){
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
t[i][j] = s[i][j];
}
void dis(int r, int c, const double s[r][c]){
for(int i=0;i<r;++i){
for(int j=0;j<c;++j)
printf("%.2lf\t", s[i][j]);
printf("\n");
}
}
int main(void){
double source[3][5];
double t[3][5];
for(int i=0;i<3;++i)
for(int j=0;j<5;++j)
source[i][j] = i+j;
copy_ptr(3,5,source,t);
printf("\n源数组元素分别为:\n");
dis(3,5,source);
printf("拷贝后的数组元素分别为:\n");
dis(3,5,t);
printf("\n");
return 0;
}
编写一个函数,把两个数组中相对应的元素相加,然后把结果储存到第3个数组中。也就是说,如果数组1中包含的值是2、4、5、8,数组2中包含的值是1、0、4、6,那么该函数把3、4、9、14赋给第三个数组。函数接受3个数组名和一个数组大小。在一个简单的程序中测试该函数。
# include
void cal(int *t, const int *a, const int *b,int n){
for(int i=0;i<n;++i)
t[i] = a[i]+b[i];
}
void dis(const int *s, int n){
for(int i=0;i<n;++i)printf("%d\t", s[i]);
printf("\n");
}
int main(void){
int a[4]={2,4,5,8};
int b[4]={1,0,4,6};
int t[4];
printf("\n数组a元素分别为:\n");
dis(a,4);
printf("数组b元素分别为:\n");
dis(b,4);
cal(t,a,b,4);
printf("数组a与数组b之和的数组元素分别为:\n");
dis(t,4);
printf("\n");
return 0;
}
编写一个程序,声明一个int类型的3*5二维数组,并用合适的值初始化它。该程序打印数组中的值,然后各值翻倍(即是原来的2倍),便是出各个元素的新值。编写一个函数显示数组的内容,再编写一个函数把各元素的翻倍。这两个函数都以函数名和行数作为参数。
# include
void cal(int (*t)[5],int n){
for(int i=0;i<n;++i)
for(int j=0;j<5;++j)
t[i][j] *= 2;
}
void dis(const int (*s)[5], int n){
for(int i=0;i<n;++i){
for(int j=0;j<5;++j)printf("%d\t", s[i][j]);
printf("\n");
}
}
int main(void){
int s[3][5];
for(int i=0;i<3;++i)
for(int j=0;j<5;++j)
s[i][j] = i+j;
printf("\n原数组元素分别为:\n");
dis(s,3);
cal(s,3);
printf("2倍后的数组元素分别为:\n");
dis(s,3);
printf("\n");
return 0;
}
重新编写程序清单10.7的rain.c程序,把main()中的主要任务都改成用函数来完成。
# include
# define MONTHS 12
# define YEARS 5
void rain_year(const double r[][MONTHS]){
int year;
int month;
float subtot,total;
printf("YEAR RAINFALL(inches)\n");
for(year=0, total = 0;year<YEARS;++year){
for(month=0, subtot =0;month<MONTHS;++month)
subtot += r[year][month];
printf("%5d %15.1f\n",2010+year,subtot);
total += subtot;
}
printf("\nThe yearly average is %.1f inches.\n\n", total/YEARS);
}
void rain_mon(const double r[][MONTHS]){
int year;
int month;
float subtot,total;
printf("MONTHLY AVERAGES: \n\n");
printf("Jan\tFeb\tMar\tApr\tMay\tJun\tJul\tAug\tSep\tOct\tNov\tDec\n");
for(month = 0;month < MONTHS; ++month){
for(year = 0,subtot=0;year<YEARS;++year)
subtot += r[year][month];
printf("%.1f\t",subtot/YEARS);
}
printf("\n");
}
int main(void){
const double rain[YEARS][MONTHS] ={
{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
{8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
{9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
{7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
{7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
};
const double (*r)[MONTHS] = rain;
int year;
int month;
float subtot,total;
rain_year(r);
rain_mon(r);
return 0;
}
编写一个程序,提示用户输入3组数,每组数包含5个double类型的数(假设用户都正确地响应,不会输入非数值数据)。该程序应完成下列任务。
a. 把用户输入从数据存储到3*5的数组中。
b. 计算每组(5个)数据的平均值
c. 计算所有数据的平均值
d. 找出这15个数据中的最大值
e. 打印结果
每个任务都要用单独的函数来完成(使用传统C处理数组的方式)。完成任务b,编写一个计算并返回一维数组平均值的函数,利用循环调用函数3次。对于处理其他任务的函数,应该把整个数组作为参数,完成任务c和d的函数应该把结果返回主调函数。
# include
void get_data(double (*d)[5], int n){
printf("\n请输入15个小数: ");
for(int i=0;i<n;++i){
for(int j=0;j<5;++j)
scanf("%lf", d[i]+j);
}
}
double avg_data(const double *s, int n){
double t = 0;
for(int i=0;i<n;++i) t+=s[i];
return t/n;
}
double avg_total(const double (*s)[5], int n){
double t = 0;
for(int i=0;i<n;++i)
for(int j=0;j<5;++j)
t+=s[i][j];
return t/n;
}
double max_total(const double (*s)[5], int n){
double t = s[0][0];
for(int i=0;i<n;++i)
for(int j=0;j<5;++j)
t= t>s[i][j]?t:s[i][j];
return t;
}
int main(void){
double data[3][5];
get_data(data,3);
printf("每组数据的平均值为: ");
for(int i=0;i<3;++i) printf("%.2lf\t", avg_data(data[i],5));
printf("\n所有数据的平均值为%.2lf\n", avg_total(data,3));
printf("\n所有数据的最大值值为%.2lf\n", max_total(data,3));
return 0;
}
输入数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
以变长数组作为函数形参,完成变长联系13.
# include
void get_data(int r, int c, double d[r][c]){
printf("\n请输入15个小数: ");
for(int i=0;i<r;++i){
for(int j=0;j<c;++j)
scanf("%lf", d[i]+j);
}
}
double avg_data( int n, const double s[n]){
double t = 0;
for(int i=0;i<n;++i) t+=s[i];
return t/n;
}
double avg_total(int r, int c, double s[r][c]){
double t = 0;
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
t+=s[i][j];
return t/r/c;
}
double max_total(int r, int c, double s[r][c]){
double t = s[0][0];
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
t= t>s[i][j]?t:s[i][j];
return t;
}
int main(void){
double data[3][5];
get_data(3,5,data);
printf("每组数据的平均值为: ");
for(int i=0;i<3;++i) printf("%.2lf\t", avg_data(5, data[i]));
printf("\n所有数据的平均值为%.2lf\n", avg_total(3,5,data));
printf("\n所有数据的最大值值为%.2lf\n", max_total(3,5,data));
return 0;
}
输入数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15