鱼C论坛

 找回密码
 立即注册
查看: 2738|回复: 9

a[] 和 *b 的问题

[复制链接]
发表于 2013-12-21 21:58:00 | 显示全部楼层 |阅读模式
5鱼币
    char a[] = "abc";
    char *b = "abc";


    printf("%p\n",&a);
    printf("%p\n",a);
    printf("%p\n",*a);

    printf("%p\n",&b);
    printf("%p\n",b);
    printf("%p\n",*b);


    printf("%d\n",sizeof(a));
    printf("%d\n",sizeof(b));

output:

0x7fff34cc81c0
0x7fff34cc81c0
0x61
0x7fff34cc81b8
0x400654
0x61
4
8


想请问一下
0x400654 代表什么意思呢?

    char a[] = "abc";
    char *b = "abc";
存在哪些区别吗?
谢谢

最佳答案

查看完整内容

char a[] = "abc"; ---1 char *b = "abc"; ---2 0x400654 是b的值。。。而b是字符数"abc"---2的首地址。。。所以0x400654位置存放的就是"abc", 不信你可以用OD调试, 然后,,a[] 和 *b 肯定不一样。 a[]比*b的效率要低一些。。。我以前就测试过。。首先说明,a[]和b代表的字符串 都存放在内存中, 然后在对a[]这个字符串进行操作时,先要将a[]代表的字符串复制进进程栈, 而对*b代表的字符串进行操作时确实直接操作的内存 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-21 21:58:01 | 显示全部楼层
本帖最后由 向往青莲 于 2013-12-22 09:51 编辑

char a[] = "abc"; ---1
char *b = "abc"; ---2
0x400654  是b的值。。。而b是字符数"abc"---2的首地址。。。所以0x400654位置存放的就是"abc",
不信你可以用OD调试,
然后,,a[] 和 *b 肯定不一样。
a[]比*b的效率要低一些。。。我以前就测试过。。首先说明,a[]和b代表的字符串
都存放在内存中, 然后在对a[]这个字符串进行操作时,先要将a[]代表的字符串复制进进程栈,
而对*b代表的字符串进行操作时确实直接操作的内存,所以*b的效率高一点,
而且。。sizeof(a)是对a[]代表的字符串长度进行求字节,"abc"肯定是4个字节,而sizeof(b)确是
对b自身这个类型的长度求字节,和b代表的字符串完全没关系,
在32位系统上32位程序指针类型占4个字节,而b不也是一个指针嘛? 是char*类型的,
所以同常sizeof(b)是4,而你的sizeof(b)是8,应该是因为你的程序是编译的64位程序吧。。。。(linux没测试)

说了这么多。。有什么问题可以继续问,知无不言,同时欢迎采纳我的回答,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-21 22:38:25 | 显示全部楼层
本帖最后由 maomingkun 于 2013-12-21 22:47 编辑

0x400654  代表字符串“abc”在内存中的位置,b是字符串abc中a的地址吧?&b是存放字符串地址的地址
有点类似于指针的指针。变量应该是放在,栈中的,指针我想是放在栈中的,但是指针指向的内容应该释放到堆中的吧这个是我个人的想法。
你可以看看你这个程序的反汇编代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-12-22 14:34:25 | 显示全部楼层

谢谢你的回答,
我大致了解了,
还有两个问题,
1. 为什么同样是内存位址, 用a[]的时候
会显示为0x7fff55db9c4c 而用*b时会显示为0x400654
长度会差那么多呢?是因为地址本来就可长可短吗?
而为什么用*b的时候 地址一定会是短的呢?

2.&a 和 a, print 出来是同一个地址,
这样是说 0x7fff34cc81c0 里面存放了 0x7fff34cc81c0 吗?
但是 0x7fff34cc81c0 不是应该存'a'这个字元才对吗?
如果把&a理解为指向整个数组,a理解为指向第一个字元,
那在底层是如何区分这两者的呢?
谢谢

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-22 16:46:08 | 显示全部楼层
maca 发表于 2013-12-22 14:34
谢谢你的回答,
我大致了解了,
还有两个问题,

