之前对数组访问的理解不是很深刻,今天通过这道题,再次理解一下数组的访问。
题目:编写程序,要求用下标和指针两种方式访问二维数组,计算矩阵(5行5列)以下值:
- 主对角线元素之和;
- 除对角线外所有元素之和;
- 上三角元素之和;
- 首行、首列、末行和末列的所有元素之和。
法一:用下标访问数组
例如此处创建一个5*5的数组,那么直接用下标值可对数组进行访问,如:
arr[0][0]=1;
arr[3][4]=7;
arr[2][1]=8;
本题解答如下:
#include<stdio.h>
int main()
{
int arr[5][5] = { {1,2,3,4,5},{7,8,9,8,5},{5,8,7,2,6},{6,9,8,7,2},{8,9,5,7,4} };
int i = 0;
int j = 0;
int x = -1;
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
int sum4 = 0;
//(1)计算主对角线元素之和
for (i = 0; i < 5; i++)
{
sum1 += arr[i][i];
}
printf("主对角线元素之和为:>%d\n",sum1);
//(2)计算除对角线外所有元素之和
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
sum2 += arr[i][j];
}
}
sum2 -= sum1;
printf("除对角线外所有元素之和为:>%d\n", sum2);
//(3)计算上三角元素之和
for (i = 0; i < 5; i++)
{
x++;
for (j = x; j < 5; j++)
{
sum3 += arr[i][j];
}
}
printf("上三角元素之和为:>%d\n", sum3);
//(4)计算首行、首列、末行和末列的元素之和
for (i = 0; i < 5; i++)
{
sum4 += (arr[0][i] + arr[i][0]+arr[4][i]+arr[i][4]);
}
sum4 = sum4 - arr[0][0] - arr[4][4] - arr[0][4] - arr[4][0];
printf("首行、首列、末行和末列的所有元素之和为:>%d", sum4);
return 0;
}
运行结果如下:
法二:用指针访问数组
我们任以上面创建的二维数组为例。
如图所示,数组是按行存储的,地址arr上存储的内容是第一行数组的首地址,即*arr。也就是说,*arr是第一行数组的首地址,对地址进行解引用操作,自然就可以通过*(*(arr))访问到首地址指向的首元素的值了。
我们的想法是否正确呢?在编译器上进行简单测试,可以验证我们的想法是正确的。
那么如何访问其余元素呢?按照同样的思路,只需要找到每一个元素的地址,再对其进行解引用操作,就可以访问任意元素的值。以数组第一行为例,(*arr)是第一行数组的首地址,(*arr)+1就是第一行第二个元素的地址,(*arr)+3就是第一行第四个元素的地址;按照同样的思路,*(arr+3)是第四行数组的首地址,*(arr+3)+1就是第四行第二个元素的地址,*(arr+3)+3就是第四行第四个元素的地址。
总结一下,以m行n列数组为例,首先要找到数组每一行首元素的地址,以*(arr+m)表示,m是几,就是第几行;在看这个元素是该行的第几列,就在该行首元素的地址后面+n,n是几,就是第几列。
以本题中创建的数组为例,每一个元素的地址如下图所示:
对地址解引用,就可以得到元素值,如:
*(*(arr+4)+3)=arr[4][3]=7;
*(*(arr+2)+1)=arr[2][1]=8;
本题解答如下:
#include<stdio.h>
int main()
{
int arr[5][5] = { {1,2,3,4,5},{7,8,9,8,5},{5,8,7,2,6},{6,9,8,7,2},{8,9,5,7,4} };
int i = 0;
int j = 0;
int x = -1;
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
int sum4 = 0;
//(1)主对角线元素之和
for (i = 0; i < 5; i++)
{
sum1 += *(*(arr+i)+i);
}
printf("主对角线元素之和为:>%d\n",sum1);
//(2)除对角线外所有元素之和
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
sum2 += *(*(arr+i)+j);
}
}
sum2 -= sum1;
printf("除对角线外所有元素之和为:>%d\n", sum2);
//(3)上三角元素之和
for (i = 0; i < 5; i++)
{
x++;
for (j = x; j < 5; j++)
{
sum3 += *(*(arr + i) + j);
}
}
printf("上三角元素之和为:>%d\n", sum3);
//(4)首行、首列、末行和末列的所有元素之和
for (i = 0; i < 5; i++)
{
sum4 += *(*(arr)+i) + *(*(arr + 4) + i) + *(*(arr + i)) + *(*(arr + i) + 4);
}
sum4 = sum4 -*(*arr)-*(*(arr+4))-*(*(arr)+4)-*(*(arr+4)+4);
printf("首行、首列、末行和末列的所有元素之和为:>%d", sum4);
return 0;
}
运行结果如下: