c语言第22课,小甲鱼老师解释数组名是地址信息
我看反汇编觉的数组名和变量一样的,只是个别名lea eax,
scanf,只是数组前加了一个隐形的‘&‘ 只是一个符号而已
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:54 编辑
#include <stdio.h>
int main(void)
{
char str;
printf("请输入域名:");
scanf("%s", str);
printf("鱼C工作室的域名是:%s\n", str);
return 0;
}
这是源码 有没有老师肯定我一下 反汇编截图上传 #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 对一个普通变量赋值
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 对数组中的元素赋值
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:25 编辑
我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?) wow7jiao 发表于 2018-6-24 21:17
我说错了,数组名在需要的时候会自己提供地址(指针常量,指向固定地址的指针?)
什么? 本帖最后由 wow7jiao 于 2018-6-24 21:45 编辑
人造人 发表于 2018-6-24 21:36
什么?
数组名是指向固定的地址的指针,偏正语法指针常量 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 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))//*号是对的指针的间接解引用 先从最简单的来
#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
人造人 发表于 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的指针)在指针的类型上是有区别的。 好吧,你是对的
数组名就相当于是用 const 修饰了一下
页:
[1]