| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1117 人关注过本帖
标题:指针,数组问题
只看楼主 加入收藏
huangapple
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:545
专家分:1790
注 册:2010-12-30
收藏
得分:0 
回复 3楼 犬虫门心
printf(" %p %p %p %d %d\n", a, ptr1, ptr1[-1], ptr1[-1], ptr2[0]);
这样输出的结果是下面的:
 0012FF70 0012FF80 00000004 4 33554432
怎么a的地址跟ptr1的地址是差16呢?
怎么ptr1【-1】的地址又跳转到00000004这边去了呢?
我太不懂了

勤能补拙,熟能生巧!
2011-02-18 22:20
zjsxwc
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:1
帖 子:252
专家分:601
注 册:2011-1-20
收藏
得分:0 
ptr1[-1]不是地址.。
他其实就是a[3]也就是4,a的地址跟ptr1的地址是差 就是 a[0]的地址跟a[3]的地址的差,因为每个int 4字节所以差是16

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 22:43
你们都要疼我哦
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:火星
等 级:贵宾
威 望:49
帖 子:1296
专家分:2746
注 册:2008-7-13
收藏
得分:0 
以下是引用huangapple在2011-2-18 22:20:33的发言:

printf(" %p %p %p %d %d\n", a, ptr1, ptr1[-1], ptr1[-1], ptr2[0]);
这样输出的结果是下面的:
 0012FF70 0012FF80 00000004 4 33554432
怎么a的地址跟ptr1的地址是差16呢?
怎么ptr1【-1】的地址又跳转到00000004这边去了呢?
我太不懂了

前2个输出明显是堆栈地址,牵扯到变量的分配和布局这些东西 学一下汇编 学学调试 很容易理解。


无非就是地址和偏移。 C在逻辑上把地址和偏移包装成指针。

现在都不开汇编课了吗?




3楼应该是位老师吧,现在学习C的朋友普遍缺少调试知识,朱老师如果
能借助IDE的调试功能讲解指针这方面的东东,会直观很多 更容易理解。

[ 本帖最后由 你们都要疼我哦 于 2011-2-19 00:30 编辑 ]

小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
2011-02-19 00:17
huangapple
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:545
专家分:1790
注 册:2010-12-30
收藏
得分:0 
没开汇编的

勤能补拙,熟能生巧!
2011-02-19 13:26
huangapple
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
帖 子:545
专家分:1790
注 册:2010-12-30
收藏
得分:0 
听了你们的话还是有点蒙

勤能补拙,熟能生巧!
2011-02-19 13:28
qq312154421
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:124
专家分:120
注 册:2010-6-7
收藏
得分:0 
楼主那是什么跟什么啊,看不懂啊

勤奋不止,自强不息。
2011-02-19 15:16
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
以下是引用zjsxwc在2011-2-18 19:48:23的发言:

期待啊
c对变量的地址 和 变量的内容 怎么存储的?两者有什么关系
zjsxwc,希望你能接受我下面的说法:
1、变量的本质是:内存中的一段连续存储空间,可以认为就是“空间”;
2、变量有3个要素:
    a、变量名称:用以区别于其他变量;但本质上是“人文化”的首地址;(这个概念我下面有专门论述)
    b、变量类型:对空间的字节数的约定和对其中二进制内容解释时的方式的约定;
    c、变量的值:对空间中的二进制内容按变量类型解释所得到的“适应于人”的结果(但于人的情感无关)。
3、变量的定义:
    a、变量必须先定义方可使用(C99也相同);
    b、定义变量的本质是:申请存储空间(所谓的静态存储分配,包括数组在内)!
4、除了机器语言以外的所有程序设计语言,所编写的源代码程序,都必须先转换成机器语言程序,方可执行。

第4点与前面的内容综合起来,将有下述推导:
1、编程者所编写的源代码,并不是最终的执行代码,都需要翻译成机器代码;
2、只有在源代码中才会出现“人文化”的“变量名称”,当源代码转换成机器代码后,所有的变量名称(包括数组名称、函数名称)统统不复存在,而是被真正的“地址”所替代;
3、在将源代码转换成机器代码的过程中,即,编译过程中,编译软件将“记住”每一个变量名称,并可以通过计算机内部机制得到该变量的首地址,但这仅限于变量(数组、函数),不适用于常量和表达式!
4、“变量的首地址”这个说法的更精确地表达是:“一段连续存储空间(变量)的多个字节中的第一个字节()的地址”!
5、从上面的说法可以知道,无论变量长度如何,其首地址永远是第一个“首”字节的地址(注意红颜色的两个字),那么,结论是:任何类型的变量,其首地址总是4B(以32位计算机系统为前提)!
6、这个4B的地址值,当然也可以保存在内存中,当然要消耗4B,而这种类型在C语言中,就被称为“指针”!

