| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1205 人关注过本帖
标题:&运算符的一些问题,不要以为很简单。
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
编译器视变量名为地址,这你看上面我给的编译结果就知道了。

授人以渔,不授人以鱼。
2011-09-11 20:06
pauljames
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:千里冰封
威 望:9
帖 子:1555
专家分:10000
注 册:2011-5-8
收藏
得分:3 
我的理解是:a是指向int类型的指针,d是指向10个int类型的指针;a=&a[0]=&*(a+0);&a就是指向10个int类型的了。期待高人指点。

经常不在线不能及时回复短消息,如有c/单片机/运动控制/数据采集等方面的项目难题可加qq1921826084。
2011-09-11 20:06
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:2 
8楼代码的原程序,语句
printf("a = %d, &a[0] = %d, &a = %d, d = %d, d[0] = %d\n", a, &a[0], &a, d, d[0]);
输出的数值全部一样。

授人以渔,不授人以鱼。
2011-09-11 20:08
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 10楼 lz1091914999
你说得对,我是看国人的书,对C的数据结构的确没有具体的理解,你是一针见血,数据结构我正在学,一本书看了一半,我现在求指教,以避免我走太多的弯路,谢谢您!

人得一生得奋斗!
2011-09-11 20:09
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
再看这个编译结果,对变量x、y是如何处理的:

程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE    C:\Users\TonyDeng\Documents\Visual Studio 2010\Projects\test4\test4\test.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB OLDNAMES

EXTRN    @__security_check_cookie@4:PROC
EXTRN    __imp__printf:PROC
EXTRN    __imp___getwch:PROC
$SG-5    DB    'a = %d, &a[0] = %d, &a = %d, d = %d, d[0] = %d', 0aH, 00H
PUBLIC    __$ArrayPad$
PUBLIC    _main
EXTRN    ___security_cookie:DWORD
EXTRN    @_RTC_CheckStackVars@8:PROC
EXTRN    __RTC_CheckEsp:PROC
; Function compile flags: /Odtp /RTCsu
; File c:\users\tonydeng\documents\visual studio 2010\projects\test4\test4\test.cpp
_TEXT    SEGMENT
_y$ = -64                        ; size = 4
_x$ = -60                        ; size = 4
_d$ = -56                        ; size = 4
_a$ = -48                        ; size = 40
__$ArrayPad$ = -4                    ; size = 4
_main    PROC

