繁体   English   中英

C / C ++中的变量如何工作?

[英]How does a variable in C/C++ work?

C / C ++中的变量如何工作?

我的意思是,一个指针存储一个变量的地址然后你必须取消引用它来访问它所引用的对象,所以我认为一个变量是一个在使用时自动解除引用的指针......这有什么意义吗? ?

变量是计算机上内存位置的抽象(方便的名称)。 在C / C ++中,如果变量的类型为int ,则对于包含整数值的内存地址,它将是一个方便的名称。

并且变量不是自动解除引用的指针。 变量只保存它应该保持的值。 如果它是一个指针,它将保存一个内存地址,如果它是一个整数,它将保持一个整数值,如果它是一个浮点数,它将保持一个浮点数...依此类推......

请考虑以下定义

char *string="abc";
int b = 10;
int *bptr = &b;

我稍微简化一下并使用十进制值,变量(名称)是地址的占位符,在这些地方存储具体值。

Adr  content
1000 a b c 0    // "abc" : string literal '\0' terminated 
1004    1000    // *string: pointer to string (address 1000)
1008      10    // b = 10 : integer value
1012    1008    // *bptr  : pointer to &b 

通过使用例如printf(“%s \\ n”,string); 你不想复制整个字符串,而是给出字符串开始的地址(通过引用调用)。

读/写变量是在已知位置读/写一段字节。 “know location”是编译器已知的位置,它可以是:

  • 固定地址。 编译器知道全局变量的所有地址。 如果我们读/写一个全局变量,编译器就会发出如下指令:“读/写内存地址为0x00235A87”
  • 固定堆栈偏移量。 局部变量被压入堆栈。 指向堆栈顶部的指针(“堆栈指针”或“SP”)存储在处理器寄存器中。 编译器知道局部变量从堆栈顶部的偏移量。 如果我们读/写一个局部变量,编译器会发出如下指令:“在地址'SP-0x05'处读/写内存”。
  • 处理寄存器。 使用时,变量被加载到处理器寄存器中。 编译器知道哪些寄存器。 要使用它们,不需要存储器读/写,编译器只需放置使用寄存器的指令,例如:“将寄存器B的内容添加到寄存器A”。

访问变量实际上是以处理器指令的形式编写的算法。 变量可以是固定存储器地址,计算存储器地址(使用固定偏移量和寄存器中保存的值)或处理器寄存器的地址。 编译器放置在存储器/寄存器之间和寄存器/寄存器之间移动变量值的指令。 变量甚至可能不存在于内存中,它可以一直保存在寄存器中。

你所说的有一些类比。

考虑到上述情况,请记住指针是保持地址(即整数)的变量。 如果我们取消引用指针并读取指向值,则必须执行两个步骤。 首先,我们必须像任何其他变量一样读取指针变量。 之后,地址在寄存器中。 然后我们用如下指令读取指向变量:“读取存储在寄存器A中的地址的存储器”。

变量只是一种抽象。 这是一个命名值的想法 ,你可以参考,阅读和(有时,取决于其类型)修改。

它存储在硬件中的位置只是一个实现细节。 通常 ,它们是通过将数据存储在某个存储器地址,然后在每次访问变量时使用该地址来实现的,因此从这个意义上说,它通常是一个“自动解除引用的指针”。

但有时,变量存储在寄存器中而不是存储器中。 然后它没有地址,你不能创建它的指针。

有时,它甚至可能不存在于编译的代码中。 有时编译器可能会转换代码,因此不再需要变量,或者变量可能会转换为单个编译时常量。

最终,变量仅存在于源代码中。 代码执行后,变量不再存在。 一些变量被转换为内存位置,有些变量被完全删除,或转换成你甚至不能识别为变量的东西。

例如,这段代码:

int x = 10;
y += 10;

可以通过将x和y表示为存储器位置来编译,然后使用诸如“将存储器地址x的值添加到存储器地址y的值”的指令来执行加法。

但是编译器也可以将常量10编码到指令本身中,生成“在存储器地址y处添加10”指令。 当然, x是原始源代码中的变量,但它不再是内存位置。 它直接编码到指令流中。

我知道你已经接受了答案,而这并没有直接回答你的问题......如果你想阅读它,这是为了你的启发。

自动内存分配如何在C ++中实际工作?

局部变量可以存在于内存中,也可以存在于寄存器中,或者它可以在程序执行的不同阶段在两者之间浮动,或者它可以与另一个变量共享空间。 编译器可以为您的变量分配最有效的空间。

如果您获取指向变量的指针,则编译器需要将该变量放入内存,以便它具有唯一的地址。 但是如果你从来没有指向它,那么你的变量可能会保留在自己的CPU寄存器中。 或者如果你有两个局部变量,并且如果你从不同时使用它们,那么编译器可以让它们占用同一块内存或CPU寄存器。

http://en.wikipedia.org/wiki/Register_allocation

变量是引用位置的名称。 该位置在编译时解析 - 编译器在编译时计算出位置,并将所有变量替换为它们各自的位置。 基本上,每次编译器找到变量定义时,它都会将名称放在所谓的符号表中。 它至少有两列:名称(主键,如果你愿意)和一个位置。 简单地说,当编译器处理完所有变量并计算出它们的位置时,编译器会将所有变量引用换成它们各自的位置。 (这还有更多,但这是一本有价值的书......)

指针也是变量 使指针有用的原因是存储在(指针)变量位置的内容可用于在不同位置读取或写入值。 这就是所谓的解除引用指针。 这是在运行时完成的。 在这方面,您无法真正说出自动解除引用的变量,因为工作已从编译时延迟到运行时。

Not Buddy指针是一组变量,为了区分它们,除了变量的数量,值(整数,字符)必须是不同的!

变量只保存它应该保持的值。 如果它是一个指针,它将保存一个内存地址,如果它是一个整数,它将保存一个整数值,如果它是一个浮点数,它将保存一个浮点数...

变量实际上没有做任何工作。 相反,程序可以处理变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM