当我在C ++程序中创建一个新变量时,例如char:
1.) In PHP, its automatically convert Type Casting.
2.) Rules of Type Casting :
2.1) int + int = int
2.2) string + string = string
2.3) float + float = double
2.4) int + string = int
2.5) float + string = double
2.6) int + float = double
C ++如何在内存中访问此变量?我想象它需要存储变量的内存位置,但那需要一个指针变量,并且需要再次访问该指针。
答案 0 :(得分:3)
请参阅docs:
声明变量时,存储其值所需的内存为 在内存中分配了一个特定的位置(其内存地址)。 通常,C ++程序不会主动确定确切的内存 存储变量的地址。幸运的是,那个任务是 离开程序运行的环境 - 通常是一个 决定特定内存位置的操作系统 运行。但是,程序能够获得它可能是有用的 运行时期间变量的地址,以便访问数据单元格 相对于它的某个位置。
您还可以在Variables and Memory
上查阅此文章筹码
堆栈是局部变量和函数参数所在的位置。它 被称为堆栈,因为它遵循后进先出原则。 随着数据被添加或推送到堆栈,它会增长,并且当数据增加时 删除或弹出它缩小。实际上,内存地址不是 每次推送或弹出数据时,物理移动 堆栈,而不是堆栈指针,顾名思义指向 堆栈顶部的内存地址,上下移动。 这个地址以下的所有内容都被认为是在堆栈上 可用,而它上面的所有东西都不在堆栈中,并且无效。 这一切都是由操作系统自动完成的 结果它有时也称为自动记忆。在 非常罕见的情况,一个人需要能够明确 调用这种类型的内存,可以使用C ++关键字auto。 通常,会在堆栈上声明变量,如下所示:
void func () { int i; float x[100]; ... }
在堆栈上声明的变量仅在 他们的声明范围。这意味着当列出函数func()时 以上返回,i和x将不再可访问或有效。
放置在堆栈上的变量还有另一个限制: 操作系统只分配一定的空间 堆。正在执行的程序的每个部分都会进入 范围,操作系统分配适当的内存量 这是将所有局部变量保存在堆栈上所必需的。如果这 大于操作系统允许的内存量 堆栈的总大小,然后程序将崩溃。虽然 有时可以通过编译时改变堆栈的最大大小 参数,它通常相当小,远远不及总数 机器上可用的RAM量。
答案 1 :(得分:2)
C ++本身(或编译器)可以根据程序结构访问此变量,表示为数据结构。也许你问的是程序中的其他部分如何在运行时访问它。
答案是它有所不同。它可以存储在寄存器,堆栈,堆上或data / bss部分(全局/静态变量)中,具体取决于它的上下文和为其编译的平台:如果需要传递它通过引用(或指针)到其他函数,它可能会存储在堆栈中。如果您只需要在函数的上下文中,它可能会在寄存器中处理。如果它是堆上对象的成员变量,那么它就在堆上,并通过偏移量引用它到对象中。如果它是全局/静态变量,则一旦程序完全加载到内存中,就会确定其地址。
C ++最终会编译成机器语言,并且通常在操作系统的上下文中运行,所以你可能想要了解一下Assembly基础知识,甚至是一些操作系统原理,以便更好地理解引擎盖下发生的事情。
答案 2 :(得分:1)
假设这是一个局部变量,则该变量在堆栈上分配 - 即在RAM中。编译器跟踪堆栈上的变量偏移量。在基本场景中,如果随后使用变量执行任何计算,则将其移动到处理器的一个寄存器中并且CPU执行计算。然后将结果返回到RAM。现代处理器将整个堆栈帧保留在寄存器中并具有多级寄存器,因此它可能变得非常复杂。
请注意二进制文件中不再提及“c”名称(除非您有调试符号)。二进制文件仅适用于内存位置。例如。它看起来像这样(简单的加法):
a = b + c
take value of memory offset 1 and put it in the register 1
take value of memory offset 2 and put in in the register 2
sum registers 1 and 2 and store the result in register 3
copy the register 3 to memory location 3
二进制文件不知道“a”,“b”或“c”。编译器只是说“a在内存1中,b在内存2中,c在内存3中”。 CPU只是盲目地执行编译器生成的命令。
答案 3 :(得分:0)
假设我们的程序以堆栈地址4000000
开头当你调用一个函数时,根据你使用的堆栈数量,它会像这样“分配”
假设我们有2个整数(8字节)
int function()
{
int a = 0;
int b = 0;
}
然后会在集会中发生什么
MOV EBP,ESP
//这里我们将堆栈地址的原始值(4000000)存储在EBP中,并在函数末尾将其恢复为4000000
SUB ESP, 8
//这里我们在堆栈中“分配”8个字节,这基本上只是将ESP addr减少了8个
所以我们的ESP地址已经改变了 4000000 至 3999992
程序知道第一个int的堆栈地址是“3999992”,第二个int是3999996到4000000
即使这几乎与编译器无关,知道这一点非常重要,因为当你知道如何“分配”堆栈时,你会意识到执行这样的事情是多么便宜
char my_array [20000]; 因为它所做的只是做sub esp,20000这是一个单独的汇编指令
但是如果你真的使用像memset(my_array,20000)那样的所有字节,那就是不同的历史。
答案 4 :(得分:0)
C ++如何在内存中访问此变量?
它没有!
您的计算机执行此操作,并通过将内存中变量的位置加载到寄存器中来指示如何执行此操作。这全部由汇编语言处理。我不会在这里详细介绍这些语言是如何工作的(你可以查阅它!)但这更像是C ++编译器的目的:将一组抽象的,高级的“指令”转换为计算机可以理解和执行的实际技术说明。您可以说汇编程序包含很多指针,但大多数都是文字而不是“变量”。