• 3147阅读
  • 4回复

[未解决]指针与数组的问题! 新手请教! [复制链接]

上一主题 下一主题
离线枫叶林
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2013-09-24
— 本帖被 啊冲 从 DebugGo游戏逆向 移动到本区(2013-09-24) —







*pIndex  代表取地址里的值
pIndex   表示地址
&           表示地址

我没理解错吧 ,下面的问题 把我给高纠结了

问题一
int *pIndex=nArray;    等价于  int *pIndex=&nArray;    都是表示把数组地址复制给 *pIndex 吗? 那*pIndex 应该表示的是地址才对啊

为什么 cout<<*pIndex 的显示结果却是 1?  我认为应该输出地址才对  要想输出值 应该这样写 cout<<*(*pIndex ) 才可能得到1 ,

cout<<*(*pIndex ) 有没有这样的写法??

问题二 看教程上说

pIndex是数组1的地址
pIndex+1就是 是数组2

pIndex 是数组的下标吗?? 为什么加一就是数组2了?  pIndex不是表示地址吗?  地址不是应该+4(站四个字节)才能表示下个元素吗?

新手  纠结了我好久  还望大牛详解!!!!!!
离线果子

只看该作者 沙发  发表于: 2013-09-24
问题一
int *pIndex=nArray;    等价于  int *pIndex=&nArray;    都是表示把数组地址复制给 *pIndex 吗? 那*pIndex 应该表示的是地址才对啊
为什么 cout<<*pIndex 的显示结果却是 1?  我认为应该输出地址才对  要想输出值 应该这样写 cout<<*(*pIndex ) 才可能得到1 ,
cout<<*(*pIndex ) 有没有这样的写法??
问题二 看教程上说
pIndex是数组1的地址
pIndex+1就是 是数组2
pIndex 是数组的下标吗?? 为什么加一就是数组2了?  pIndex不是表示地址吗?  地址不是应该+4(站四个字节)才能表示下个元素吗?
新手  纠结了我好久  还望大牛详解!!!!!!



首先,我们来看上面这个图来理解数组地址(array),第一个元素地址(&array[0]),与数组名地址(&array)的关系.
1、数组地址array可以理解成一个常量指针(有的时候并不一定是等价的)。
2、数组名代码这一系列元素的集合的首地址,在内存空间里就是一列排列整齐的元素的地址,所以第一个元素的地址等价于数组的首地址,这个应该不难理解。
3、当对数组首地址取地址时(&array),相当于做了一次二次取值,即指针的指针,它指向的类型是整个数组的类型。
好了,让我们回到问题。
问题一解答:这里你需要区别下数组名与指针的关系。
1、int *pIndex=nArray; 等价于 int *pIndex=&nArray;首先得明白变量的初始化, int *pIndex=nArray等价于int *pIndex;  pIndex = nArray;那这样一来的话,int *pIndex=&nArray;等价于int *pIndex; pIndex=&nArray;这两个类型之间的赋值是相同的吗?
这个虽然在数值上是等价,但代表的含义不一样,因为它们的类型不一样,打个比方来说,你家乡在湖南,湖南在中国领土的某个位置,你可以说湖南确实是中国的一个地址,但反过来你不能说中国就是湖南。所以当你编译 int *pIndex=&nArray 这段代码时,相信万能的编译器会给你报警告的。
为什么值是1呢?这是因为它们的地址在数组上是相等的,当你用“*”这个运算符去对应地址里取值的时候,就是把这个地址里的值取出来,当然是1了。


问题2解答:
指针+1的意思是在它所指向的类型基础上偏移类型所占用的字节数。什么意思呢?
如int *p;  当它p = p+1时,其实就是在p这个地址上偏移了sizeof(int)=4个字节,如果是char *p的话就是偏移sizeof(char) = 1个字节,减法反之。
1条评分小风币+5
啊冲 小风币 +5 回答的可真详细啊 2013-09-24
因为经历,所以幸福!
离线那个谁

只看该作者 板凳  发表于: 2013-09-29
又长知识了。最近又有人拿这样的问题来问我。许久不看又忘了。我也来补充一点我遇到的问题。
关于数组名和指针的区别:
int buff[10]={0};
int i;
for(i = 0; i<10; i++)
      printf("%d\n", *buff++);
很多初学者都会认为打印出10个0。但实际情况是编译时就会出错。原因是大家开始学习时都认为数组名是数组的首地址等价,所以会将数组名直接当成一个指针来使用了。数组名本身就是一个指针,是一个指针常量,即a等价于int * const a,因此你不能试图修改数组名的值”。这个是摘抄自一个博士所写的一本书中的解释。但这个也是并不完全正确的说法。还是理解成果子的比较合理:数组名可以理解为一个指针常量(注意这里是可以理解成指针常量,不能等同成指针常量)。至于为什么,有兴趣的同学可以在汇编中去发现奥秘,我现在的汇编知识太贫乏,还无法解释。

离线gl542400

只看该作者 地板  发表于: 2013-09-30
学习!不错!让人一看就明!
离线那个谁

只看该作者 4楼 发表于: 2013-10-03
最近又遇到了一个问题,这个也是C语言中常见的问题。时间久了没有接触又忘了,现在再来学习一遍。
看下面的代码:
    char *p = "abcdefgh";
    char *temp;
    p = p + 3;
    temp = strcpy(p, "ABCD");
    //printf("%s\n", temp);
    printf("%d\n", strlen( temp ) );


这里编译的时候就会出现问题。问题如下:
1、temp = strcpy(p, "ABCD");。首先我们定义的char *temp是一个野指针,没有指向具体的位置。所以这样的赋值是错误的。编译时会报错。
2、还是这句话temp = strcpy(p, "ABCD");。我们执行strcpy(p, "ABCD");时也会有问题。问题出在我们定义和赋初值的char *p = "abcdefgh";这句话。这里的指针不是一个野指针,是一个正常的可用的指针,但是注意它所在的区域是只读存储区,也就是说是不能改变其内容的。而strcpy(p, "ABCD")是要将p所指向的内容变成字符串ABCD,所以就会报错了。
这两个问题我曾经在翻译FAQ的时候也遇到过。有兴趣的同学可以在这个版块的C语言FAQ中的子分类中的Question1.32和Question8.5中找到原版的详细的解释。
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个