我试着把我的头绕在变量的概念上。
显然,变量的工作方式是隐式的。然而,我试图解释我的隐性知识,并遇到了一些困难。以下是我想出的:
变量是一定大小的容器。大小既取决于变量声明中的数据类型,也取决于硬件(具体是什么?字数大小?)变量在内存中有一个地址,该地址存储在容器预先分配的大小内(变量的名称如何连接到其内存地址?)在该变量的内存保留点中,可以存储与声明的数据类型相对应的值。
那是错误的还是不精确的(我肯定很多)?怎样才能更好地解释呢?
发布于 2020-11-03 11:34:19
在C中,变量由两件事组成:标识符和对象。
标识符是源代码中用来表示对象的文本字符串。(标识符也可以表示函数、结构成员和其他东西。)
对象是“执行环境中的数据存储区域,其内容可以表示值”(C 2018 3.1.15 1)。
我们通常认为对象有某种类型。类型确定存储在对象中的值的意义--当解释为float时,相同的位可能意味着3.75,而当解释为int时,可能意味着1,081,081,856。C标准定义了类型表示方式的一些属性(例如,某种形式的二进制文件用于整数),并要求C实现定义其余部分(位字段的某些方面除外)。
因此,任何对象的表示方式的“最终发言权”取决于每个C实现。大多数C实现都受到硬件的影响,因为它们的设计目的是在目标系统上高效工作,但是C实现可以在使用32位字的硬件上提供37位int对象。
早些时候,我说过,我们通常认为对象有某种类型。定义对象的标识符时,为其保留存储。该存储的数量取决于类型。但是,对象值的实际解释取决于用于访问对象的表达式。几乎所有时候,我们都使用其声明的类型访问对象:在声明float x;之后,我们使用x = 3.75; printf("%g\n", x);等等,用于访问这些表达式中的对象的类型是float,即声明的x类型。但是C是灵活的,允许我们使用char *p = (char *) &x;设置一个指向内存的char *p = (char *) &x;指针,然后我们可以使用c[0]、c[1]等访问x的字节。在本例中,用于访问对象或其部分的表达式的类型是char,因此在使用这些表达式访问对象时,我们将获得char值而不是float值。
编译器知道并安排标识符与其存储(内存)之间的连接。当定义了对象的标识符时,编译器将为其规划存储(取决于编译器对程序的优化)。该存储可能位于程序的数据部分、堆栈部分或其他地方。编译器知道引用存储的方法。堆栈中的位置可以通过相对于堆栈指针或帧指针的偏移来引用。数据部分中的位置可以通过相对于程序加载器存储在特定寄存器中的基本地址的偏移来引用。位置可以通过相对于节启动的偏移或绝对存储器地址来引用。不管情况如何,当编译器需要生成访问对象的指令时,它就会生成合适的指令。这可以是指令本身包含相对于堆栈指针的偏移量的指令。也可以是两个或多个指令将偏移量添加到基本寄存器中,然后使用结果访问内存。或者,它可能是部分生成的指令,当程序加载程序将其调整为具有最终地址时,该指令将在稍后完成。
https://stackoverflow.com/questions/64660363
复制相似问题