行和,列和,总和的指针求法
C中数组和指针有着紧密的关系
例如数组名可以同时看作指向数组首个元素的指针
对于一维数组
a[i] == *(a + i)
对于二维数组
a[i][j] == *(*(a + i) + j)
所以行和,列和,总和除了数组求法,也有指针求法
#include <stdio.h>
#define COL 3
#define ROW 2
int main(void)
{
int i, j, t, t1 = 0, cc = 0, cr = 0;
int ar[ROW][COL] = {{1,2,3},{4,5,6}};
for (i = 0; i < COL; i++)
{
t = 0;
for (j = 0; j < ROW; j++)
{
t += *(*(ar + j) + i);
}
cc++;
printf("sum of column %d = %d\n", cc, t);
}
for (i = 0; i < ROW; i++)
{
t = 0;
for (j = 0; j < COL; j++)
{
t += *(*(ar + i) + j);
}
cr++;
printf("sum of row %d = %d\n", cr, t);
}
for (i = 0; i < ROW; i++)
{
t = 0;
for (j = 0; j < COL; j++)
{
t += *(*(ar + i) + j);
}
t1 += t;
}
printf("sum in total = %d\n", t1);
return 0;
}
sum of column 1 = 5
sum of column 2 = 7
sum of column 3 = 9
sum of row 1 = 6
sum of row 2 = 15
sum in total = 21
拷贝数组(一维)
数组不能被整个操作,只能对其中单个元素进行操作
另外如果不对数组初始化,则数组中全部是随机(?)值
具体如下
#include <stdio.h>
void copy_arr(int a[], int b[], int c);
void copy_ptr(int a[], int b[], int c);
void copy_ptrs(int * a, int * b, int * c);
int main(void)
{
int a[] = {1,2,3,4,5};
int b[5];
int c[5];
int d[5];
int e[5];
int i;
int *pt = a;
for (i = 0; i < 5; i++)
{
printf("%d ", b[i]);
}
putchar('\n');
copy_arr(a, b, 5);
for (i = 0; i < 5; i++)
{
printf("%d ", b[i]);
}
putchar('\n');putchar('\n');
for (i = 0; i < 5; i++)
{
printf("%d ", c[i]);
}
putchar('\n');
copy_ptr(a, c, 5);
for (i = 0; i < 5; i++)
{
printf("%d ", c[i]);
}
putchar('\n');putchar('\n');
for (i = 0; i < 5; i++)
{
printf("%d ", d[i]);
}
putchar('\n');
copy_ptrs(a, d, a + 5);
for (i = 0; i < 5; i++)
{
printf("%d ", d[i]);
}
putchar('\n');putchar('\n');
for (i = 0; i < 5; i++)
{
printf("%d ", e[i]);
}
putchar('\n');
copy_ptrs(pt + 1, e, pt + 4); //用指针实现部分拷贝
for (i = 0; i < 3; i++)
{
printf("%d ", e[i]);
}
putchar('\n');putchar('\n');
return 0;
}
//数组方法
void copy_arr(int a[], int b[], int c)
{
int i;
for (i = 0; i < c; i++)
{
b[i] = a[i];
}
}
//指针方法
void copy_ptr(int a[], int b[], int c)
{
int i;
for (i = 0; i < c; i++)
{
*(b + i) = *(a + i);
}
}
//递增指针直至其指向数组界外的下一个元素(下两个及以后的不可)
void copy_ptrs(int * a, int * b, int * c)
{
while (a < c)
{
*b = *a;
//如果对指针加1,则增加1个存储单位(此处int即4字节)
//在数组中,也表示指针指向了下一个元素
a++;
b++;
}
}
4200656 0 16 0 0
1 2 3 4 5
8259424 0 -1152394762 32762 8
1 2 3 4 5
4199744 0 8 0 0
1 2 3 4 5
8259416 0 -1152394762 32762 4206600
2 3 4
拷贝数组(二维)
使用拷贝一维数组的函数拷贝每一行
递增指针指针进行换行
但要注意此处指针指向的是一个数组(即一整行),声明形式为
type (*name)[index];
括号不可去掉,否则
type * name[index];
表示的是指针数组(数组里的元素都是指针)
具体如下,可以看到函数完全不用动,只要在主程序里用对指针即可
#include <stdio.h>
void copy_ptr(int a[], int b[], int c);
void print_array(int a[][3], int b);
int main(void)
{
int (*start)[3];
int (*b0)[3];
int b[3][3];
int a[3][3] = {
{1,4,9},
{3,5,7},
{2,6,0}
};
start = a;
b0 = b;
while (start < a + 3)
{
copy_ptr(*start, *b0, 3);
b0++;
start++;
}
print_array(a, 3); //打印a
putchar('\n');
print_array(b, 3); //打印b作对照
return 0;
}
void copy_ptr(int a[], int b[], int c)
{
int i;
for (i = 0; i < c; i++)
{
*(b + i) = *(a + i);
}
}
void print_array(int a[][3], int b)
{
int i, j;
for (i = 0; i < b; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", a[i][j]);
}
putchar('\n');
}
}
1 4 9
3 5 7
2 6 0
1 4 9
3 5 7
2 6 0
找出数组最值
Fortran版:
#include <stdio.h>
void min(double a[], int b);
void max(double a[], int b);
void reverse(double * a, int b);
int main(void)
{
double b[] = {44.12,55.45,1.25,12.56,12.14,77.25};
min(b, sizeof(b) / sizeof(*b));
max(b, sizeof(b) / sizeof(*b));
reverse(b, sizeof(b) / sizeof(*b));
return 0;
}
void min(double * a, int b)
{
double min = *a;
int i, d;
for (i = 0; i < b; i++)
{
if (a[i] < min)
{
min = a[i];
d = i;
}
else
{
continue;
}
}
printf("min = a[%d] = %f\n", d + 1, min);
}
void max(double * a, int b)
{
double max = a[0];
int i, d;
for (i = 0; i < b; i++)
{
if (a[i] > max)
{
max = a[i];
d = i;
}
else
{
continue;
}
}
printf("max = a[%d] = %f\n", d + 1, max);
}
void reverse(double * a, int b)
{
int i;
printf("Array entered in reverse order:\n");
for (i = b; i > 0; i--)
{
printf("%.2f ", *(a + i - 1));
}
}
min = a[3] = 1.250000
max = a[6] = 77.250000
Array entered in reverse order:
77.25 12.14 12.56 1.25 55.45 44.12
矩阵的加法,标量倍,乘法
向函数传入数组,一维时元素个数单独传入
func_d1(int x[], int y);
二维及更高的数组只有最左边的括号是可以空的,用来传入一维上的元素个数
func_d3(int x[][2][3][4], int y);
当然使用变长数组传入每个维度的值的话会显得明了一些
func_vla(int x, int y, int z, int a[x][y][z])
具体如下
#include <stdio.h>
void matrix_addition(int m, int n, int a[m][n], int b[m][n], int c[m][n]);
void scalar_multiplication(int m, int n, int t, int a[m][n], int b[m][n]);
void matrix_multiplication(int m, int n, int p, int a[m][n], int b[n][p], int c[m][p]);
int main(void)
{
//使用复合字面量,省略声明数组
matrix_addition(2, 2, (int[][2]){{1,2},{3,4}}, (int[][2]){{5,6},{7,8}}, (int[][2]){});
putchar('\n');
scalar_multiplication(2, 2, 4, (int[][2]){{5,6},{7,8}}, (int[][2]){});
putchar('\n');
matrix_multiplication(4, 3, 4, (int[4][3]){2,3,7,7,8,9,2,3,7,7,8,9}, (int[3][4]){2,3,7,7,8,9,2,3,7,7,8,9}, (int[4][4]){});
return 0;
}
void matrix_addition(int m, int n, int a[m][n], int b[m][n], int c[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
*(*(c + i) + j) = *(*(a + i) + j) + *(*(b + i) + j);
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%-5d ", c[i][j]);
}
putchar('\n');
}
}
void scalar_multiplication(int m, int n, int t, int a[m][n], int b[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
*(*(b + i) + j) = (*(*(a + i) + j)) * t ;
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%-5d ", b[i][j]);
}
putchar('\n');
}
}
void matrix_multiplication(int m, int n, int p, int a[m][n], int b[n][p], int c[m][p])
{
int i, j, k;
for (i = 0; i < m; i++)
{
for (j = 0; j < p; j++)
{
for (k = 0; k < n; k++)
{
c[i][j] += a[i][k] * b[k][j];
}
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < p; j++)
{
printf("%-5d ", c[i][j]);
}
putchar('\n');
}
}
6 8
10 12
20 24
28 32
77 82 76 86
141 156 137 154
77 82 76 86
141 156 137 154
逐行传入/整体传入
#include <stdio.h>
void save(int m, double a[m]);
void print_array(int m, int n, double a[m][n]);
double row_average(int m, double a[m]);
double all_average(int m, int n, double a[m][n]);
double max(int m, int n, double a[m][n]);
int main(void)
{
double c[3][5];
double (*pt)[5];
int i;
pt = c;
for (i = 0; i < 3; i++)
{
save(5, *(pt + i));
fflush(stdin); //不保存第五项以后的输入
}
putchar('\n');
printf("Matrix you entered:\n");
print_array(3, 5, pt);
putchar('\n');
//pt是指向一维数组的指针,对其解引用(*pt)就是矩阵的第一行,对pt做加法就可以指向下几行
for (i = 0; i < 3; i++)
{
printf("Average of row %d:\n", i + 1);
printf("%.2f\n", row_average(5, *(pt + i)));
putchar('\n');
}
printf("Average of all elements:\n");
printf("%.2f\n", all_average(3, 5, pt));
putchar('\n');
printf("Maximum in all elements:\n");
printf("%.2f\n", max(3, 5, pt));
return 0;
}
//逐行保存
void save(int m, double a[m])
{
int i;
printf("Please enter %d numbers.\n", m);
a:
for (i = 0; i < m; i++)
{
while (scanf("%lf", &a[i]) != 1)
{
printf("%d numbers, please.\n", m);
fflush(stdin); //防无限循环
goto a;
}
}
}
//逐行求平均
double row_average(int m, double * a)
{
int i;
double z = 0;
for (i = 0; i < m; i++)
{
z += *(a + i);
}
return z / m;
}
//全矩阵求平均
double all_average(int m, int n, double a[m][n])
{
int i, j, s = 0;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
s += a[i][j];
}
}
return (double)s / (m * n);
}
//打印矩阵
void print_array(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
putchar('\n');
}
}
//全矩阵求最大值
double max(int m, int n, double a[m][n])
{
int i, j;
double maximum = a[0][0];
for (i = 0; i <= m; i++)
{
for (j = 0; j <= n; j++)
{
if (a[i][j] > maximum)
{
maximum = a[i][j];
}
else
{
continue;
}
}
}
return maximum;
}
Please enter 5 numbers.
1 4 7 8 58 5 4 8 5
Please enter 5 numbers.
7 [ l 4 5
5 numbers, please.
7 4 8 9 54 8 65
Please enter 5 numbers.
7 4 84 9 5 6 9 8
Matrix you entered:
1.00 4.00 7.00 8.00 58.00
7.00 4.00 8.00 9.00 54.00
7.00 4.00 84.00 9.00 5.00
Average of row 1:
15.60
Average of row 2:
16.40
Average of row 3:
21.80
Average of all elements:
17.93
Maximum in all elements:
84.00