c语言指针有关问题(谭浩强c语言第3版第10章第3节)

c语言指针问题(谭浩强c语言第3版第10章第3节)
问题如上所说,都是谭浩强c语言第3版第10章第3节中的。

问题1:
int a[10]={1,2,3,4,5,6,7,8,9,10};
x=a;
for(i=0;i<10;i++)
printf("%d ",*x++);
printf("\n");
//for(i=0;i<10;i++)
printf("%d ",*x++);
注释掉第2个for循环打印*x或者*x++结果都是10
但是如果不注释,结果就是垃圾数据(10之后的,不包括10)
何解?

  我觉得第一个for最后一次输出后已经把指针指向了a数组最后一个元素之后的那个元素了,但为什么会出现10

问题2:下面2段程序都是要把数组中的元素对调,把第一个和最后一个,第2个和倒数第2个元素对调,依次类推。

#include <stdio.h>

main()
{
void inv(int a[],int n);
int i;
int a[10]={1,2,3,4,5,6,7,8,9,10};
for(i=0;i<10;i++)
{
printf("%d ",a[i]);
}
printf("\n");
inv(a,10);
for(i=0;i<10;i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
void inv(int a[],int n)
{
int i,*p;//定义成int i,p;
p=a;//去掉这里
for(i=0;i<(n-1)/2;i++)
{
int j=n-i-1;
*p=a[i];//*p换成p
a[i]=a[j];
a[j]=*p;
}
}

//结果为什么是4 9 8 7 5 6 4 3 2 10,但是如果换成上面注释后的内容的话,就可以正常对调

然后我把程序小调整了一下:

#include <stdio.h>
main()
{
void inv(int *x,int y);
int i,*x;
int a[10]={1,2,3,4,5,6,7,8,9,10};
x=a;
for(i=0;i<10;i++)
printf("%d ",*x++);
printf("\n");
inv(a,10);
for(i=0;i<10;i++)
printf("%d ",*x++);
printf("\n");
}

void inv(int *x,int y)
{
int i,p,*j;
for(i=0;i<(y-1)/2;i++,x++)
{
j=x+(y-1-i);
p=*x;
*x=*j;
*j=p;
}
}

//结果是10 1 2 3 5 6 7 8 9 4?inv函数中哪里出错了?
我感觉指针的传递应该没什么为题啊



以上2个问题我理解不了,还请大神帮助,实在感谢!


------解决方案--------------------
第一个问题
学会用%p格式输出变量的地址
第一次循环结束时的x值可能是&i

第二个问题
for(....;i++,x++)
.....
j=x+(y-1-i);j不是你希望的位置,
枚举一下:
i,x,j
0,a,a+9
1,a+1,a+9
2,a+2,a+9
....
------解决方案--------------------
探讨
引用:
第一个问题
学会用%p格式输出变量的地址
第一次循环结束时的x值可能是&amp;i

如果去掉第2个for循环的话,第一次for循环结束时x是10的地址
但是如果不去掉第2个for循环的话,第一次for循环结束时x是i的地址
如果打印*x的话结果是0 1 2 3 4 5 6 7 8 9
如果打印*x++的话结果是0 垃圾数据 垃圾数据 ...
请问这是什么……

------解决方案--------------------
问题2中第一个程序中inv函数for循环出现问题i<(n-1)/2相当于i<4,所以导致第5个跟第6个不能转换。再说*p=a,你将指针指向数组的首地址,所以没有输出的时候第一个跟最后一个没有交换。
------解决方案--------------------
*p=a[i]表示p指向a[i],所以a[i]=a[j]之后*p=a[j],再令a[j]=*p就没有意义了,第一次对调的结果就是a[0]=10,a[9]=10,之后的依次类推。其实你根本没用到*p,*p起到的作用跟一个临时变量一样,所以你随便换一个temp(你定义的int p)就行了
------解决方案--------------------
void inv(int a[],int n)
{
int i,*p;//定义成int i,p;
p=a;//去掉这里
for(i=0;i<(n-1)/2;i++)
{
int j=n-i-1;
*p=a[i];//*p换成p
a[i]=a[j];
a[j]=*p;
}
================
问的是这段代码吗?
跟踪一下:
p=a;//p指向了a[0]
在i循环中跟踪i,j,p
i,j,p
0,9,&a[0]
1,8,&a[0]
2,7,&a[0]
.......
你是用*p即a[0]做交换用的临时单元,自然交换过程中a[0]中的有效数据丢了。
另外i的循环条件有误:
i<(n-1)/2即i<(10-1)/2即i<4,只交换了四次
正确的写法是i<(n)/2,不论n是奇是偶都是正确的,减一是怎样考虑的?自己总结一下。
}
=====================

------解决方案--------------------
void inv(int *x,int y)
{
int i,p,*j;
for(i=0;i<(y-1)/2;i++,x++)
{
j=x+(y-1-i);
p=*x;
*x=*j;
*j=p;
}
}

=============
这段代码提些意见:
称原数组的首元素地址为基准点
指针变量x接收这个基准点
但循环中x++,x的值就不是基准点了------动点
j是另一个动点,如果它按基准点计算一般不会错,但你基于动点x计算j----初学指针的人很难把握。