C语言指针及二维数组

来源:百度知道 编辑:UC知道 时间:2024/05/18 12:51:59
我写的一个求二维数组平均数的程序:

#include "stdio.h"
main()
{
void aver(float *p,int n);
float a[3][4]={65,67,70,60,80,87,90,81,90,99,100,98};
aver(*a,12);
}

void aver(float *p,int n)
{float sum=0,average,*pend;
pend=p+n-1;
for(;p<=pend;p++)
sum+=*p;
average=sum/12;
printf("average=%5.2f\n",average);
}

这个程序是正确的。但是请看一下我的aver函数。我有3个问题。一,因为只要算12个数的平均数,所以我一开始在aver函数的for循环里直接写p<=11,也没有定义*pend,系统就一直报错,为什么?二,为什么改成现在这个样子之后就行了?三,a是二维数组,那么*p是一个地址,而不是值,对不对?如果是这样的话,为什么是sum+=*p,而sum+=**p就不对呢?
3个问题,麻烦给我详细地说说。

一、p是存放float型数据的地址,而11是整型数据,当然不能做比较
二、因为pend也是地址
如:
p指向地址0x0012FF60 pend = p的话,pend也为0x0012FF60
pend = p+1,则p指向0x0012FF64 因为float占4个byte
pend=p+2 0x0012FF68
...
三 传入*a相当于传入&a[0][0]的地址,即二维数组a的地址
相当于
float* p = &a[0][0];
aver( p, 12 );
p是地址,*p则取到该地址里存地数据,即该程序的中的65
*(p+1)则会取到67 --二维数组是按行存储的
...
以此类推
p是个一级float型指针,所以**p显然不合逻辑,不合语法

首先,*p是个地址,你给地址直接赋值,编译器是不允许的,只接受编译器自己分配的地址检查
其次,pend = p+n-1,是一个基地址上面转换的,所以都是float *类型,允许。
三。不管数组维数,其实都是连续分配的,比如float a[2][3],可以用float * b引用,相当于是b[0]到b[5],所以强制转换成float*,理论上只要是指针都能转换