标签:
习题:编写一个对数组进行操作的函数,目的用此函数返回数组内所有元素的和
方法一: 知道固定数组个数
<pre name="code" class="objc"><span style="font-size:18px;">#include<stdio.h>
int sum(int *ar);
int main()
{ int total;
int numbers[5]={3,4,2,6,1};
printf("%d ",numbers)
total=sum(numbers) ;
printf("%d\n",total);
}
int sum(int *ar)
{
int i;
int total=0;
for(i=0;i<5;i++)
total+=ar[i];
return total;
}</span>
方法二: 不知道固定的个数
<span style="font-size:18px;">#include<stdio.h>
int sum(int *ar,int n);
int main()
{ int total,n;
int numbers[]={3,4,2,6,1,8};
n=sizeof(numbers)/sizeof(int);
total=sum(numbers,n) ;
printf("%d\n",total);
}
int sum(int *ar,int n)
{
int i;
int total=0;
for(i=0;i<n;i++)
total+=ar[i];
printf("%d\n",sizeof(ar));
return total;
}</span>
运行结果是 : 4 24
因为: ar 不是一个数组,它是一个指向 numbers 首元素的指针 ,对于32位的机器,指针存放的是地址,自己本身的大小也是 32位bit ,也就是 4个字节。
——————————————————————————————————————————————————————————————————————————————————————————————————————————————
讲解: 由于 数组名是该数组首元素的地址,所以说实际参数是一个数组名,那么形参必须是与之匹配的指针。而且仅在这种场合C对 int ar[] 跟 int *ar 解释是一样的。
所以说下面几种原型是等价的。
int sum(int *ar , int n);
int sum(int ar[], int n);
int sum(int * , int );
int sum(int [ ] , int );
至于定义也一样。
int sum(int *ar , int n)
{
//代码
}
int sum(int ar[], int n)
{
// 代码
}
————————————————————————————————————————————
如何使用指针参数 (非常重要了!!!!!!!!!!!)
<span style="font-size:14px;">#include<stdio.h>
#define SIZE 5
int sump(int *start ,int *end );
int main()
{
int num[SIZE]={1,2,3,4,5};
int total;
printf("%p %p %p %p %p %p \n",num,num+1,num+2,num+3,num+4,num+5);
total=sump(num,num+SIZE);
printf("%d\n",total);
return 0;
}
int sump(int*start,int *end)
{
int total=0;
while(start<end)
{
total+=*start;
start++;
}
return total;
}</span>
我们发现num+SIZE 指向的是 数组末尾最后一个元素之后 ,0012FF7C 地址对应的是数值5, 而0012FF80 我们不知道对应是那一个值,这叫“”越界“
所以说形参 end 对应实参里面的 num+SIZE 是 0012ff80 地址了,但是这样的好处是简洁啊。。。。。
start++ 在循环之后的值为 end ,但是要跳出循环了,所以仍然是 1+2+3+4+5=15 多好啊。
也可以写成 total+=*start++; 简洁
——————————————————————————————————————————————————
指针运算的优先级:
代码:如下
<pre name="code" class="objc">#include<stdio.h>
int data[2]={100,200};
int moredata[2]={300,400};
int main(void)
{
int *p1,*p2,*p3;
p1=p2=data ; // 你要记得这里指针也是个变量,只不过存储的是数组首地址而已
p3=moredata;
printf(" *p1= %d ,*p2= %d ,*p3= %d \n ",
*p1, *p2, *p3 ); // 应该是 100 100 300 吧
printf("*p1++=%d ,*++p2=%d, (*p3)++=%d\n ",
*p1++ , *++p2, (*p3)++ ); // 应该是 100 200 301
printf("*p1=%d , *P2=%d, *p3=%d \n ",
*p1 , *p2 , *p3 ); // 应该是 200 200 300
return 0;
}
// 我们来试一下运行结果:
然而自己的并不正确!!!!!!!!!!
所以要多思考一下。
解释:*p1++ 由于是同优先级,规定是右结合,所以说 *(P1++),有两步要走,先是 输出*P 值,也就是100 ,副作用是P1指向下一个数组元素的地址
*++P, 相当于 *(++P),考虑到 ++在前面还是后面的问题,所以先指向下一个地址,再取值的。所以为 200
(*P3)++ 指针没有变,但是里面的值,加1了,但是这里,是先是 使用(*P3)值后改变(*P3)的值的。所以这里仍然是300 ,
也就是说门牌号码即存放的地址没有变,仍然指向moredata数组的首元素地址,但是里面的值加上1 了,也就是301.
有点费脑子,要多理解。!!!!!!!!!!!!!!!!!
标签:
原文地址:http://www.cnblogs.com/shengruxiahua/p/4883719.html