C 语言编程练习都为本人学习时的编写代码记录或学习笔记,若有不当之处欢迎指正,感激不尽。(其中编程设计也可有其他设计方案,本人目前仅在学习中,所以仅为个人学习记录,仅供参考。)
1.修改程序清单 10.7 中的程序 rain,使它不使用数组下标,而是使用指针进行计算(程序中仍然需要声明并初始化数组)。
/* rain.c -- find yearly totals, yearly average, and monthly average for several years of rainfall data */
#include
#define MONTHS 12 /* number of months in a year */
#define YEARS 5 /* number of years of data */
int main(void)
{
/* initializing rainfall data for 2000 - 2004 */
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},
};
int year, month;
float subtot, total;
printf(" YEAR RAINFALL (inches)\n");
for(year = 0, total = 0; year < YEARS; year++) {
/* for each year, sum rainfall for each month */
for(month = 0, subtot = 0; month < MONTHS; month++)
subtot += *(*(rain+year) + month); /* use pointer */
printf("%5d %15.1f\n", 2000 + year, subtot);
total += subtot; /* total for all years */
}
printf("\nThe yearly average is %.1f inches.\n\n", total/YEARS);
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct ");
printf("Nov Dec\n");
for(month = 0; month < MONTHS; month++) {
/* for each month, sum rainfall over years */
for(year = 0, subtot = 0; year < YEARS; year++)
subtot += *(*(rain+year) + month); /* use pointer */
printf("%4.1f ", subtot/YEARS);
}
printf("\n");
return 0;
}
2.编写一个程序,初始化一个 double 数组,然后把数组内容复制到另外两个数组(3 个数组都需要在主程序中声明)。制作第一份拷贝的函数使用数组符号。制作第二份拷贝的函数使用指针符号,并使用指针的增量操作。把目标数组名和要复制的元素数目做为参数传递给函数。也就是说,如果给定了下列声明,函数调用应该如下面所示:
double source [5]={1.1, 2.2, 3.3, 4.4, 5.5};
double targetl[5];
double target2 [5];
copy_arr (source, target1, 5);
copy_ptr (source, target1,5);
#include
void copy_arr(double [],double [], int );
void copy_ptr(double *,double *, int );
int main(void)
{
double source[] = {1.1,2.2,3.3,4.4,5.5};
double target1[5];
double target2[5];
printf("source\t\ttarget1\n");
copy_arr(source, target1, 5);
printf("\n");
printf("source\t\ttarget2\n");
copy_ptr(source, target2, 5);
return 0;
}
/* use array notaion */
void copy_arr(double a[], double b[], int n)
{
int i;
for(i = 0; i < n; i++) {
b[i] = a[i];
printf("%.1lf\t\t%.1lf\n",a[i], b[i]);
}
}
/* use pointer notaion and pointer incrementing */
void copy_ptr(double * p1, double * p2, int n)
{
int i;
for(i = 0; i < n; i++) {
* (p2 + i) = *(p1 + i);
printf("%.1lf\t\t%.1lf\n", *(p1 + i), *(p2 + i));
}
}
3.编写一个函数,返回一个 int 数组中存储的最大数值,并在一个简单的程序中测试这个函数。
#include
#define ELT 6
int ret_max(int [], int );
int main(void)
{
int arr[ELT] = {3, 2, 1, 8, 4, 7};
int i;
printf("arr[ELT] = {3, 2, 1, 8, 4, 7};\n");
printf("max = %d\n", ret_max(arr , ELT));
return 0;
}
int ret_max(int a[], int n)
{
int i, max;
for(i = 1, max = a[0]; i < n; i++) {
if(max < a[i])
max = a[i];
}
return max;
}
4.编写一个函数,返回一个 double 数组中存储的最大数值的索引,并在一个简单程序中测试这个函数。
#include
#define ELT 6
int ret_index(double [], int );
int main(void)
{
double arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};
printf("arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};\n");
printf("max_index = %d\n", ret_index(arr , ELT));
return 0;
}
int ret_index(double a[], int n)
{
int i, max;
for(i = 1, max = 0; i < n; i++) {
if(a[max] < a[i])
max = i;
}
return max;
}
5.编写一个函数 , 返回一个 double 数组中最大的和最小的数之间的差值 , 并在一个简单的程序中测试这个函数。
#include
#define ELT 6
double ret_sub(double [], int );
int main(void)
{
double arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};
printf("arr[ELT] = {3.3, 2.2, 1.1, 8.8, 4.4, 7.7};\n");
printf("max - min = %.1lf\n", ret_sub(arr , ELT));
return 0;
}
double ret_sub(double a[], int n)
{
int i, max, min;
for(i = 1, max = min = 0; i < n; i++) {
if(a[max] < a[i])
max = i;
if(a[min] > a[i])
min = i;
}
return (a[max] - a[min]);
}
6.编写一个程序,初始化一个二维 double 数组,并利用练习 2 中的任一函数来把这个数组复制到另一个二维数组(因为二维数组是数组的数组,所以可以使用处理一维数组的函数来复制数组的每个子数组)。
#include
#define ROWS 2
#define COLS 3
void copy_2d(double [][COLS],double [][COLS], int );
void copy_arr(double [],double [], int );
int main(void)
{
int i, j;
double source[ROWS][COLS] = {1.1,2.2,3.3,4.4,5.5,6.6};
double target1[ROWS][COLS];
copy_2d(source, target1, ROWS);
printf("source\t\ttarget1\n");
for( i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++)
printf("%g\t\t%g\n",source[i][j],target1[i][j]);
}
return 0;
}
void copy_2d(double (*source)[COLS], double target1[][COLS], int n)
{
int i;
for(i = 0; i < n; i++) {
copy_arr(*(source+i), target1[i], COLS);
}
}
void copy_arr(double a[], double b[], int n)
{
int i;
for(i = 0; i < n; i++)
b[i] = a[i];
}
7.利用练习 2 中的复制函数,把—个包含 7 个元素的数组内第 3 到第 5 元素复制到一个包含 3 个元素的数组中。函数本身不需要修改,只需要选择合适的实际参数(实际参数不需要是数组名和数组大小,而只须是数组元素的地址和需要复制的元素数目)。
#include
void copy_arr(double [],double [], int );
void copy_ptr(double *,double *, int );
int main(void)
{
double source[] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7};
double target1[3];
double target2[3];
printf("source\t\t1.1 2.2 3.3 4.4 5.5 6.6 7.7\n");
copy_arr(source+2, target1, 3);
printf("\n");
printf("source\t\t1.1 2.2 3.3 4.4 5.5 6.6 7.7\n");
copy_ptr(source+2, target2, 3);
return 0;
}
/* use array notaion */
void copy_arr(double a[], double b[], int n)
{
int i;
printf("target1:\t");
for(i = 0; i < n; i++) {
b[i] = a[i];
printf("%.1lf ", b[i]);
}
printf("\n");
}
/* use pointer notaion and pointer incrementing */
void copy_ptr(double * p1, double * p2, int n)
{
int i ;
printf("target2:\t");
for(i = 0; i < n; i++) {
* (p2 + i) = *(p1 + i);
printf("%.1lf ", *(p2 + i));
}
printf("\n");
}
8.编写一个程序,初始化一个 3x5 的二维 double 数组,并利用一个基于变长数组的函数把该数组复制到另一个二维数组。还要编写。个基于变长数组的函数来显示两个数组的内容。这两个函数应该能够处理任意的 NxM 数组(如果没有可以支持变长数组的编译器,就使用传统 C 中处理 Nx5 数组的函数方法)。
#include
#define ROWS 3
#define COLS 5
/* r-rows, c-cols, sou-source, tar-target */
void vla_copy(int r, int c, double sou[r][c], double tar[r][c]);
void vla_show(int r, int c, double ptr[r][c]);
int main(void)
{
double sou[ROWS][COLS] = {
{1,1,1,1,1},
{2,2,2,2,2},
{3,3,3,3,3}
};
double tar[ROWS][COLS];
vla_copy(ROWS, COLS, sou, tar);
printf("source:\n");
vla_show(ROWS, COLS, sou);
printf("target:\n");
vla_show(ROWS, COLS, tar);
return 0;
}
void vla_copy(int r, int c, double sou[r][c], double tar[r][c])
{
int i, j;
for(i = 0; i < r; i++) {
for(j = 0; j < c; j++)
tar[i][j] = sou[i][j];
}
}
void vla_show(int r, int c, double ptr[r][c])
{
int i, j;
for(i = 0; i < r; i++) {
for(j = 0; j < c; j++)
printf("%.1lf ", ptr[i][j]);
printf("\n");
}
}
9.编写一个函数,把两个数组内的相应元素相加,结果存储到第 3 个数组内。也就是说,如果数组 1具有值 2、4、5、8,数组 2 具有值 1、0、4、6,则函数对数组 3 赋值为 3、4、9、140 函数的参数包括 3 个数组名和数组大小。并在一个简单的程序中测试这个函数。
#include
#define NUM 4
/* 根据题中说明以整型示例 */
void add(int [], int [], int [], int );
int main(void)
{
int i;
int one[] = {2, 4, 5, 8};
int two[] = {1, 0, 4, 6};
int three[NUM];
add(one, two, three, NUM);
printf("one\ttwo\tthree\n");
for(i = 0; i < NUM; i++) {
printf("%d\t%d\t%d\n",one[i], two[i], three[i]);
}
return 0;
}
void add(int a[], int b[], int c[], int n)
{
int i;
for(i = 0; i < NUM; i++)
c[i] = a[i] + b[i];
}
10.编写…个程序,声明一个 3x5 的数组并初始化,具体数值可以随意。程序打印出数值,然后数值翻 1 番,接着再次打印出新值。编写一个函数来显示数组的内容,再编写另一个函数执行翻倍功能。数组名和数组行数作为参数由程序传递给函数。
#include
#define ROWS 3
#define COLS 5
void show(int [][COLS], int );
void twice(int [][COLS], int );
int main(void)
{
int x1[][5] = {
{1,1,1,1,1},
{2,2,2,2,2},
{3,3,3,3,3}
};
printf("before:\n");
show(x1, ROWS);
twice(x1, ROWS);
printf("after:\n");
show(x1, ROWS);
return 0;
}
void show(int a1[][COLS], int row)
{
int i, j;
for(i = 0; i < row; i++) {
for(j = 0; j < 5; j++)
printf("\t%d ", a1[i][j]);
printf("\n");
}
}
void twice(int a1[][COLS], int row)
{
int i, j;
for(i = 0; i < row; i++) {
for(j = 0; j < COLS; j++)
a1[i][j] = 2 * a1[i][j];
}
}
11.重写程序清单 10.7 的程序 rain,main()中的主要功能改为由函数来执行。
/* rain.c -- find yearly totals, yearly average, and monthly average for several years of rainfall data */
#include
#define MONTHS 12 /* number of months in a year */
#define YEARS 5 /* number of years of data */
void show(float rain[][MONTHS], int years);
int main(void)
{
/* initializing rainfall data for 2000 - 2004 */
float rain[][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},
};
show(rain, YEARS);
return 0;
}
void show(float rain[][MONTHS], int years)
{
int year, month;
float subtot, total;
printf(" YEAR RAINFALL (inches)\n");
for(year = 0, total = 0; year < YEARS; year++) {
/* for each year, sum rainfall for each month */
for(month = 0, subtot = 0; month < MONTHS; month++)
subtot += rain[year][month];
printf("%5d %15.1f\n", 2000 + year, subtot);
total += subtot; /* total for all years */
}
printf("\nThe yearly average is %.1f inches.\n\n", total/YEARS);
printf("MONTHLY AVERAGES:\n\n");
printf(" Jan Feb Mar Apr May Jun Jul Aug Sep Oct ");
printf("Nov Dec\n");
for(month = 0; month < MONTHS; month++) {
/* for each month, sum rainfall over years */
for(year = 0, subtot = 0; year < YEARS; year++)
subtot += rain[year][month];
printf("%4.1f ", subtot/YEARS);
}
printf("\n");
}
12.编写一个程序,提示用户输入 3 个数集,每个数集包括 5 个 double 值。程序应当实现下列所有功能:
a.把输入信息存储到一个 3x5 的数组中
b.计算出每个数集(包含 5 个数值)的平均值
c. 计算所有数值的平均数
d.找出这 15 个数中的最大值
e. 打印出结果
每个任务需要用一个单独的函数来实现(使用传统 C 处理数组的方法)。对于任务 b,需要编写计算并返回一维数组平均值的函数,循环 3 次调用该函数来实现任务 b。对于其他任务,函数应当把整个数组做为参数,并且完成任务 c 和 d 的函数应该向它的调用函数返回答案。
#include
#define ROWS 3
#define COLS 5
void storage(double arr[ROWS][COLS]); /* task a */
void row_aver(double *arr, int ); /* task b */
double all_aver(double arr[ROWS][COLS]); /* task c */
double max(double arr[ROWS][COLS]); /* task d */
void print(double arr[ROWS][COLS]); /* task e */
int main(void)
{
int i;
double arr[ROWS][COLS];
storage(arr);
for(i = 0; i < ROWS; i++) {
row_aver(arr[i], COLS);
}
printf("all_average = %.2lf\n",all_aver(arr));
printf("max = %.2lf\n", max(arr));
print(arr);
return 0;
}
void storage(double arr[ROWS][COLS]) /* task a */
{
int i, j;
printf("Please input 15 double(3x5).\n");
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++)
scanf("%lf", &arr[i][j]);
}
}
void row_aver(double * arr, int rows) /* task b */
{
int i;
double sum = 0;
for(i = 0; i < rows; i++)
sum += arr[i];
printf("row_average = %.2lf\n", sum / (1.0*rows));
}
double all_aver(double arr[ROWS][COLS]) /* task c */
{
int i, j;
double total = 0;
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++)
total += arr[i][j];
}
return (total / (1.0*ROWS*COLS));
}
double max(double arr[ROWS][COLS]) /* task d */
{
int i, j;
double max = arr[0][0];
for( i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++)
max = (max > arr[i][j]?max:arr[i][j]);
}
return max;
}
void print(double arr[ROWS][COLS]) /* task e */
{
int i, j;
for( i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++)
printf("%.2lf\t", arr[i][j]);
printf("\n");
}
}
13.利用变长数组做为函数参量重做练习 12。
#include
#define R 3 /* R-ROWS */
#define C 5 /* C-COLS */
void storage(int rows, int cols, double arr[rows][cols]); /* task a */
void row_aver(int cols, double arr[cols]); /* task b */
double all_aver(int rows, int cols, double arr[rows][cols]); /* task c */
double max(int rows, int cols, double arr[rows][cols]); /* task d */
void print(int rows, int cols, double arr[rows][cols]); /* task e */
int main(void)
{
int i;
double arr[R][C];
storage(R, C, arr);
for(i = 0; i < R; i++) {
row_aver(C, arr[i]);
}
printf("all_average = %.2lf\n",all_aver(R, C, arr));
printf("max = %.2lf\n", max(R, C, arr));
print(R, C, arr);
return 0;
}
void storage(int rows, int cols, double arr[rows][cols]) /* task a */
{
int i, j;
printf("Please input 15 double.\n");
for(i = 0; i < rows; i++) {
for(j = 0; j < cols; j++)
scanf("%lf", &arr[i][j]);
}
}
void row_aver(int cols, double arr[cols]) /* task b */
{
int i;
double sum = 0;
for(i = 0; i < cols; i++)
sum += arr[i];
printf("row_average = %.2lf\n", sum / (1.0*cols));
}
double all_aver(int rows, int cols, double arr[rows][cols]) /* task c */
{
int i, j;
double total = 0;
for(i = 0; i < rows; i++) {
for(j = 0; j < cols; j++)
total += arr[i][j];
}
return (total / (1.0*rows*cols));
}
double max(int rows, int cols, double arr[rows][cols]) /* task d */
{
int i, j;
double max = arr[0][0];
for( i = 0; i < rows; i++) {
for(j = 0; j < cols; j++)
max = (max > arr[i][j]?max:arr[i][j]);
}
return max;
}
void print(int rows, int cols, double arr[rows][cols]) /* task e */
{
int i, j;
for( i = 0; i < rows; i++) {
for(j = 0; j < cols; j++)
printf("%.2lf\t", arr[i][j]);
printf("\n");
}
}