如果程序员必须清楚地知道某块内存存着什么内容和某个内容存在哪个内存地址里了,那他们的负担可想而知。
汇编语法对“一个内存地址存着一个对应的数”,作了简单的“抽象”:把内存地址用变量名代替了,对内存地址的取值和赋值方式不变。
c语言对此进行了进一锋轮郑步的抽桐基象:变量 <==>
(一个内存地址,对应的值)(这里忽略类型等信息)。
把C语言中的基本类型(int,long,float等),指针,数组等还原为(一个内存地址,对应的值)后,就能更清淅地理解它们了。
内存就相当于(addr,val)的大hash表,c语句的语义基本就是改变hash值。
什么叫hash表?:根据关键码值key直接进行内存访问的数据结构。
为了下文的方便,特定义如下语义(遵循C的标准语义):
var<==>(addr, val)(var为一个变量名,addr为var在内存中的首地址,val为var的值)
&var <==>addr
var<==>
var作为左值出现(即等式左边)时,var等价于 addr
var作为右值出现(即等式右边)时,var等价于val
*var <==>val
注:符号"<==>"右边出的等式x = y(x是一个内存地址,y是一个值)表示将内存地址为x的内容置为值y,如addr = 3表示置内存addr里的值为3
现在利用上银颂面的语义解释一下这些例子:
int i = 3
假设i的内存地址为0x8049320 ,那么这句话的语义是0x8049320 = 3,经过i =
3后,i为(0x8049320,3)
int b = i
假设b的内存地址为0x8049324 ,那么这句话的语义是0x8049324 = i对应的val
= 3,此时b为(0x8049324,3)
int *p = &b
指针p也是一个变量,int **p,int *p[8],在这些申明中p都只是一个指针变量,它和其他的变量的不同之处在于它的大小是定的,它的类型信息只是编译器用来进行类型检查和其他一些作用的(如果没有类型检查,你可以用任何的方式对一个变量进行 *** 作如int i****i = 3)。假设p的地址为0x8049328,则根据p = &b的语义p.addr = b.addr,p为(0x8049328,0x8049324)
*p = 5
语义为0x8049324 = 5,此时只改变了内存地址为0x8049324的值,即改变了b的值(0x8049324,5),而p的值并未改变
int **q = &p//如果写为int **q = &&igcc编译不通过
假设q的内存地址为0x8049330,语义为0x8049330 = addr(p) = 0x8049328所以q为(0x8049330,
0x8049328)
(int **q = &&i,要是编译过了则q应该表示为(0x8049330,
x),内存地址为x的地方表示为(x,0x8049320),那么地址x为多少呢? )
**q = 6
语义为val(val(q)) =
val(0x8049328) = 0x8049324 = 6,将内存地址为0x8049324的内容置为6,即将b的值置为6,b为(0x8049324,6)
对于结构,这些语义也适用,因为结构里的成员也是有对应地址的,也能表示为(addr,val)的形式。
对。c语言允许直接访问内存腊弯地址。
C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生轮友闷少量的机器语言以及不告粗需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括一些类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。C语言是一门面向过程的计算机编程语言,与C++、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速,工作量小、可读性好,易于调试、修改和移植,而代码质量与汇编语言相当。C语言一般只比汇编语言代码生成的目标程序效率低10%~20%。因此,C语言可以编写系统软件。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)