免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: jeanlove
打印 上一主题 下一主题

[原创]对指针的两点认识 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-11-06 11:43 |只看该作者
楼上的,c专家编程你肯定没看.
虽然这句话对的:对buf2[],&buf2根本就还是buf2

数组名就是字符串的首地址,不能改
但指针的时候,指针变量的内容存放字符串的首地址,所以想改成存放其他地址当然不是问题

论坛徽章:
0
12 [报告]
发表于 2008-11-06 11:49 |只看该作者
>> (1)如果buf2的声明不是char *buf2="efgh";而是char buf2[]="efgh";那么编译就会提示g(&buf2);失败
前面 scutan 已经说了。
定义为 char buf2[] = "efgh" 时,  &buf2 的类型是 char (*)[],而不是 char **,
所以编译器会因类型不符报错。



对指针的各种提取操作,包括*,**,*** 等形式,汇编能力强的话,最好的理解还是从编译器角度来看,
否则还是老老实实看文档,多做实验。

1、
void f(char* s)
{
 s[0]='8';
 s[1]='9';
}
--------------------------
编译器对 s 指针及其提取操作,s[0] = '8'; 会作如下处理:
mov eax,
mov [eax], '8'

>> 是s变量里的值,不是变量本身。地址值通过s传过来,给了eax,
     然后通过[eax] 往这个地址做 store 操作。



2、
void g(char **s)
{
  *s=global;
}
-------------------------------------
编译器对 *s = global; 的处理大概如下:

mov eax,
mov eax, [eax]
mov [eax], global    ---> global 一般是立即数

>> 多了一层提取操作。 
  地址值通过 s 传过来给了 eax ,然后取这个地址里面的值,当作是地址值。
  然后,再通过 [eax] 把这个当作是地址值的地址上 (取出来的值),做 store 操作。
  
  也就是对 ** 类型的操作示范。


可以想象,如果:

char c = 'a';
g(&c);

>> 强行通过 &c, 给g(),会有什么后果?
  mov eax,  &c           ---> c 变量本身的地址值
  mov eax, [eax]       ----> 这还没出现问题,eax 的值为 'a' (65)
  mov [eax], global   ----> 往 65 这个地址写东西,只有出错了。


若:char *p = &c;
     g(&p);

>> 调用端:
  lea eax, c          ---> offset c
      mov [p], eax     ---> [p] = offset c  

    lea eax, p          ---> offset p
      push eax

     这是正确的使用方法




3、
g(char*s)
{
    char** ps=&s
     ... ...
}
形参 s 与实参址是不同的,一般如:s => [ebp+8] (callee)
                                     实参 => [ebp-XX] (caller) 

论坛徽章:
0
13 [报告]
发表于 2008-11-06 12:39 |只看该作者
LS斑竹汇编很强哦!  :wink: :wink:

论坛徽章:
0
14 [报告]
发表于 2008-11-06 12:41 |只看该作者
通过汇编语言来分析,果然更容易理解。

理解了汇编还是牛啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP