| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1205 人关注过本帖
标题:&运算符的一些问题,不要以为很简单。
只看楼主 加入收藏
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
结帖率:100%
收藏
已结贴  问题点数:100 回复次数:28 
&运算符的一些问题,不要以为很简单。
我今天复习C语言,看到书对&运算符的一些介绍,有回忆起论坛里面的曾经的一些问题。
int a[10],b;
int *c,(*d)[10];
c=&b;
d=&a;
以上是否对?原因说明一下! 为什么d在数值上等于a?
还有a是否有存储地址?如果有,&a为什么不是得到存储a的地址?
还是&运算符对待a、b方法不一样?或者说&对待数组名和普通变量不一样?


我对于C的一些东西开始越来越困惑了,希望有人帮我一下,我知道上面那几个表达式都是对的,以前我以为我理解,但现在我回过头来在看这些才发现,我什么也不知道!
大家帮帮我!谢谢!

[ 本帖最后由 饭桶 于 2011-9-11 19:31 编辑 ]
搜索更多相关主题的帖子: 存储 东西 表达式 C语言 
2011-09-11 19:06
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你是不是觉得语法对编译没报告错误就是对的?

授人以渔,不授人以鱼。
2011-09-11 19:10
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 2楼 TonyDeng
那你的意思是这个都是错的?一点理论方面的支持都没有?好像有一点吧。

人得一生得奋斗!
2011-09-11 19:15
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:5 
我没说这是错的。我看你搞不清楚对错其实在于写代码的人想达到什么目的。你说这代码,希望d是什么东西?代码跟愿望吻合吗?吻合就对,不吻合就错。

授人以渔,不授人以鱼。
2011-09-11 19:17
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 4楼 TonyDeng
但是d在数值上等于a ,这些本来就没有太大实际意义,没有人会故意这么去写这种代码。
但为什么d在数值上等于a?a有没有存储地址?我现在想知道这些.

人得一生得奋斗!
2011-09-11 19:23
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
d=&a
a是地址,&a是这个地址的地址,也是自己,你说d能是多少?

授人以渔,不授人以鱼。
2011-09-11 19:35
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 6楼 TonyDeng
明白了。我学过汇编语言一段时间,我一直试图去理解c的一些操作,用汇编去理解,从最底层去理解。
在编译的时候编译器是怎么对待变量名的呢?是不是与数组名一样?我刚学的时候就有这么一个困惑,我脑袋不是太好,到现在都还没有完全想明白,我希望你帮我一下,谢谢!

人得一生得奋斗!
2011-09-11 19:44
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:5 
这是你那个代码的汇编,自己看看:

程序代码:
; 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
_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 38     sub     esp, 56            ; 00000038H
  00006    56         push     esi
  00007    57         push     edi
  00008    8d 7d c8     lea     edi, DWORD PTR [ebp-56]
  0000b    b9 0e 00 00 00     mov     ecx, 14            ; 0000000eH
  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];
; 7    :     int (*d)[10];
; 8    :
; 9    :     d = &a;

  00021    8d 45 d0     lea     eax, DWORD PTR _a$[ebp]
  00024    89 45 c8     mov     DWORD PTR _d$[ebp], eax

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

  00027    8b f4         mov     esi, esp
  00029    8b 4d c8     mov     ecx, DWORD PTR _d$[ebp]
  0002c    51         push     ecx
  0002d    8b 55 c8     mov     edx, DWORD PTR _d$[ebp]
  00030    52         push     edx
  00031    8d 45 d0     lea     eax, DWORD PTR _a$[ebp]
  00034    50         push     eax
  00035    8d 4d d0     lea     ecx, DWORD PTR _a$[ebp]
  00038    51         push     ecx
  00039    8d 55 d0     lea     edx, DWORD PTR _a$[ebp]
  0003c    52         push     edx
  0003d    68 00 00 00 00     push     OFFSET $SG-5
  00042    ff 15 00 00 00
    00         call     DWORD PTR __imp__printf
  00048    83 c4 18     add     esp, 24            ; 00000018H
  0004b    3b f4         cmp     esi, esp
  0004d    e8 00 00 00 00     call     __RTC_CheckEsp

