user-0 提问: 编译器如何解析指针

回复:
user: user-1
content: 谢谢分享

user: user-2
content: 指针是烧脑的难题。。。

user: user-3
content: 这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做...所以要定制一款cpu ,具备初级的编译变量指针的功能和简单的内存管理功能.

user: user-3
content: 这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做

user: user-3
content: 这部分 我认为 应该 cpu硬件自己去做.不应该由编译器软件做

user: user-4
content: 数据在内存里存储的位置就是地址，在c语言里就是指针，如果没有操作系统的话，这个地址在硬件上是固定的，也是一个8位or16位or32位...的二进制数据，也可以保存。 所以指针类似int变量，保存的也只是一串01而已，访问数据的时候根据那一串地址找到位置读数据，但读出来的一串01你不知道它是哪国语言，还要翻译，所以指针还要有一个类型，这个类型就是告诉你这串01应该翻译成什么语言

user: user-5
content: example:  "int *p"                    ===> 0x000001                    ===> record of cpu [M(0x000001)]                   ===> [M(0x000001) + rs(32/64)] * (0x000001 >> 0x00000F)                   ===> [M(0x00001)] go [M(rs(32/64))]                   ===> rs--                   ===> 0x000000                   ===> "int * p" = 0x000000 == null

user: user-6
content: int *p; int a; p = &a;上面p是指针，指向a的地址。 编译器如何解析指针？ 编译器在做语法分析时，遇到*时，会将其值视为一个指针，而不是数值；在遇到&时，会做取地址的操作。这些逻辑上不会有什么问题吧？

user: user-7
content: http://bbs.csdn.net/topics/391945880

user: user-8
content: 查看汇编的寻址就可以了。。

user: user-9
content: 指针也是一种变量，只不过用来表示地址的

user: user-10
content: 补充： 计算机将整数作为标识内存地址来使用，其能使用的最大内存长度就是无符号整数的最大值， 8位，16位、32位CPU就是整数的长度，其相应的指针范围也就相应不同。 指针计算中，如char *p, *p1, *p2；p = p1 + 3; int i = p1 - p2; 编译器都是完全当成整数进行编译。

user: user-10
content: 指针的本质就是使用一个int来记录内存地址，所以它的具体实现完全等同与int，在汇编级别就是一个int，它的存储和读取都和int完全一样，可以自由的与int进行转换和使用，空指针就是整数0，也就是NULL。  做为指针它完全不需要一定存在它所指向的内存前面，它可以存在int可以存在的任何位置，对编译器来说，重点就是将这个int当指针来使用，在编泽中，它会将其按其所指向的数据类型进行对应的读写数据编译。  举例：我们在一个子程序中写下: char a[10];(此只为举例，假设a首地址为：0x12345678) char *p = a; 编程器就会将指针p在内存上视为一个int，和其它的变量完全一样在栈中给它一个整数长度的内存，然后在这个内存中写入数组a的第一个内存地址0x12345678这个整数值，如果你完全能确定a的地址，也可以直接写成: char *p = reinterpret_cast<char*>(0x12345678); //编译器将整数当成指针直接进行赋值 或者 *reinterpret_cast<int *>(&p) = 0x12345678;	//编译器将字符指针直接当成一个整数来用，使用整数赋值   编译器在计算时将其作为整数处理，然后按其约定类型，如整数型指针还是字符型指针等，对使用它进行内存读写的代码进行相应编译，同一个指令在操作不同类型数据时，机器码会有一定变动。这段代码在CPU运行时，会先将p作为普通整数读取到寄存器中，再将这个寄存器视为地址寄存器，对此整数所指向的内存位置进行相应类型的数据读写。 如: mov ebx, [esp+4]  //假设p在栈中位置为esp + 4，先将esp+4这个内存视为普通整数装入ebx中      mov [ebx], 'c'  //将ebx中整数所指向的内存赋值为‘c'， 即*p = 'c'

user: user-11
content: 指针也是一个变量  指针也存在内存中。   指针中存储的是一个内存地址，直接到指针所指向的地址取出数据就行了（根据指针类型决定取多少个字节）  内存就是一个大的字节数组

user: user-12
content: 1、指针也是一个数据 2、不同CPU处理指针不同，但是一般都有一个数据地址寄存器，用于从某个地址取出数据 3、例如int i = &k; 在汇编中要具体看CPU和编译器，可以参考： http://www.cnblogs.com/findumars/archive/2013/09/05/3302457.html  4. 寄存器间接寻址方式（寄存器在括号里） MOV BX,[DI] 操作数的有效地址用SI、DI、BX和BP等四个寄存器之一来指定，称这种寻址方式为寄存器间接寻址方式。 若有效地址用SI、DI和BX来指定，则其缺省的段寄存器为DS； 若有效地址用BP来指定，则其缺省的段寄存器为SS(即：堆栈段)。 5. 寄存器相对寻址方式（一个寄存器和一个立即数在括号里，并且还要计算） MOV BX, [SI+100H]

user: user-7
content: 想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！

user: user-13
content: 以python为例，系统会对所有的对象附上一个id值，这个值就是指针，当开发者需要调用时对象时，需要提供句柄（也即可以理解为标签），编译器会根据句柄的特性，找到所需要的地址空间

user: user-7
content: 楼主可以参考g++源代码中解析指针相关片断。 不过如果楼主因此过劳死的话，那纯属巧合，与本ID无关。

user: user-7
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-14
content: 想多了，都是数据操作而已，写程序是按编译器要求写的，编译器也不在乎这个那个的，倒是ide编写比编译器要考虑更多的事情，比如语法即时分析，各种跳转等。