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

时间:2022-07-18 16:47:44

How does a variable in C/C++ work?

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

I mean, a pointer stores an address from a variable and then you have to dereference it to access the object to which it refers, so I think that a variable is a pointer that is dereferenced automatically when used... does that make any sense?

我的意思是,一个指针从一个变量中存储一个地址,然后你必须取消它来访问它所引用的对象,所以我认为变量是一个指针,当使用它时,它会自动被取消。这说得通吗?

10 个解决方案

#1


29  

A variable is an abstraction (a convenient name) for a memory position on the computer. In C/C++ if the variable is of type int it will be a convenient name for a memory address holding an integer value.

变量是计算机上内存位置的抽象(方便的名称)。在C/ c++中,如果变量是int类型的,那么它将是保存整数值的内存地址的方便名称。

And a variable is not a pointer automatically dereferenced. A variable just holds the value it is supposed to hold. If it is a pointer, it will hold a memory address, if it is an integer it will hold an integer value, if it is a float, it will hold a floating point number... And so on and so forth...

一个变量不是一个自动去引用的指针。变量只保存它应该保存的值。如果它是一个指针,它将保存一个内存地址,如果它是一个整数,它将保存一个整数值,如果它是一个浮点数,它将保存一个浮点数……等等等等……

#2


12  

Consider the following definitions

考虑下面的定义

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

I simplify this a little bit and use decimal values, the variables (names) are placeholder for adresses, at these adressess the concrete values are stored.

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

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 

By using e.g. printf("%s\n" , string ); you don't want to copy the whole string, rather you give the address where the string starts (call by reference).

通过使用printf(“%s\n”,字符串);您不希望复制整个字符串,而是给出字符串开始的地址(按引用调用)。

#3


8  

To read/write a variable is to read/write a piece of bytes at know location. "know location" is a location known by compiler, it can be:

读/写变量就是在已知位置上读/写一个字节。“知道位置”是编译器知道的位置,可以是:

  • Fixed address. Compiler knows all address of global variables. If we read/write a global variable, compiler puts instruction like this: "read/write memory at address 0x00235A87"
  • 固定的地址。编译器知道全局变量的所有地址。如果我们读/写一个全局变量,编译器会这样放置指令:“读/写内存地址为0x00235A87”
  • Fixed stack offset. Local variables are pushed onto the stack. Pointer to the top of the stack ("stack pointer" or "SP") is stored in processor registers. Compiler knows what's the offset of local variable from top of the stack. If we read/write a local variable, compiler puts instruction like this: "read/write memory at address 'SP-0x05'".
  • 固定栈抵消。将局部变量推到堆栈上。指向堆栈顶部的指针(“堆栈指针”或“SP”)存储在处理器寄存器中。编译器知道本地变量从堆栈顶部的偏移量是多少。如果我们读/写一个本地变量,编译器会这样放置指令:“读/写内存在地址‘SP-0x05’”。
  • Processor registers. Variables, when used, are loaded into processor registers. Compiler knows which registers. To use them no memory reading/writing is needed, compiler simply puts instructions that use registers like: "add content of register B to register A".
  • 处理器寄存器。变量在使用时被加载到处理器寄存器中。编译器知道哪个寄存器。要使用它们不需要读/写内存,编译器只需放置使用寄存器的指令,如“添加寄存器B的内容来注册寄存器A”。

Accessing a variable is actually algorithm written in a form of processor instructions. Variable can be addresses by fixed memory address, by calculated memory address (using fixed offset and value kept in a register) or processor register. Compiler puts instruction that moves values of variables between memory/register and between register/register. Variable may even not exist in memory, it can be all the time kept in registers.

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

There is some kind of analogy in that what you say.

你所说的有点类似。

Considering above, remember the pointer is variable that keeps an address (which is integral number). If we dereference a pointer and read pointed value then two steps must be done. Firstly we must read pointer variable like any other variable. After that the address is in a register. Then we read pointed variable with instruction like: "read memory at address stored in register A".

考虑到以上,请记住指针是保持地址(即整数)的变量。如果我们删除指针并读取指针的值,那么必须执行两个步骤。首先,我们必须像读取其他变量一样读取指针变量。之后地址在寄存器中。然后我们读取带有指令的指针变量,如:“读取存储在寄存器A中的地址的内存”。

