左值与右值

 

左值与右值

2003-5-3

 在程序设计中,左值与右值是一个基本问题。任何变量与函数名都有左值和右值。简单的说左值是变量所代表的内容在内存中存放的地址;右值则是该变量代表的内容。下面的图示形象地给出左值与右值的关系。

 

左值与右值示意图

 在上图中,变量x代表存放在内存中的一个字符‘A’,该字符便是变量x的右值,其左值如图所示。实际使用过程中,直接对变量x操作,实则对其右值——字符‘A’进行操作。要取得变量x的左值,需要使用取址符号‘&’,即通过&x来取得x的左值。

 程序执行的过程,是不断改变变量的左值和右值的过程。

 从声明变量的那一刻起,系统便要为该变量设定初始值——包括左值和右值。左值的设定——即变量在内存所处的位置,要根据变量的声明类型、声明方式和声明时所处程序的位置来决定。全局变量和静态变量都存放与“全局变量”区域,见下图。(注:该图摘自《C语言大全(第四版)(赫伯特●希尔特),我怀疑该图过于简略,画得不太妥当。怀疑原因来自文后的例子。)

一个C程序在内容中的映像图

 

    一切局部变量都存放在栈区域。虽然在程序执行过程中申请的内存在堆内分配,但指向分配内存的变量还是存放在栈上。

局部变量的初始右值不确定,而全局变量和静态变量的初始右值自动设置为零。

 理解变量的左值与右值,对理解指针的声明、初始值以及使用方法都有极大的帮助。

 

一个例子:

#include <stdio.h>
float f;
void main()
{
float *x, *y;
static float *z;
const float g = 1.2;
register int r;
int *n = new int [1];

printf("the address of *x viz. the value of variable x is: %d/n", x);
printf("the address of *y viz. the value of variable y is: %d/n", y);
printf("the address of *z viz. the value of variable z is: %d/n", z);
printf("the address of *n viz. the value of variable n is: %d/n", n);

 printf("the address of x is: %d/n", &x);
printf("the address of y is: %d/n", &y);
printf("the address of static z is: %d/n", &z);
printf("the address of new n is: %d/n", &n);
printf("the value of f is: %d/n", f);
 printf("the address of global f is: %d/n", &f);

printf("the value of g is: %f/n", g);
printf("the address of const g is: %d/n", &g);
printf("the value of r is: %d/n", r);
printf("the address of register r is: %d/n", &r);

}

编译器

    g++(Dev-C++ 4.9.6.0)

运行平台:

       WIN2000

运行结果:

the address of *x viz. the value of variable x is: 2293600
the address of *y viz. the value of variable y is: 2
the address of *z viz. the value of variable z is: 0
the address of *n viz. the value of variable n is: 4598752
the address of x is: 2293592
the address of y is: 2293588
the address of static z is: 4227080
the address of new n is: 2293580
the value of f is: 0
the address of global f is: 4227072
the value of g is: 1.200000
the address of const g is: 2293584
the value of r is: 4598752
the address of register r is: 2293564

几点分析:

1、全局变量f和静态变量z存放在同一区域,该区域位于高址地带。

2、局部变量xyrn存放于同一区域。

3、全局变量和静态变量的右值都自动初始化为零。对于指针z这意味着它指向NULL

4、局部变量的自动右值不确定,如xyr

5、对变量的内存映像图的改动,如下图:

改动的内存映像图

 2003-5-14修改:

例子基本不变,仅把地址显示格式改为16进制。

硬件环境不变(同一台计算机)

编译器:

gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

运行平台:

  Linux 2.4.20-8(Red Hat 9.0)

运行结果:

the address of *x viz. the value of variable x is: 40015360
the address of *y viz. the value of variable y is: 42130a14
the address of *z viz. the value of variable z is: 0
the address of *n viz. the value of variable n is: 80498c8
the address of x is: bffff524
the address of y is: bffff520
the address of static z is: 8049870
the address of new n is: bffff514
the value of f is: 0
the address of global f is: 80498d4
the value of g is: 1.200000
the address of const g is: bffff51c
the value of r is: -1073744600
the address of register r is: bffff518 

思考:

1、Linux平台,从结果看到的变量的内存映像排列与赫伯特的描述是一致的。

2、Linux平台,每次运行该程序得到的结果皆不一致,即同一变量的地址在每次程序执行时都会发生改变。与此相反,在Windows平台,程序无论被执行多少次(笔者已执行10次以上),结果皆一致。

3、从各自的结果可以看到Windows平台的变量地址明显要比Linux平台的变量地址小,而且前者堆与栈之间的跨度远不及后者的大。因此我猜测前者显示的是变量的实地址(即真正的内存地址)。至于后者,显然是采用了虚地址。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p style="color:#666666;"> <span style="font-size:14px;">本门课程重实战,将基础知识拆解到项目里,让你在项目情境里学知识。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">这样的学习方式能让你保持兴趣、充满动力,时刻知道学的东西能用在哪、能怎么用。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">平时不明白的知识点,放在项目里去理解就恍然大悟了。</span> </p> <p style="color:#666666;"> <span></span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>一、融汇贯通</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本视频采用了前后端分离的开发模式,前端使用Vue.js+Element UI实现了Web页面的呈现,后端使用Python 的Django框架实现了数据访问的接口,前端通过Axios访问后端接口获得数据。在学习完本章节后,真正理解前后端的各自承担的工作。</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>二、贴近实战</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">本系列课程为练手项目实战:学生管理系统v4.0的开发,项目包含了如下几个内容:项目的总体介绍、基本功能的演示、Vuejs的初始化、Element UI的使用、在Django中实现针对数据的增删改查的接口、在Vuejs中实现前端增删改查的调用、实现文件的上传、实现表格的分页、实现导出数据到Excel、实现通过Excel导入数据、实现针对表格的批量化操作等等,所有的功能都通过演示完成、贴近了实战</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>三、课程亮点</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">在本案例中,最大的亮点在于前后端做了分离,真正理解前后端的各自承担的工作。前端如何和后端交互</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="color:#FF0000;font-size:14px;"><strong>适合人群:</strong></span> </p> <p style="color:#666666;"> <span style="font-size:14px;">1、有Python语言基础、web前端基础,想要深入学习Python Web框架的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">2、有Django基础,但是想学习企业级项目实战的朋友;</span> </p> <p style="color:#666666;"> <span style="font-size:14px;">3、有MySQL数据库基础的朋友</span> </p> <p style="color:#666666;"> <span style="font-size:14px;"> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><img alt="" src="https://img-bss.csdnimg.cn/202009070752197496.png" /><br /> </span> </p> <p style="color:#666666;"> <span style="font-size:14px;"><br /> </span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值