7、变量名称出现在C语言表达式不同的位置,其意义也有所不同:
A)在=(含+=、-=等运算符)左侧,应读作:某空间;
B)在=右侧和其他地方,应读作:某空间的值。
例如:int a, b = 3, c;
    a = b; //将b空间的值赋值给a空间
    c = a + b; //取a空间的值与b空间的值求和,和值赋值给c空间
请不要认为我这样做是故弄玄虚,这样说是将简单问题复杂化了,但其目的是将以后的复杂问题简单化!

两者的关系这个问题,其实是指针运算的问题,请允许我稍后随着有关问题阐述。
上述的问题简单,但与书上的说法又有些许差别,请仔细阅读,再回头看我在3楼的论述,可能会容易些了。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-02-19 16:02
ansic
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:恍惚窈冥
等 级:城市猎人
帖 子:1543
专家分:5367
注 册:2011-2-15
收藏
得分:0 
包含其他变量地址的变量称为指针变量或指针。(intel汇编语言程序设计P94)。32位模式下(保护模式)下的指针类型都是一个32位的偏移地址,也即4B

善人者,不善人之师;不善人者,善人之资。不贵其师,不爱其资,虽智大迷。
2011-02-19 16:14
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
以下是引用huangapple在2011-2-18 22:20:33的发言:

printf(" %p %p %p %d %d\n", a, ptr1, ptr1[-1], ptr1[-1], ptr2[0]);
这样输出的结果是下面的:
 0012FF70 0012FF80 00000004 4 33554432
怎么a的地址跟ptr1的地址是差16呢?
怎么ptr1【-1】的地址又跳转到00000004这边去了呢?
我太不懂了
printf(" %p %p %p %d %d\n", a, ptr1, ptr1[-1], ptr1[-1], ptr2[0]);
这样输出的结果是下面的:
 0012FF70     0012FF80       00000004                      4                           33554432
 这是a的值    这是ptr1的值   这是ptr1[-1]的十六进制的值    这是ptr1[-1]的十进制的值    这是ptr2[0]的值
从上面可以看到a和ptr1相差16,原因是:
前面的语句:ptr2 = (int *)(&a + 1);
关键是&a的类型!
1、&a是指针表达式,这个表达式的值将指向a,这就意味着这个指针指向数组,就是传说中的“指向数组的指针”,又称“行指针”,其指类为int[4],这是一个由4个int元素组成的一个16B空间;
2、根据我在三楼讲到的“指针+1”的概念,应该就是要加16B!
3、根据2,ptr1将指向a[4](这个元素不存在,但其位置所对应的字节是存在的,请仔细阅读我在3楼的解说);
4、那么ptr[-1]当然就应该是a[4 - 1],即a[3]了。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-02-19 16:33
xby841221
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-6-30
收藏
得分:0 
回复 3楼 犬虫门心
非常感谢!讲的很清楚了,但是如果再加上CPU大小端一起讲解会有更好的效果,我想这个问题初学的人应该会很常见。以下是CPU大小判断的C代码;
int    checkSystem()
{
    union    check
    {
        int    i;
        char    ch;
    }c;
    c.i =1;
    return(c.ch==1);
}
输出结果为1,CPU为Little-Endian型;输出结果为0,CPU为BIG-ENDIAN。
*ptr2在CPU为Little模式时:
01 00 00 00
02
00 00 00
03 00 00 00
04 00 00 00
根据小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
得出结果为:02 00 00 00,即:0x2000000。

*ptr2在CPU为Big模式时:
00 00 00 01
00
00 00 02
00 00 00 03
00 00 00 04
根据大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
得出结果为:00 00 01 00,  即:0x100。

理解有错的话,请加QQ:287068809指出,并讨论,希望不吝赐教!

[ 本帖最后由 xby841221 于 2011-2-19 18:44 编辑 ]
2011-02-19 17:55
快速回复:指针,数组问题
数据加载中...
 
   



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

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