关于存储器的编址问题。 求教求教求教~

app16 2012-03-31 12:44:18
突然想起, 以前学C的时候说, int a=10, 是指一个存储单元中值为10,a为此存储单元的地址,
可是在C#中呢 ?! int a=10, int为一个类, a为一个类实例,a也是一个地址么!?
a中有很多方法, 方法名也是地址么!?

这些名称 在经过编译器编译之后, 都会变成存储器地址!? 名称的长度对程序的性能有影响么 !?

object a =new object(); a为实例的名称。 可是对于类名(Object) ,它算什么? 编译后也会变成地址!?

假设有一个1KB的内存,按字节编址就是0~1024(十进制),第一个字节对应1,第二个字节对应2, ...;程序访问第一个字节也是通过地址1找到存储单元的, 可是1也是个数据啊, 它怎么知道1就是那个存储单元, 这个1又在哪存着呢!? 它又是怎么来的?!


可能我的问题 是因为建立在一个错误的认知上而产生的这些问题!? 还请各位高手各位大哥们指点..感谢。
...全文
310 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2012-04-21
  • 打赏
  • 举报
回复
另外3L说的是不怎么正确的。
threenewbee 2012-04-21
  • 打赏
  • 举报
回复
就是说,当一个整数参与运算的时候,它实际上和C语言的整数没有区别。
当对一个整数调用诸如ToString() GetHashCode() Equals()之类属于object的成员的时候,会发生装箱,使得你看上去觉得一个整数也是一个对象一样。
这个过程是CLR幕后完成的。
app16 2012-04-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
虽然object看上去是所有类型的基类,但是出于性能的考虑,在.NET上引入了值变量和引用变量的概念。注意这个概念本身完全是为了性能而增加的。对于值类型,其实编译器只为它分配数据成员的空间,而那些看上去属于object的基类型成员,则是通过装箱/拆箱点缀上去的。
[/Quote]
我晕,貌似真正的大师才刚出现,,
那些看上去属于object的基类型成员,则是通过装箱/拆箱点缀上去的。
什么意思 !?
threenewbee 2012-04-21
  • 打赏
  • 举报
回复
首先你C就没学好。

int a = 10, 是指一个存储单元中值为10,a为此存储单元的地址,
这个说法并不确切。

正确的说法是,编译器会在堆栈上为这个整数分配4个字节的空间。a作为一个符号代表这个空间。

int* b = &a;

这个b存储的才是a的地址。

但是由于编译器优化的缘故,这些未必成立。
如果a没有再次使用,可能编译器根本不会编译它。
如果a定义后直接参与运算,有可能a被分配在寄存器上。


要想理解C#,首先要了解CLR,这是一部抽象的计算机。

深入的不理解算了,装箱拆箱还是应该了解下的。

虽然object看上去是所有类型的基类,但是出于性能的考虑,在.NET上引入了值变量和引用变量的概念。注意这个概念本身完全是为了性能而增加的。对于值类型,其实编译器只为它分配数据成员的空间,而那些看上去属于object的基类型成员,则是通过装箱/拆箱点缀上去的。
app16 2012-04-21
  • 打赏
  • 举报
回复
唉, 好久了, 结贴吧,呵呵, 谢谢xboxeer、moonwrite与sp1234的指点。
xboxeer 2012-04-21
  • 打赏
  • 举报
回复
个人建议看两本书
深入理解计算机系统 这边书了解机器级别程序如何运行
CLR VIA C# 这边书了解.net程序如何运行在CLR上面
[Quote=引用 7 楼 的回复:]

引用 6 楼 的回复:
这就是托管程序的概念,最起码地区别,它的地址概念跟c的所谓地址概念是不同的。


O.O ,, 这么深奥 !? 那我应该了解搜哪些知识点了解这些概念呢 !?
[/Quote]
app16 2012-04-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
这就是托管程序的概念,最起码地区别,它的地址概念跟c的所谓地址概念是不同的。
[/Quote]

O.O ,, 这么深奥 !? 那我应该了解搜哪些知识点了解这些概念呢 !?
  • 打赏
  • 举报