; 11   :     _getwch();

  00052    8b f4         mov     esi, esp
  00054    ff 15 00 00 00
    00         call     DWORD PTR __imp___getwch
  0005a    3b f4         cmp     esi, esp
  0005c    e8 00 00 00 00     call     __RTC_CheckEsp

; 12   : }

  00061    33 c0         xor     eax, eax
  00063    52         push     edx
  00064    8b cd         mov     ecx, ebp
  00066    50         push     eax
  00067    8d 15 00 00 00
    00         lea     edx, DWORD PTR $LN5@main
  0006d    e8 00 00 00 00     call     @_RTC_CheckStackVars@8
  00072    58         pop     eax
  00073    5a         pop     edx
  00074    5f         pop     edi
  00075    5e         pop     esi
  00076    8b 4d fc     mov     ecx, DWORD PTR __$ArrayPad$[ebp]
  00079    33 cd         xor     ecx, ebp
  0007b    e8 00 00 00 00     call     @__security_check_cookie@4
  00080    83 c4 38     add     esp, 56            ; 00000038H
  00083    3b ec         cmp     ebp, esp
  00085    e8 00 00 00 00     call     __RTC_CheckEsp
  0008a    8b e5         mov     esp, ebp
  0008c    5d         pop     ebp
  0008d    c3         ret     0
  0008e    8b ff         npad     2
$LN5@main:
  00090    01 00 00 00     DD     1
  00094    00 00 00 00     DD     $LN4@main
$LN4@main:
  00098    d0 ff ff ff     DD     -48            ; ffffffd0H
  0009c    28 00 00 00     DD     40            ; 00000028H
  000a0    00 00 00 00     DD     $LN3@main
$LN3@main:
  000a4    61         DB     97            ; 00000061H
  000a5    00         DB     0
_main    ENDP
_TEXT    ENDS
END

授人以渔,不授人以鱼。
2011-09-11 19:48
饭桶
Rank: 6Rank: 6
等 级:侠之大者
帖 子:165
专家分:422
注 册:2011-4-5
收藏
得分:0 
回复 8楼 TonyDeng
我知道我错了,我承认我错了。你能不能用语言描述一下,我汇编只是了解了一下,了解汇编可以更好的理解指针,我用功不深。你随便描述一下嘛。如果我想了解这些该去看一些什么书?前辈啊,给点建议,谢谢!

人得一生得奋斗!
2011-09-11 19:55
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:25 
楼主理解有误,估计你是看国人书籍出身的,或者是对C的数据结构没有个具体的理解。由于隐藏了内部实现,所以不抽象的东西变得难学了,其实不然,个人觉得一个专业写代码的应该从机器或汇编开始学起,之前还要大致了解计算机内部物理实现。敢问国人中有多少人是这样学的?这大多不能怪我们,因为非自学的朋友都是按照老师的指导进行的,所以大多数的老师也是这样心存疑惑的。这说明了教学规划有问题,好像一直没有改善过,还是他们一直没明白这样做是错的?在美国,稍微在代码行业有点名声的人,谁不是从最底层开始的?以致于他们能轻松架构一个操作系统?作为一个自学的人,我明白了这些,幸运的是我们还可以自己去做自己想做的事情。这也证明了国外书籍通常比国内书籍厚的原因,因为有很大一部分在于去解释那些晦涩的原理去了。

int a[10],b;
int *c,(*d)[10];
c=&b;  // 因为&b的返回值是int *类型而c也是int *,所以没问题。
d=&a;  // 因为&a的返回值是int (*)[10]类型而d也是int (*)[10]类型,所以没问题。

每当声明一个数据类型,这个数据类型的信息就会被保存下来,这个信息应该存放在可执行文件里,使用操作符时都会得到该变量的信息。当然这些是自己理解的,至于C是如何实现的我也不明白,一种感觉告诉我C是这样做的。这也许是证明以前的C不支持变长数组的原因吧?

但是d在数值上等于a ,这些本来就没有太大实际意义,没有人会故意这么去写这种代码。
但为什么d在数值上等于a?a有没有存储地址?我现在想知道这些.

这可能是a主要是为了去引用这个数组信息的句柄吧。

My life is brilliant
2011-09-11 19:58
快速回复:&运算符的一些问题,不要以为很简单。
数据加载中...
 
   



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

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