#4


6  

A variable is just an abstraction. It is the idea of a named value that you can refer to, read and (sometimes, depending on its type) modify.

变量只是一个抽象概念。它是一个命名值的概念,您可以引用、读取和(有时,取决于它的类型)修改。

Where it is stored in the hardware is just an implementation detail. Often, they are implemented by storing data at a certain memory address, and then using that address whenever the variable is to be accessed, so in that sense, it is often an "automatically dereferenced pointer" as you say.

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

But sometimes, a variable is stored in a register instead of in memory. Then it doesn't have an address, and you can't create pointers to it.

但有时,变量存储在寄存器中而不是存储在内存中。那么它就没有地址,你也不能创建指向它的指针。

Sometimes, it may not even exist in the compiled code. Sometimes the compiler might transform the code so the variable is no longer necessary, or the variable might be converted to a single compile-time constant.

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

Ultimately, variables only exist in the source code. Once your code is executing, variables no longer exist. Some variables are converted into memory locations, and some are removed entirely, or transformed into something you wouldn't even recognize as a variable.

最终,变量只存在于源代码中。一旦代码执行完毕,变量就不再存在。有些变量被转换为内存位置,有些则完全被删除,或者转换成您甚至不认识的变量。

For example, this code:

例如,这段代码:

int x = 10;
y += 10;

could be compiled by representing x and y as memory locations, and then the addition is performed with an instruction such as "add the value from memory address x to the value at memory address y".

可以通过将x和y表示为内存位置来编译,然后使用“将内存地址x的值添加到内存地址y的值”之类的指令进行添加。

But the compiler could also encode the constant 10 into the instruction itself, generating an "add 10 to the value at memory address y" instruction. Sure, x was a variable in the original source code, but it's no longer a memory location. It's encoded directly into the instruction stream.

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

#5


4  

I know you've already accepted an answer, and this does not directly answer your question... this is for your edification, if you desire to read it.

我知道你已经接受了答案,但这并不能直接回答你的问题……如果你想读的话,这是给你的启发。

How does automatic memory allocation actually work in C++?

在c++中,自动内存分配是如何工作的?

#6


2  

A local variable can live in memory, or in a register, or it can float between the two at different stages of program execution, or it can share space with another variable. The compiler is free to allocate the most efficient space for your variable.

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

If you take a pointer to a variable then the compiler needs to put that variable into memory, so that it has a unique address. But if you never take a pointer to it then your variable can might remain in its own CPU register. Or if you have two local variables, and if you never use both of them at the same time, then the compiler can have them occupy the same piece of memory or CPU register.

如果你取一个指向一个变量的指针,那么编译器需要把这个变量放到内存中,这样它就有一个唯一的地址。但是,如果您从不使用指向它的指针,那么您的变量可以保留在它自己的CPU寄存器中。或者如果你有两个局部变量,如果你从来没有同时使用它们,那么编译器可以让它们占用相同的内存或CPU寄存器。

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

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

#7


1  

A variable is a name that refers to a location. The location is resolved at compile time - the compiler figures out the location at compile time, and will replace all variables with their respective locations. Basically, each time the compiler finds a variable definition, it puts the name in a so called symbol table. It has at least two columns: the name (primary key if you will), and a location. To put it simply, when the compiler has processed all variables, and figured out their locations, the compiler will swap out all variable references with their respective locations. (There's more to it that this, but that's a book worth of material...)

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

Pointers are variables too. What makes a pointer useful, is that the contents stored in the location of the (pointer) variable, can be used to read or write values in a different location. This is what's called dereferencing the pointer. This is done at run time. In this respect, you can't really say that variables that are automatically dereferenced, because the work has been deferred from compile time to run time.

指针变量。使指针有用的是,存储在(指针)变量位置的内容可以用于在不同的位置读取或写入值。这就是所谓的去引用指针。这是在运行时完成的。在这方面,您不能说那些自动取消引用的变量,因为工作已经从编译时延迟到运行时。

#8


0  

Not Buddy a pointer is a set of variables, and to differentiate them, besides the number of variables, values (integer, character) has to be different!

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

#9


0  

A variable just holds the value it is supposed to hold. If it is a pointer, it will hold a memory address, if it is an integer it will hold an integer value, if it is a float, it will hold a floating point number...

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

#10


-2  

A variable actually does not do any work. Instead, a program may work upon variables.

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

#1


29  

A variable is an abstraction (a convenient name) for a memory position on the computer. In C/C++ if the variable is of type int it will be a convenient name for a memory address holding an integer value.

变量是计算机上内存位置的抽象(方便的名称)。在C/ c++中,如果变量是int类型的,那么它将是保存整数值的内存地址的方便名称。

And a variable is not a pointer automatically dereferenced. A variable just holds the value it is supposed to hold. If it is a pointer, it will hold a memory address, if it is an integer it will hold an integer value, if it is a float, it will hold a floating point number... And so on and so forth...

一个变量不是一个自动去引用的指针。变量只保存它应该保存的值。如果它是一个指针,它将保存一个内存地址,如果它是一个整数,它将保存一个整数值,如果它是一个浮点数,它将保存一个浮点数……等等等等……

#2


12  

Consider the following definitions

考虑下面的定义

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

I simplify this a little bit and use decimal values, the variables (names) are placeholder for adresses, at these adressess the concrete values are stored.

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

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 

By using e.g. printf("%s\n" , string ); you don't want to copy the whole string, rather you give the address where the string starts (call by reference).

通过使用printf(“%s\n”,字符串);您不希望复制整个字符串,而是给出字符串开始的地址(按引用调用)。

#3


8  

To read/write a variable is to read/write a piece of bytes at know location. "know location" is a location known by compiler, it can be:

读/写变量就是在已知位置上读/写一个字节。“知道位置”是编译器知道的位置,可以是:

  • Fixed address. Compiler knows all address of global variables. If we read/write a global variable, compiler puts instruction like this: "read/write memory at address 0x00235A87"
  • 固定的地址。编译器知道全局变量的所有地址。如果我们读/写一个全局变量,编译器会这样放置指令:“读/写内存地址为0x00235A87”
  • Fixed stack offset. Local variables are pushed onto the stack. Pointer to the top of the stack ("stack pointer" or "SP") is stored in processor registers. Compiler knows what's the offset of local variable from top of the stack. If we read/write a local variable, compiler puts instruction like this: "read/write memory at address 'SP-0x05'".
  • 固定栈抵消。将局部变量推到堆栈上。指向堆栈顶部的指针(“堆栈指针”或“SP”)存储在处理器寄存器中。编译器知道本地变量从堆栈顶部的偏移量是多少。如果我们读/写一个本地变量,编译器会这样放置指令:“读/写内存在地址‘SP-0x05’”。
  • Processor registers. Variables, when used, are loaded into processor registers. Compiler knows which registers. To use them no memory reading/writing is needed, compiler simply puts instructions that use registers like: "add content of register B to register A".
  • 处理器寄存器。变量在使用时被加载到处理器寄存器中。编译器知道哪个寄存器。要使用它们不需要读/写内存,编译器只需放置使用寄存器的指令,如“添加寄存器B的内容来注册寄存器A”。

Accessing a variable is actually algorithm written in a form of processor instructions. Variable can be addresses by fixed memory address, by calculated memory address (using fixed offset and value kept in a register) or processor register. Compiler puts instruction that moves values of variables between memory/register and between register/register. Variable may even not exist in memory, it can be all the time kept in registers.

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

There is some kind of analogy in that what you say.

你所说的有点类似。

Considering above, remember the pointer is variable that keeps an address (which is integral number). If we dereference a pointer and read pointed value then two steps must be done. Firstly we must read pointer variable like any other variable. After that the address is in a register. Then we read pointed variable with instruction like: "read memory at address stored in register A".

考虑到以上,请记住指针是保持地址(即整数)的变量。如果我们删除指针并读取指针的值,那么必须执行两个步骤。首先,我们必须像读取其他变量一样读取指针变量。之后地址在寄存器中。然后我们读取带有指令的指针变量,如:“读取存储在寄存器A中的地址的内存”。

#4


6  

A variable is just an abstraction. It is the idea of a named value that you can refer to, read and (sometimes, depending on its type) modify.

