标签:
习题:编写一个对数组进行操作的函数,目的用此函数返回数组内所有元素的和
方法一: 知道固定数组个数
<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