| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1117 人关注过本帖
标题:指针,数组问题
只看楼主 加入收藏
xby841221
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-6-30
结帖率:0
收藏
 问题点数:0 回复次数:26 
指针,数组问题
请教论坛的高手们一个问题:
int main()
{
    int a[4]={1,2,3,4};
    int *ptr1=(int*)(&a+1);
    int *ptr2=(int*)((int)a+1);

    printf(" %x\n %x\n",ptr1[-1], *ptr2);
    return 0;
}
结果是多少?为什么?
*提示*,涉及到大小端问题。
搜索更多相关主题的帖子: 多少 return 
2011-02-18 18:32
刘定邦
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:687
专家分:1570
注 册:2010-9-21
收藏
得分:0 
上机编译一下看就知道了呀....
2011-02-18 18:38
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
甲:“这个问题深啊!”
我:“深?!我这深的多着那!”
且听我细细道来!
首先,得给大家讲一个目前国内(含国外,赫赫)所讲到的指针概念中都涉及,但都没有足够清晰解释的一个关于指针的概念:
指针有两个要素:
1、首地址(学过C的都知道)
2、指类(朱某人的专用术语):指针所指向的空间的类型。
指类的概念非常重要,是比首地址概念更重要、更要命的概念,原因如下:
指针之间的操作必须保证指针指类的一致性,如果参加运算的两个指针的指类不同,则至少会有编译的警告,多数是错误报告;
指针+(-)整型量,能使指针的指向发生更改,而更改量取决于指类长度!即,指针+1将得到指针值+sizeof(指针指类)的效果。
指针指类的判别方法是:在定义指针、数组的语句中,去掉一个*,剩余的内容与基本类型结合,就成为指类。例如:

char *cp;//去掉一个*,类型部分只剩char,那么char就是cp的指类;或者说,C语言对于cp所指向的空间仅按char解释。

float **pfp;//去掉一个*,类型部分是float *,那么float *就是fpf的指类;或者说,fpf指向类型为(float *)的指针空间(变量)(这里我用空间而不用变量,因为变量这个名词太混乱,简直就是一本混账);

int *ar[10];//这里要复杂些。首先在定义数组ar的语句中,有两个符号:*和[],按优先级,[]优先于*,因此[]优先与ar结合;此时将结合不是很紧密的部分与ar[10]分开,将得到:
int*      ar[10];从这里可以很清楚的知道,int*是数组ar的每个元素的类型,而ar是数组;

int (*ar)[10];//这个更复杂。由于()的存在,*与ar优先结合,此时可以将[10]前置,与int组合成:
int[10]     *ar;从这里可以很清楚地知道,int[10]是指针变量ar的指类,ar是指针变量!
接着,由于ar的指类是int[10](由10个int元素组成的一段连续存储空间,为40B),长度为40B,所以ar+1将移动40B!

有了这些知识了,我们可以看楼主提出的问题了:

int main()
{
    int a[4]={1,2,3,4};
    int *ptr1=(int*)(&a+1);
//这里&a是表达式,而且是指针表达式,且这个指针的指类是a的类型,是int[4];这是最关键的地方!
//&a+1,是典型的指针+1运算,按照我的理论,将使指向向后移动16B,指向数组a所申请的空间的下一个字节!
//也就是说,ptr1现在实质上指向了&a[4](这个地址所表示的字节是不以人的意志为转移而存在的!)
//那么,后面的ptr1[-1]很明显就是a[3]了!
    int *ptr2=(int*)((int)a+1);
//这里更微妙:
//首先看数组的数据在内存中的映像:
01(每行是一个字节,这里我用的是高高低低原则:高位数存放在高端字节(地址编号较大的字节))
00 //下面的操作,使ptr2指向这里 (新开始
00
00(上面4个B组成第一个元素)
02 //从新开始到这里,形成由ptr2所指向的int类型的“变量”(此时如果换成“空间”,那么就不存在感情上的问题了)
00
00
后面省略
    int *ptr2=(int*)((int)a+1);
//首先将a强制转换成int类型,那么它+1就是实实在在的+1,那么ptr2将指向上面所述的位置。此时再输出*ptr2,自然就会得到:02 00 00 00(对应十进制数:33554432)
    printf(" %x\n %x\n",ptr1[-1], *ptr2);
    return 0;
}

请大家验证!
建议将输入改为:
    printf(" %p %p %p %d %d\n", a, ptr1, ptr1, ptr1[-1], ptr2[0]);
那就能清晰了。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-02-18 19:11
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
ptr1指向的是 a[3] 地址下一个 未知的的东西,而ptr1[-1]就是a[3]了,也就输出4
ptr2 指向的是介于a[0],与a[1]之间的一个地址,比如a[0]地址是00000000,则 a[1]地址是00000004,ptr2地址是00000001,于是按int输出ptr2的内容就是 由地址 000000001 000000002 000000003 000000004 ,构成的东西,我不怎么懂汇编,大致就这个意思,而他的输出就取决与编译器对变量存储方式问题了,不同编译器不一样,楼上说的很清楚学习了

[ 本帖最后由 zjsxwc 于 2011-2-18 19:49 编辑 ]

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-02-18 19:28
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
C语言那些指针比汇编那些寄存器可怕得太多

小代码,大智慧
2011-02-18 19:36
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
以下是引用点线面在2011-2-18 19:36:47的发言:

C语言那些指针比汇编那些寄存器可怕得太多
如果你能懂寄存器,那么指针应该不难,关键问题还是内存的概念及其管理的知识。
大家可以就我的解释问些问题,我择日给大家逐一解释。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-02-18 19:38
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
回复 6楼 犬虫门心
期待啊
c对变量的地址 和 变量的内容 怎么存储的?两者有什么关系

[ 本帖最后由 zjsxwc 于 2011-2-18 19:59 编辑 ]

The tools I recommended:
GUI: CSharp(VS), QT;    Core Code: Plain C (Tiny C Compiler);    Web: Python, JavaScript;    Android: Java;    Embedded System: ASM&C (Linux)
2011-02-18 19:48
huangapple
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:545
专家分:1790
注 册:2010-12-30
收藏
得分:0 
GetAsyncKeyState()
用这个函数,msdn去查查这个函数的用法

勤能补拙,熟能生巧!
2011-02-18 20:19
huangapple
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:545
专家分:1790
注 册:2010-12-30
收藏
得分:0 
大哥,原谅我吧,我是想答另一个楼主的

勤能补拙,熟能生巧!
2011-02-18 20:20
waterstar
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:5
帖 子:984
专家分:2810
注 册:2010-2-12
收藏
得分:0 
地址加法的差异

冰冻三尺,非一日之寒;士别三日,不足刮目相看!
2011-02-18 21:41
快速回复:指针,数组问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.036569 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved