wow7jiao 发表于 2018-6-24 20:51:46

c语言第22课,小甲鱼老师解释数组名是地址信息

我看反汇编觉的数组名和变量一样的,只是个别名

lea eax,

scanf,只是数组前加了一个隐形的‘&‘

人造人 发表于 2018-6-24 20:51:47

只是一个符号而已

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,
0007F11E 89 45 E8             mov         dword ptr ,eax


        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,
0007F11E 89 45 E8             mov         dword ptr ,eax

wow7jiao 发表于 2018-6-24 20:52:29

本帖最后由 wow7jiao 于 2018-6-24 20:54 编辑

#include <stdio.h>

int main(void)
{
        char str;

        printf("请输入域名:");

        scanf("%s", str);

        printf("鱼C工作室的域名是:%s\n", str);



       

        return 0;
}

这是源码

wow7jiao 发表于 2018-6-24 20:53:39

有没有老师肯定我一下

wow7jiao 发表于 2018-6-24 20:55:48

反汇编截图上传

人造人 发表于 2018-6-24 21:02:37

#include <stdio.h>

int main(void)
{
0007F0D0 55                   push      ebp
0007F0D1 8B EC                mov         ebp,esp
0007F0D3 81 EC 74 02 00 00    sub         esp,274h
0007F0D9 53                   push      ebx
0007F0DA 56                   push      esi
0007F0DB 57                   push      edi
0007F0DC 8D BD 8C FD FF FF    lea         edi,
0007F0E2 B9 9D 00 00 00       mov         ecx,9Dh
0007F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0007F0EC F3 AB                rep stos    dword ptr es:
0007F0EE A1 00 70 13 00       mov         eax,dword ptr
0007F0F3 33 C5                xor         eax,ebp
0007F0F5 89 45 FC             mov         dword ptr ,eax
        int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr ,64h
        int *p = &a;
0007F0FF 8D 45 F4             lea         eax,
0007F102 89 45 E8             mov         dword ptr ,eax
        int arr;
        arr = 10;
0007F105 B8 04 00 00 00       mov         eax,4
0007F10A 6B C8 00             imul      ecx,eax,0
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr arr,0Ah

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,
0007F11E 89 45 E8             mov         dword ptr ,eax

        return 0;
0007F121 33 C0                xor         eax,eax
}
0007F123 52                   push      edx
0007F124 8B CD                mov         ecx,ebp
0007F126 50                   push      eax
0007F127 8D 15 48 F1 07 00    lea         edx,ds:
0007F12D E8 0F C2 FF FF       call      @_RTC_CheckStackVars@8 (07B341h)
0007F132 58                   pop         eax
0007F133 5A                   pop         edx
0007F134 5F                   pop         edi
0007F135 5E                   pop         esi
0007F136 5B                   pop         ebx
0007F137 8B 4D FC             mov         ecx,dword ptr
0007F13A 33 CD                xor         ecx,ebp
0007F13C E8 EB C2 FF FF       call      @__security_check_cookie@4 (07B42Ch)
0007F141 8B E5                mov         esp,ebp
0007F143 5D                   pop         ebp
0007F144 C3                   ret

#include <stdio.h>

int main(void)
{
0007F0D0 55                   push      ebp
0007F0D1 8B EC                mov         ebp,esp
0007F0D3 81 EC 74 02 00 00    sub         esp,274h
0007F0D9 53                   push      ebx
0007F0DA 56                   push      esi
0007F0DB 57                   push      edi
0007F0DC 8D BD 8C FD FF FF    lea         edi,
0007F0E2 B9 9D 00 00 00       mov         ecx,9Dh
0007F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0007F0EC F3 AB                rep stos    dword ptr es:
0007F0EE A1 00 70 13 00       mov         eax,dword ptr ds:
0007F0F3 33 C5                xor         eax,ebp
0007F0F5 89 45 FC             mov         dword ptr ,eax
        int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr ,64h
        int *p = &a;
0007F0FF 8D 45 F4             lea         eax,
0007F102 89 45 E8             mov         dword ptr ,eax
        int arr;
        arr = 10;
0007F105 B8 04 00 00 00       mov         eax,4
0007F10A 6B C8 00             imul      ecx,eax,0
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr ,0Ah

        p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,
0007F11E 89 45 E8             mov         dword ptr ,eax

        return 0;
0007F121 33 C0                xor         eax,eax
}
0007F123 52                   push      edx
0007F124 8B CD                mov         ecx,ebp
0007F126 50                   push      eax
0007F127 8D 15 48 F1 07 00    lea         edx,ds:
0007F12D E8 0F C2 FF FF       call      0007B341
0007F132 58                   pop         eax
0007F133 5A                   pop         edx
0007F134 5F                   pop         edi
0007F135 5E                   pop         esi
0007F136 5B                   pop         ebx
0007F137 8B 4D FC             mov         ecx,dword ptr
0007F13A 33 CD                xor         ecx,ebp
0007F13C E8 EB C2 FF FF       call      0007B42C
0007F141 8B E5                mov         esp,ebp
0007F143 5D                   pop         ebp
0007F144 C3                   ret

人造人 发表于 2018-6-24 21:06:14

对一个普通变量赋值
      int a = 100;
0007F0F8 C7 45 F4 64 00 00 00 mov         dword ptr ,64h

取一个普通变量的地址,然后赋值给一个指针
      int *p = &a;
0007F0FF 8D 45 F4             lea         eax,
0007F102 89 45 E8             mov         dword ptr ,eax


把数组名赋值给指针
      p = arr;
0007F118 8D 85 50 FE FF FF    lea         eax,
0007F11E 89 45 E8             mov         dword ptr ,eax

人造人 发表于 2018-6-24 21:07:13

对数组中的元素赋值

      arr = 10;
0007F105 B8 04 00 00 00       mov         eax,4
0007F10A 6B C8 00             imul      ecx,eax,0
0007F10D C7 84 0D 50 FE FF FF 0A 00 00 00 mov         dword ptr ,0Ah

wow7jiao 发表于 2018-6-24 21:17:57

本帖最后由 wow7jiao 于 2018-6-24 21:25 编辑

我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?)

人造人 发表于 2018-6-24 21:36:41

wow7jiao 发表于 2018-6-24 21:17
我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?)

什么?

wow7jiao 发表于 2018-6-24 21:41:01

本帖最后由 wow7jiao 于 2018-6-24 21:45 编辑

人造人 发表于 2018-6-24 21:36
什么?

数组名是指向固定的地址的指针,偏正语法指针常量

人造人 发表于 2018-6-24 21:53:31

wow7jiao 发表于 2018-6-24 21:41
数组名是指向固定的地址的指针,偏正语法指针常量

就只是一个符号而已
你写
int a = 100;
编译器就知道你要访问dword ptr 内存单元,并把这个内存单元改写为 64h

你写
int b = 10;
编译器就知道你要访问dword ptr 内存单元,并把这个内存单元改写为 0ah

你写
a = b;
编译器就知道你要访问dword ptr 内存单元和 dword ptr 内存单元
并把 dword ptr 内存单元的值复制到 dword ptr 内存单元


        p = arr;
00C7F139 8D 85 44 FE FF FF    lea         eax,
00C7F13F 89 45 DC             mov         dword ptr ,eax

arr 就是一个地址,就是 ebp+FFFFFE44h 内存地址,把这个内存地址保存到 dword ptr 内存地址


#include <stdio.h>

int main(void)
{
00C7F0D0 55                   push      ebp
00C7F0D1 8B EC                mov         ebp,esp
00C7F0D3 81 EC 80 02 00 00    sub         esp,280h
00C7F0D9 53                   push      ebx
00C7F0DA 56                   push      esi
00C7F0DB 57                   push      edi
00C7F0DC 8D BD 80 FD FF FF    lea         edi,
00C7F0E2 B9 A0 00 00 00       mov         ecx,0A0h
00C7F0E7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00C7F0EC F3 AB                rep stos    dword ptr es:
00C7F0EE A1 00 70 D3 00       mov         eax,dword ptr ds:
00C7F0F3 33 C5                xor         eax,ebp
00C7F0F5 89 45 FC             mov         dword ptr ,eax
        int a = 100;
00C7F0F8 C7 45 F4 64 00 00 00 mov         dword ptr ,64h
        int b = 10;
00C7F0FF C7 45 E8 0A 00 00 00 mov         dword ptr ,0Ah
        a = 1;
00C7F106 C7 45 F4 01 00 00 00 mov         dword ptr ,1
        b = 2;
00C7F10D C7 45 E8 02 00 00 00 mov         dword ptr ,2
        a = b;
00C7F114 8B 45 E8             mov         eax,dword ptr
00C7F117 89 45 F4             mov         dword ptr ,eax
        b = a;
00C7F11A 8B 45 F4             mov         eax,dword ptr
00C7F11D 89 45 E8             mov         dword ptr ,eax

        int *p = &a;
00C7F120 8D 45 F4             lea         eax,
00C7F123 89 45 DC             mov         dword ptr ,eax
        int arr;
        arr = 10;
00C7F126 B8 04 00 00 00       mov         eax,4
00C7F12B 6B C8 00             imul      ecx,eax,0
00C7F12E C7 84 0D 44 FE FF FF 0A 00 00 00 mov         dword ptr ,0Ah

        p = arr;
00C7F139 8D 85 44 FE FF FF    lea         eax,
00C7F13F 89 45 DC             mov         dword ptr ,eax

        return 0;
00C7F142 33 C0                xor         eax,eax
}
00C7F144 52                   push      edx
00C7F145 8B CD                mov         ecx,ebp
00C7F147 50                   push      eax
00C7F148 8D 15 68 F1 C7 00    lea         edx,ds:
00C7F14E E8 EE C1 FF FF       call      00C7B341
00C7F153 58                   pop         eax
00C7F154 5A                   pop         edx
00C7F155 5F                   pop         edi
00C7F156 5E                   pop         esi
00C7F157 5B                   pop         ebx
00C7F158 8B 4D FC             mov         ecx,dword ptr
00C7F15B 33 CD                xor         ecx,ebp
00C7F15D E8 CA C2 FF FF       call      00C7B42C
00C7F162 8B E5                mov         esp,ebp
00C7F164 5D                   pop         ebp
00C7F165 C3                   ret

wow7jiao 发表于 2018-6-24 22:52:37

本帖最后由 wow7jiao 于 2018-6-24 23:07 编辑

人造人 发表于 2018-6-24 21:53
就只是一个符号而已
你写
int a = 100;


int main()
{
        char str[] = "I love FishC.com";
        int count = 0;

        while (*str++ != '\0')
        {
                count++;
        }

        printf("总共有%d个字符\n", count);



       

        return 0;


------------------------------------------
c语言23课,把str当地址++,又提示str不是左值,22课视频的后半部分,b是数组名,*b ,*(b+1),*(b+2)又是正确,我现在把数组名当指针常量正好可以完美的解释^_^指针常量里面放着地址常量



#include <stdio.h>

int main()
{
        char a[] = "FishC";
        int b = {1, 2, 3, 4, 5};
        float c = {1.1, 2.2, 3.3, 4.4, 5.5};
        double d = {1.1, 2.2, 3.3, 4.4, 5.5};

        // int *p = b;

        // printf("*p = %d, *(p+1) = %d, *(p+2) = %d\n", *p, *(p+1), *(p+2));
        printf("*b = %d, *(b+1) = %d, *(b+2) = %d\n", *b, *(b+1), *(b+2));

      /*
        printf("a -> %p, a -> %p, a -> %p\n", &a, &a, &a);
        printf("b -> %p, b -> %p, b -> %p\n", &b, &b, &b);
        printf("c -> %p, c -> %p, c -> %p\n", &c, &c, &c);
        printf("d -> %p, d -> %p, d -> %p\n", &d, &d, &d);
      */

        return 0;
}

正好把22课这个部分也可以对上
printf("*b = %d, *(b+1) = %d, *(b+2) = %d\n", *b, *(b+1), *(b+2))//*号是对的指针的间接解引用

人造人 发表于 2018-6-24 23:34:31

先从最简单的来

#include <stdio.h>

int main(void)
{
        int a;
        a = 100;
        a = 0;

        return 0;
}


#include <stdio.h>

int main(void)
{
0105F0A0 55                   push      ebp
0105F0A1 8B EC                mov         ebp,esp
0105F0A3 81 EC CC 00 00 00    sub         esp,0CCh
0105F0A9 53                   push      ebx
0105F0AA 56                   push      esi
0105F0AB 57                   push      edi
0105F0AC 8D BD 34 FF FF FF    lea         edi,
0105F0B2 B9 33 00 00 00       mov         ecx,33h
0105F0B7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0105F0BC F3 AB                rep stos    dword ptr es:
        int a;
        a = 100;
0105F0BE C7 45 F8 64 00 00 00 mov         dword ptr ,64h
        a = 0;
0105F0C5 C7 45 F8 00 00 00 00 mov         dword ptr ,0

        return 0;
0105F0CC 33 C0                xor         eax,eax
}
0105F0CE 5F                   pop         edi
0105F0CF 5E                   pop         esi
0105F0D0 5B                   pop         ebx
0105F0D1 8B E5                mov         esp,ebp
0105F0D3 5D                   pop         ebp
0105F0D4 C3                   ret



        a = 100;
0105F0BE C7 45 F8 64 00 00 00 mov         dword ptr ,64h

ebp - 8 的值就是变量 a 的地址

ebp 现在是 0x0053f8c4
0x0053f8c4 - 8 = 0x53f8bc
0x53f8bc 就是变量 a 的地址

mov         dword ptr ,64h
就是把 0x53f8bc 地址的内容改写为 0x64

执行 mov         dword ptr ,64h之前 0x53f8bc 内存地址中保存的值是 0xcccccccc
执行之后 0x53f8bc 内存地址中保存的值是 0x00000064



wow7jiao 发表于 2018-6-25 10:47:19

人造人 发表于 2018-6-24 23:34
先从最简单的来




谢谢老师截图解释

我老是在说数组名是指针常量,其实看了《c和指针》说法。

https://blog.csdn.net/daniel_ice/article/details/6857019

首先引用《C和指针》p141中的理论:
在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向int的常量指针“。
看到这里我想应该就知道为什么 会有I 和 III式的结果了。

对于II 和 IV 则是特殊情况,在《C和指针》p142中说到,在以下两中场合下,数组名并不是用指针常量来表示,就是当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量的指针。
所以&a后返回的指针便是指向数组的指针,跟a(一个指向a的指针)在指针的类型上是有区别的。

人造人 发表于 2018-6-25 11:46:38

好吧,你是对的
数组名就相当于是用 const 修饰了一下




页: [1]
查看完整版本: c语言第22课,小甲鱼老师解释数组名是地址信息