回复
这就是托管程序的概念,最起码地区别,它的地址概念跟c的所谓地址概念是不同的。
  • 打赏
  • 举报
回复
已经脱离了低级的物理概念。例如.net程序可以运行在32位或者64位机器上,而且内存中的对象是随时浮动的,但是对外开来对象的引用并没有改变。对象的地址已经不是c里边所说的地址,机制其安全不同,很多信息已经脱离了硬件的限制。
app16 2012-04-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
我看过的是这样的
CPU的寄存器分 我是这样分的
数据寄存器(寄存器指到的内存位置会被当成数据读取)
代码(方法)寄存器(寄存器指到的内存位置会被当成方法调用)
……
[/Quote]

哦, 谢谢了,最近没怎么上网,才看到,,
请问你能给我推荐一点关于这一类的文章 么!?
moonwrite 2012-04-05
  • 打赏
  • 举报
回复
我看过的是这样的
CPU的寄存器分 我是这样分的
数据寄存器(寄存器指到的内存位置会被当成数据读取)
代码(方法)寄存器(寄存器指到的内存位置会被当成方法调用)

比如内存10000这个位置
如果是数据寄存器指向10000 那么他就从这个位置开始读
读多长呢,根据数据类型来
byte读取8bit 也就是将10000到10008这个读到寄存器中
int会读取32bit 10000到10032 读取到寄存器 然后转成数字 当然还可以转换成字母 其他
反正内存中只是一堆1和0

数据寄存器可以读写10000这个位置
代码(方法)寄存器也可以读写10000这个位置
堆栈寄存器也可以读写10000这个位置

可是对于类名(Object) ,它算什么?
类型的作用是决定读取多少个byte(1byte=8bit) cpu通常是以为byte来读写的 不是bit
也就是说cpu的寄存器每次最少读写1byte

C#中有个方法列表的概念 它保证了强类型
方法的定义决定了2个东西
1.从哪里开始的0和1被当成方法
2.需要把多少个参数压入堆栈

再回答 它怎么知道1就是那个存储单元
其实在底层的编程中

数据寄存器可以读写10000这个位置
代码(方法)寄存器也可以读写10000这个位置
堆栈寄存器也可以读写10000这个位置

这个地方是非常有问题 任何寄存器可以读写10000这个位置
这样很容易让程序出错

另外 你可以想象一下
程序A 指向10000 写入8
程序B 指向10000 写入9
程序A 读取10000 读到的9了 它本来是想8+10 现在的结果是19了
很严重把

所以微软提成了进程这个概念
程序A 指向10000 写如8 其实由系统再分配真实内存位置 如20000
程序B 指向10000 写入9 其实由系统再分配真实内存位置 如30000
这样读写的时候就不会出问题了

同理 关于内存中数据是怎么读取的 已经有编译器或系统帮我们完成
怎么知道
当然还是告诉
寄存器从那个地方开始读写 读写多少byte(长度)




app16 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
你想问除了本身的数据之外 一个类的方法等等是怎么存放的吧?
每个引用类型对象在.net托管堆里面都有一个类型对象 也就是Type类 然后每个实例都有指向Type这个Type类的一个指针 Type类里面存放的是该类的元数据 也就是你说的方法等 然后初次调用方法的时候CLR会去这个TYPE类里面找对应方法的IL代码并将它编译为本地代码 同时修改元数据中方法地址到本地代码的内存地址 再次调用就会去这个……
[/Quote]

稍微, 懂了一点,,
xboxeer 2012-03-31
  • 打赏
  • 举报
回复
你想问除了本身的数据之外 一个类的方法等等是怎么存放的吧?
每个引用类型对象在.net托管堆里面都有一个类型对象 也就是Type类 然后每个实例都有指向Type这个Type类的一个指针 Type类里面存放的是该类的元数据 也就是你说的方法等 然后初次调用方法的时候CLR会去这个TYPE类里面找对应方法的IL代码并将它编译为本地代码 同时修改元数据中方法地址到本地代码的内存地址 再次调用就会去这个地址找方法的本地代码了

17,748

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