; 5    : {

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    83 ec 40     sub     esp, 64            ; 00000040H
  00006    56         push     esi
  00007    57         push     edi
  00008    8d 7d c0     lea     edi, DWORD PTR [ebp-64]
  0000b    b9 10 00 00 00     mov     ecx, 16            ; 00000010H
  00010    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  00015    f3 ab         rep stosd
  00017    a1 00 00 00 00     mov     eax, DWORD PTR ___security_cookie
  0001c    33 c5         xor     eax, ebp
  0001e    89 45 fc     mov     DWORD PTR __$ArrayPad$[ebp], eax

; 6    :     int a[10] = {0x10, 0x11};

  00021    c7 45 d0 10 00
    00 00         mov     DWORD PTR _a$[ebp], 16    ; 00000010H
  00028    c7 45 d4 11 00
    00 00         mov     DWORD PTR _a$[ebp+4], 17 ; 00000011H
  0002f    33 c0         xor     eax, eax
  00031    89 45 d8     mov     DWORD PTR _a$[ebp+8], eax
  00034    89 45 dc     mov     DWORD PTR _a$[ebp+12], eax
  00037    89 45 e0     mov     DWORD PTR _a$[ebp+16], eax
  0003a    89 45 e4     mov     DWORD PTR _a$[ebp+20], eax
  0003d    89 45 e8     mov     DWORD PTR _a$[ebp+24], eax
  00040    89 45 ec     mov     DWORD PTR _a$[ebp+28], eax
  00043    89 45 f0     mov     DWORD PTR _a$[ebp+32], eax
  00046    89 45 f4     mov     DWORD PTR _a$[ebp+36], eax

; 7    :     int (*d)[10];
; 8    :     int x = 0x20;

  00049    c7 45 c4 20 00
    00 00         mov     DWORD PTR _x$[ebp], 32    ; 00000020H

; 9    :     int y;
; 10   :
; 11   :     d = &a;

  00050    8d 4d d0     lea     ecx, DWORD PTR _a$[ebp]
  00053    89 4d c8     mov     DWORD PTR _d$[ebp], ecx

; 12   :     y = x;

  00056    8b 55 c4     mov     edx, DWORD PTR _x$[ebp]
  00059    89 55 c0     mov     DWORD PTR _y$[ebp], edx

; 13   :     printf("a = %d, &a[0] = %d, &a = %d, d = %d, d[0] = %d\n", a, &a[0], &a, d, d[0]);

  0005c    8b f4         mov     esi, esp
  0005e    8b 45 c8     mov     eax, DWORD PTR _d$[ebp]
  00061    50         push     eax
  00062    8b 4d c8     mov     ecx, DWORD PTR _d$[ebp]
  00065    51         push     ecx
  00066    8d 55 d0     lea     edx, DWORD PTR _a$[ebp]
  00069    52         push     edx
  0006a    8d 45 d0     lea     eax, DWORD PTR _a$[ebp]
  0006d    50         push     eax
  0006e    8d 4d d0     lea     ecx, DWORD PTR _a$[ebp]
  00071    51         push     ecx
  00072    68 00 00 00 00     push     OFFSET $SG-5
  00077    ff 15 00 00 00
    00         call     DWORD PTR __imp__printf
  0007d    83 c4 18     add     esp, 24            ; 00000018H
  00080    3b f4         cmp     esi, esp
  00082    e8 00 00 00 00     call     __RTC_CheckEsp

; 14   :     _getwch();

  00087    8b f4         mov     esi, esp
  00089    ff 15 00 00 00
    00         call     DWORD PTR __imp___getwch
  0008f    3b f4         cmp     esi, esp
  00091    e8 00 00 00 00     call     __RTC_CheckEsp

; 15   : }

  00096    33 c0         xor     eax, eax
  00098    52         push     edx
  00099    8b cd         mov     ecx, ebp
  0009b    50         push     eax
  0009c    8d 15 00 00 00
    00         lea     edx, DWORD PTR $LN5@main
  000a2    e8 00 00 00 00     call     @_RTC_CheckStackVars@8
  000a7    58         pop     eax
  000a8    5a         pop     edx
  000a9    5f         pop     edi
  000aa    5e         pop     esi
  000ab    8b 4d fc     mov     ecx, DWORD PTR __$ArrayPad$[ebp]
  000ae    33 cd         xor     ecx, ebp
  000b0    e8 00 00 00 00     call     @__security_check_cookie@4
  000b5    83 c4 40     add     esp, 64            ; 00000040H
  000b8    3b ec         cmp     ebp, esp
  000ba    e8 00 00 00 00     call     __RTC_CheckEsp
  000bf    8b e5         mov     esp, ebp
  000c1    5d         pop     ebp
  000c2    c3         ret     0
  000c3    90         npad     1
$LN5@main:
  000c4    01 00 00 00     DD     1
  000c8    00 00 00 00     DD     $LN4@main
$LN4@main:
  000cc    d0 ff ff ff     DD     -48            ; ffffffd0H
  000d0    28 00 00 00     DD     40            ; 00000028H
  000d4    00 00 00 00     DD     $LN3@main
$LN3@main:
  000d8    61         DB     97            ; 00000061H
  000d9    00         DB     0
_main    ENDP
_TEXT    ENDS
END


授人以渔,不授人以鱼。
2011-09-11 20:12
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:5 
回复 14楼 饭桶
我说的是“C的数据结构”,意思就是C内部的数据类型,就是说C是如何实现像float、double、int这样的数据结构的,以致于我们可以用C定义的操作符去使用它。最好的方法就是反汇编,但对于我们不是从基本开始学起的,而且很难找到一本好的汇编书籍,好的书籍都是英文版的,这里显得十分蛋疼。所以我们目前唯一要做的就是先把英语学好,然后去参考国外的文献,把计算机的整体结构弄明白和学习汇编语言,最后再回过头来学C,这似乎太疯狂了,但这是最好的解决方案。如果你只是为了应付老师,或者是用带着疑问的抽象去社会上挣点钱,那么就可以忽略。

