C++-我的C问题,关于char *的地址问题
首先,请看代码:
#include<stdio.h>
#include<stdlib.h>
#include"windows.h"
int main()
{
char *p1 = NULL ;
p1 = "gbregbrgr";
printf("p1=0x%x, "gbregbrgr"==0x%xn",p1,"gbregbrgr");
{
int i = 0;
for(i = 0; i<10; i++)
printf("&p1+%d==0x%xn",i,&p1+i);
}
p1 = p1+20 ;//注,此处已经加20了
printf("p1==0x%x, &p1==0x%x, "gbregbrgr"==0x%xn",p1,&p1,"gbregbrgr");
printf("p1==0x%x, &p1==0x%x, "bregbrgr"==0x%xn",p1,&p1,"bregbrgr");
system("pause");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
1.p1 保存的是字符串"gbregbrgr"的首地址,但是 p1 也是个变量,它也有自己的地址,&p1 就是取 p1 自己的地址,而且它的地址就是 0x12ff7c 。所以你第一点中的疑问统统不存在。
2.p1 = p1+20 只是对 p1 中保存值进行操作,p1 本身的地址从来没有变,所以 &p1 是 p1 本身的地址,仍然是 0c12ff7c 。
3."bregbrgr"==0x425178 这个地址没有特殊之处。
实际就是:
p1 值是 "gbregbrgr"字符串在内存中的首地址,即0x424024
&p1 是p1在内存中的地址,也就是说存放p1这个值的地址。按你输出的内容看,p1被存放在这个地址:0x12ff7c
也就是0x12ff7c这个地址(及连续的4个字节)的内容实际是0x424024, 0x424024这个地址的内容才是"gbregbrgr"的第一个字符。
后面你对p1加了20,实际是0x12ff7c对应的值加了20,你输出的是p1的地址,p1值被改变了,地址不会改变的啊,地址还是0x12ff7c
第3个问题不知你在疑惑啥,对于字符串,在代码中使用了,就肯定得有对应的地址存储。
要想达到你的目的,p1是指针了,对p1进行操作即可移动位置,从不同的位置取出字符串。
p1 == &"gbregbrgr"(此处只为表达), *p1 = 'g' 。
对于楼主的代码,使用VS2008单步跟踪,结果如下。
当执行到第一个printf的时候,观察p1和&p1的值,结果如下:
从上述结果可以看出,p1的值是0x00a557e4,&p1的值是0x002ef73c。
然后查看p1的值所指向的内存情况,结果如下:
可以看出,存储的就是字符串“gbregbrgr”。这也可以说明p1的值是指向字符串“gbregbrgr”的指针,所以会有p1和“gbregbrgr”的值是一样的,因为都是字符串“gbregbrgr”的地址。
查看&p1的值所指向的内存情况,结果如下:
可以看出,存储的就是指针变量p1的地址值,所以&p1+1也就是在p1的地址上面自加1个单位之后的地址。由于地址的存储空间占4byte,所以每一次加1都会增加4byte,但是其实这个自加之后的值是没有意义的,因为自加之后的地址是相对于&p1的,所以内部存储的内容也是随机的。这也是说明了&p1+0并不是指向‘g’的地址。指向‘g’的地址应该就是p1.
上面解释了for循环中&p1+i的情况。下面继续解释p1=p1+20.先看结果:
可以看出,p1的值已经改了,在以前p1的基础上后移了20byte。因为p1是指向char类型的指针,而char类型的存储空间占1byte,所以p1+20向后面移动20个单位,也就是20byte。此时p1的值是0x00a557f8,指向字符‘d’.这个字符‘d’其实也是随机的。因为p1原本是指向字符串“gbregbrgr”,而这个字符串长度只有10,所以p1+20已经超出了这个字符串的长度,指向了一个不确定的内存空间。
不过注意,这里只是改变了p1的值,并没有改变存储指针变量p1的存储空间地址,也就是&p1还是原来的p1的地址值,也就是0x2ef73c。这一点LZ一定要明白。
当然,字符串“gbregbrgr”的地址同样没有改变,还是等于最开始p1中存储的值,也就是0xa557e4.
最后一个printf语句的前两个输出与上面讲述的同理。不过最后一个输出“bregbrgr”的地址,这个其实是一个随机地址。执行这行的时候,编译器会先生成一个字符串,赋值为“bregbrgr”,地址当然也是随机的。然后把这个地址输出来。
我运行的总体结果如下:
至此,所有的问题都解答了。希望能够帮LZ理解。
p1=p1+20;
这句代码只是把p1(指针)的值加了20,但没把p1所指向的地址是没有变的(指针也有地址),
就像:
int i=10;
i+=20;
i的地址是不会变的,
总的来说,指针是一种特殊的变量,改变它的值并不会改变它地址的值。
1.&p1+0 不是'g'的地址,是p1指针变量的地址加0,&是取地址操作符,所以&p1做的事情是取p1指针变量的地址,所以代码中做如下处理:
for(i = 0; i<10; i++)
printf("&p1+%d==0x%xn",i,&p1+i);
//改为
for(i = 0; i<10; i++)
printf("p1+%d==0x%xn",i,p1+i);
就可以得到'g'的地址为:0x424024, 'b'的地址为:0x424025。
2.同第一问,p1+20 后,p1指针的值增加20,也就是地址偏移20,所以可以得到p1 = 0x424038,但是&p1得到的是p1指针变量的地址,所以输出的是0c12ff7c,这是p1指针变量的地址。
3.你在printf()函数中用字符串"bregbrgr"作为参数,程序在编译的时候实质上也会给这个字符串分配地址,至于为什么这个字符串的首地址值为0x425178 ,是因为你这个程序运行在系统分配的一段有限的内存空间中,所以这个字符首地址值和之前定义的字符串"gbregbrgr"的字符地址不会偏移很远,所以也是0x4xxxxx之类的。
综述:其实这个问题的起因应该是对&操作符的错误理解,想要输出p1指针变量指向的字符串中字符的地址,只需要直接输出p1+i即可。
p1指针要在内存中存在就应该有地址,而该地址中存放的值就是p1指针所指向的值的首地址。&p1只是取p1在内存中的地址,而不是p1所指向的值的地址。剩下的问题等高手回答。。。
楼主应该是将概念弄混了,你可以仔细的分析一下指针的含义。
p1是指针,它的值是字符串的地址。但是你打印的是&p1,也就是p1的地址,而不是字符串的地址。其实就是指针的指针。p1="aa";p2=&p1;你打印的是p2的值。