变量只是一个抽象概念。它是一个命名值的概念,您可以引用、读取和(有时,取决于它的类型)修改。

Where it is stored in the hardware is just an implementation detail. Often, they are implemented by storing data at a certain memory address, and then using that address whenever the variable is to be accessed, so in that sense, it is often an "automatically dereferenced pointer" as you say.

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

But sometimes, a variable is stored in a register instead of in memory. Then it doesn't have an address, and you can't create pointers to it.

但有时,变量存储在寄存器中而不是存储在内存中。那么它就没有地址,你也不能创建指向它的指针。

Sometimes, it may not even exist in the compiled code. Sometimes the compiler might transform the code so the variable is no longer necessary, or the variable might be converted to a single compile-time constant.

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

Ultimately, variables only exist in the source code. Once your code is executing, variables no longer exist. Some variables are converted into memory locations, and some are removed entirely, or transformed into something you wouldn't even recognize as a variable.

最终,变量只存在于源代码中。一旦代码执行完毕,变量就不再存在。有些变量被转换为内存位置,有些则完全被删除,或者转换成您甚至不认识的变量。

For example, this code:

例如,这段代码:

int x = 10;
y += 10;

could be compiled by representing x and y as memory locations, and then the addition is performed with an instruction such as "add the value from memory address x to the value at memory address y".

可以通过将x和y表示为内存位置来编译,然后使用“将内存地址x的值添加到内存地址y的值”之类的指令进行添加。

But the compiler could also encode the constant 10 into the instruction itself, generating an "add 10 to the value at memory address y" instruction. Sure, x was a variable in the original source code, but it's no longer a memory location. It's encoded directly into the instruction stream.

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

#5


4  

I know you've already accepted an answer, and this does not directly answer your question... this is for your edification, if you desire to read it.

我知道你已经接受了答案,但这并不能直接回答你的问题……如果你想读的话,这是给你的启发。

How does automatic memory allocation actually work in C++?

在c++中,自动内存分配是如何工作的?

#6


2  

A local variable can live in memory, or in a register, or it can float between the two at different stages of program execution, or it can share space with another variable. The compiler is free to allocate the most efficient space for your variable.

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

If you take a pointer to a variable then the compiler needs to put that variable into memory, so that it has a unique address. But if you never take a pointer to it then your variable can might remain in its own CPU register. Or if you have two local variables, and if you never use both of them at the same time, then the compiler can have them occupy the same piece of memory or CPU register.

如果你取一个指向一个变量的指针,那么编译器需要把这个变量放到内存中,这样它就有一个唯一的地址。但是,如果您从不使用指向它的指针,那么您的变量可以保留在它自己的CPU寄存器中。或者如果你有两个局部变量,如果你从来没有同时使用它们,那么编译器可以让它们占用相同的内存或CPU寄存器。

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

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

#7


1  

A variable is a name that refers to a location. The location is resolved at compile time - the compiler figures out the location at compile time, and will replace all variables with their respective locations. Basically, each time the compiler finds a variable definition, it puts the name in a so called symbol table. It has at least two columns: the name (primary key if you will), and a location. To put it simply, when the compiler has processed all variables, and figured out their locations, the compiler will swap out all variable references with their respective locations. (There's more to it that this, but that's a book worth of material...)

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

Pointers are variables too. What makes a pointer useful, is that the contents stored in the location of the (pointer) variable, can be used to read or write values in a different location. This is what's called dereferencing the pointer. This is done at run time. In this respect, you can't really say that variables that are automatically dereferenced, because the work has been deferred from compile time to run time.

指针变量。使指针有用的是,存储在(指针)变量位置的内容可以用于在不同的位置读取或写入值。这就是所谓的去引用指针。这是在运行时完成的。在这方面,您不能说那些自动取消引用的变量,因为工作已经从编译时延迟到运行时。

#8


0  

Not Buddy a pointer is a set of variables, and to differentiate them, besides the number of variables, values (integer, character) has to be different!

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

#9


0  

A variable just holds the value it is supposed to hold. If it is a pointer, it will hold a memory address, if it is an integer it will hold an integer value, if it is a float, it will hold a floating point number...

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

#10


-2  

A variable actually does not do any work. Instead, a program may work upon variables.

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