My life is brilliant
2011-09-11 20:20
A13433758072
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广东潮州
等 级:小飞侠
威 望:1
帖 子:1182
专家分:2784
注 册:2010-7-22
收藏
得分:10 
回复 楼主 饭桶
仅供参考:你的代码有点错误! int a[10],b;变量就不用说了!数组?在内存一段连续的内存地址! int *c,(*d)[10];指针?指针是一个只能存放地址的变量(自己有来存放地址的空间),而int (*d)[10]呢?从运算符的优先等级可以看出这是个,数组指针同样也是指针,只不过,这个指针所指向的地址不是变量的地址,而是数组的地址,所以叫数组指针! c=&b; ﹠取地址的意思,把变量的地址,赋值给指针(指针是存放地址嘛,毕竟不能把变量的值赋值给它,那就直接吧变量内存的地址赋值给它咯) d=&a;这是错的 d=&a[0];数组指针,(上面已讲了),这个指针只能存放数组的地址,如果你把变量地址赋值给它,就会类型不符了 d=a即d=&a[0]把数组赋值给指针,数组名是地址,所以可以d=a而数组是一段连续的内存地址,第一个元素就是数组的地址d=&a[0]所以可以这样赋值! 我找了点资料,有关数组和指针的区别,个人认为数组名是只地址,指针是特殊变量,所存放的地址是可变的,还有的是,它是变量,有自己的空间! 资料如下 K&R C第二版第93页:
The unary operator&gives the address of an object.
第94页:
The unary operator * is the indirection or dereferencing operator;when applied to a pointer,it accesses the object the pointer points to.

再请看ccfaq第6.3节的问题及其解释,你以后肯定会遇到这个问题:
6.3 那么, 在C 语言中“指针和数组等价” 到底是什么意思?
在C 语言中对数组和指针的困惑多数都来自这句话。说数组和指针“等价”不表示它们相同, 甚至也不能互换。它的意思是说数组和指针的算法定义可以用指针方便的访问数组或者模拟数组。
特别地, 等价的基础来自这个关键定义:
一个T 的数组类型的左值如果出现在表达式中会蜕变为一个指向数组第一个成员的指针(除了三种例外情况); 结果指针的类型是T 的指针。
这就是说, 一旦数组出现在表达式中, 编译器会隐式地生成一个指向数组第一个成员地指针, 就像程序员写出了&a[0] 一样。例外的情况是, 数组为sizeof 或&操作符的操作数, 或者为字符数组的字符串初始值。
作为这个这个定义的后果, 编译器并那么不严格区分数组下标操作符和指针。在形如a[i] 的表达式中, 根据上边的规则, 数组蜕化为指针然后按照指针变量的方式如p[i] 那样寻址, 如问题6.2 所述, 尽管最终的内存访问并不一样。如果你
把数组地址赋给指针:
p = a;
那么p[3] 和a[3] 将会访问同样的成员。
参见问题6.6 和6.11。
参考资料: [K&R1, Sec. 5.3 pp. 93-6]; [K&R2, Sec. 5.3 p. 99]; [ISO, Sec.
6.2.2.1, Sec. 6.3.2.1, Sec. 6.3.6]; [H&S, Sec. 5.4.1 p. 124]。

[ 本帖最后由 A13433758072 于 2011-9-11 22:43 编辑 ]

一步一个脚印...............................默默地前进.....
诚邀乐于解答c菜鸟问题,的热心网友加入,  QQ群38490319
2011-09-11 20:23
A13433758072
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:广东潮州
等 级:小飞侠
威 望:1
帖 子:1182
专家分:2784
注 册:2010-7-22
收藏
得分:3 
回复 16楼 lz1091914999
有时间去学英语还不如去学点基础的知识

一步一个脚印...............................默默地前进.....
诚邀乐于解答c菜鸟问题,的热心网友加入,  QQ群38490319
2011-09-11 20:26
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 16楼 lz1091914999
C内部数据结构的话,我对它的了解是很少的,几乎空白,我是非计算机专业的学生。我现在应该好好学英语啊!国内好像没有讲C内部的,至少我没有发现,不然我早就把他买回来了。谢谢!

人得一生得奋斗!
2011-09-11 20:27
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
我感谢你们每一个回帖的人,谢谢你们!

人得一生得奋斗!
2011-09-11 20:29
快速回复:&运算符的一些问题,不要以为很简单。
数据加载中...
 
   



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

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