额。。。选我为正确答案吧。。。你懂得。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-23 14:03:30 | 显示全部楼层
无意中又进来了。。。。。。楼主就选我为最佳答案吧。。。你接下来的问题我肯定帮你解决。。。
啦啦。。。。。为了赚鱼币,没办法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-28 23:43:12 | 显示全部楼层
0x400654 代表地址,char a[] = "abc"是字符串数组,长度是sizeof(a)=7//包括A,B,C,D,E,F,'\0' 而char *b = "abc"是字符类型的指针b
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-30 12:29:54 | 显示全部楼层
本帖最后由 向往青莲 于 2013-12-30 12:35 编辑
maca 发表于 2013-12-22 14:34
谢谢你的回答,
我大致了解了,
还有两个问题,

因为用a的时候要先拷贝到堆栈。。。也就是说这个地址是堆栈的地址,
而b是直接用的。。。这个地址是进程空间地址。。。至于为什么堆栈地址这么长。。。注意b这个地址应该看成0040XXXX,而a这个堆栈的地址是7ffffxxxxxxxx,在空间值8XXXXXXXXXXX是内核。。。也就是说堆栈应该是冲7FFFFFFFFFFF往下的。。。这是我推论而来。。正确性有待参考
希望楼主回复我一下你的操作系统。。。win7? 32? 64?,这个程序的位数? 32? 64?

而a是代表a这个数组的首地址。。。同时&a代表的不是取a的地址,而是取a[]这个数组的首地址。
所以&a和a没有区别

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-12-31 12:49:16 | 显示全部楼层
向往青莲 发表于 2013-12-30 12:29
因为用a的时候要先拷贝到堆栈。。。也就是说这个地址是堆栈的地址,
而b是直接用的。。。这个地址是进程 ...

谢谢你~
我使用的是linux 64位元系统,
我想请问一下, 您是如何得知a的时候要先拷贝到堆栈的?
我一直找不到相关的资料,

另外我想问的是,
        int array[2] = {};

        printf(" array  :%p\n",array);
        printf("&array  :%p\n",&array);

        printf(" array+1:%p\n",array+1);
        printf("&array+1:%p\n",(&array)+1);
结果是
array  :0x7fff554bab2c
&array  :0x7fff554bab2c
array+1:0x7fff554bab30
&array+1:0x7fff554bab34
    我一直不太了解系统是如何区分array 和 &array,进而判断他们+1之后的值

谢谢


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-12-31 15:13:14 | 显示全部楼层
本帖最后由 向往青莲 于 2013-12-31 15:15 编辑
maca 发表于 2013-12-31 12:49
谢谢你~
我使用的是linux 64位元系统,
我想请问一下, 您是如何得知a的时候要先拷贝到堆栈的?

既然是64位系统,那么你编译的是32位程序还是64位程序?(ps, 我猜测应该是32位

程序)

首先回答我是如何得知a的时候要先拷贝到堆栈-->我调试得知的

首先明确一个概念,任务结构的结构名要解释成地址的话就是该结构的首地址,
我们得到结构是需要结构首地址,和结构大小的。。。(当时我是这么说,肯定是错

的。。你暂时这么理解吧。。)

就你这个程序。。。。array是代表“int array[2] = {};”这个数组的首地址
那么“int array[2] = {};”这个数组的首地址就是0x7fff554bab2c(因为是64位系

统),而&array代表的意义是取“int array[2] = {};”这个数组的地址,你要知道

array既可以代表这个数组,也可以代表这个数组的首地址,所以array和&array的

意义是一样的,二者没有区别--->

array---->数组首地址
&array--->取这个数组结构的首地址
你自己想想,体会一下

array+1就是array[1]的意思
array[1]是可以看做是简写的array+1
懂?

而&array。。正如上面所说的是去结构的首地址(在本例中当然是数组结构了。)
那么这是的array这个单词是基于什么单元呢?就是结构单元,
也就是说&array+1,,,这是的+1就不是+1个int那么简单,而是array这个结构大小
你不信可以试试(char*)array + sizeof(array) 和 &array + 1是相等的。。。
&array+2就是(char*)array + 2*sizeof(array)

//注意体会(char*)这个强制转换的作用。。。。
array + 1 = array[1] = (char*)array + sizeof(array[0])
array + 2 = array[2] = (char*)array + 2*sizeof(array[0])
&array+1 = (char*)array + sizeof(array) &array+2 = (char*)array + 2*sizeof(array)

注意上面都用了(char*)强制转换,是为了让 array+5 = array+5,而不是array+5 = array + 5*(sizeof(int))

你自己体会下吧。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-23 03:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表