首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

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

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

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----初学指针的人很难把握。


你试一试,保持x基准点不动,用两个动点(指针)基于x计算指向交换的元素是不是容易些?
或者用x+i和x+n-1-i指向交换元素。
还有一点,习惯上i,j,k表示循环变量、数组下标等,用j做指针变量不恰当。
[解决办法]
程序2中i的循环条件有误:
i<(n-1)/2 即i<(10-1)/2 即i<4,只交换了四次
应该是i<(n)/2,
[解决办法]
你要问,我就说:
(n-1)/2和n/2表面上分子部分差1,但概念上差别很大
对于数组而言,n是元素个数,n/2就是两两一对的对数----本题就是两两交换的次数----这是数量概念
而n-1不要理解为元素个数,它是下标的序号,最大的序号。(n-1)/2是什么?不要用数量概念理解,应该问序号除以2是什么东西?举例来说2012(年)是个序数,它除以2有什么意义?

数量概念的算术运算十分丰富!
但序号的算术运算十分有限!序号+(或-)数量得另一个序号,序号-序号得数量。在这里这个数量称作“距离”

学习程序设计过程中,有人接受得快,有人接受得慢------整数的数量和序号概念清楚与否,它们之间的联系是什么?关系很大

热点排行