理解C语言指针和内存地址的关系

一个内存地址存着一个对应的值,这是比较容易理解的。

如果程序员必须清楚地知道某块内存存着什么内容和某个内容存在哪个内存地址里了,那他们的负担可想而知。

汇编语法对“一个内存地址存着一个对应的数”,作了简单的“抽象”:把内存地址用变量名代替了,对内存地址的取值和赋值方式不变。

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 = &&i; gcc编译不通过

假设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)的形式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一个内存地址存着一个对应的值,这是比较容易理解的。如果程序员必须清楚地知道某块内存存着什么内容和某个内容存在哪个内...
    天黑北风吹阅读 661评论 0 0
  • 1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧...
    金巴多阅读 1,889评论 0 9
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,534评论 3 44
  • 接着上节 mutex,本节主要介绍atomic的内容,练习代码地址。本文参考http://www.cplusplu...
    jorion阅读 73,905评论 1 14
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,874评论 18 399