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

Hug*_*ugo 17 c c++ variables pointers

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

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

Pab*_*ruz 30

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

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

  • 变量可能并不总是作为内存中的偏移量存在,例如本地变量,仅存储在寄存器中.除此之外,+1简而言之:) (6认同)

sta*_*ker 12

请考虑以下定义

char *string="abc";
int b = 10;
int *bptr = &b;
Run Code Online (Sandbox Code Playgroud)

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

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 
Run Code Online (Sandbox Code Playgroud)

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


adf*_*f88 8

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

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

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

你所说的有一些类比.

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


jal*_*alf 6

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

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

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

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

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

例如,这段代码:

int x = 10;
y += 10;
Run Code Online (Sandbox Code Playgroud)

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

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