更多课程 选择中心

C/C++培训
达内IT学院

400-111-8989

C语言变量三要素知识详解,C语言变量三要素没那么难

  • 发布:C++培训
  • 来源:学习笔记
  • 时间:2017-06-30 16:02

1.变量的三要素

“变量的值”保存在内存的某个地方,如同使用门牌号确定地址一样,在内存中也给变量分配门牌号。在C的内存世界中,门牌号被称为变量的地址。即从变量中取值就是通过变量名找到相应的存储地址,然后读取该存储单元中的值,而写一个变量就是将变量的值存放到与之相应的存储地址中去。

通常将用于存储数据的“位置”称为对象,当将一个对象看作一个黑盒子时,如果将指定类型的值放入这个盒子,则需要使用一个名字才能访问一个对象。假设命名后的对象称为变量iNum,它有特定的类型int,类型决定将什么赋给对象,比如,将0x64赋给int类型变量iNum,以及可以使用的操作,比如,多个int类型数据可以使用“*”操作进行乘法运算。

如果有以下声明:

int     iNum = 0x64;                        // 声明iNum为int型变量

其中,int为变量iNum的类型,iNum为变量名,0x64为变量iNum的值。当声明一个变量时,编译器会根据变量的类型预留足够的内存空间。变量的存储空间是系统自动分配的,但此存储空间不会在程序的整个生命周期中永远存在。

值是被解释为一个类型的内存中的一组比特(bit)。计算机内存不知道值的类型,只是将它保存起来。因此只有决定内存如何解释时,内存中的bit才有意义。比如,3.0的含义是什么?只有使用单位时,才会决定3.0的含义。

声明是命名一个对象的一条语句,定义是为一个对象分配内存空间的声明,一个定义通常会提供一个初始值。比如:

int length = 20;

int width = 40;

int area = length + width;

2.变量的地址与指针

当你声明一个变量时,底层会分配一定大小的内存存储变量的信息。而分配多少内存,则在编译期就已经确定了。为了能够访问无限量的内存,C语言使用地址&操作符返回操作数的地址。当&运算符作用于一个变量时,则返回的是变量的地址。对于变量iNum来说,&iNum就是变量iNum的内存地址,详见图 1.3。

从变量中取值就是通过变量名iNum找到与之相应的存储地址&iNum,然后读取存储在该地址中的值0x64,写一个变量iNum就是将变量的值0x64存放到与之相应的存储地址&iNum中去。显然,不能在&iNum前面再加“&”运算符,因为&iNum已经不是变量了,而是一个不可修改的整型常量,即0x22FF74。

为了便于描述变量,C语言将用于存储变量的内存地址的&iNum抽象为指向变量iNum的指针。这些地址之所以称为指针,因为它是“指向”一个变量的。只需指出变量的地址(不是变量名),就可以确定该变量。即指针的本质就是一个内存的地址,它指向内存的某个位置。指针是一个地址,其强调的是当使用指针时要想到它是“内存地址”。实际上,在现实世界里既没有变量也没有指针,变量和指针是对程序中的数据和存储空间的抽象。

为了展示变量的地址与变量的值的对应关系,最好的方式是直接打印输出。比如,输入2个整数,交换两者的值后输出,即先将输入的整数存入变量iNum1和iNum2,然后交换,详见程序清单 1.3。注意,不同的编译环境(不同的编译器、同一编译器的不同版本、编译参数不同等),变量的地址值(0x22FF74)可能会不一样。

程序清单 1.3  变量交换范例程序

1       #include<stdio.h>

2       int main(int argc, char *argv[])

3       {

4                 intiNum1, iNum2, temp;

5

6                 scanf("%x%x",&iNum1, &iNum2);

7                 printf("%x,%x\n", &iNum1, &iNum2);

8                 printf("%x,%x\n", iNum1, iNum2);

9                 temp= iNum1;  iNum1 = iNum2;  iNum2 = temp;

10               printf("%x,%x\n", &iNum1, &iNum2);

11               printf("%x,%x\n", iNum1, iNum2);

12               return0;

13     }

       

请读者仔细观察,为何要在程序清单 1.3(6)中的变量前添加“&”?程序清单 1.3(6~7)中的&iNum1、&iNum2有什么区别?

左值和右值

为了理解某些操作符的限制,标准C发明了L-value和R-value两个名词。虽然其被解释为左值和右值,但实际上是一个美丽的误会。因为L-value是指“locator value”不是“left vaue”,其字面意思是“(在内存中)有特定位置的值”,即内存的索引值——地址。而R-value是指“readvalue”不是“rightvalue”,其字面意思是“可读的值”。比如:

int iNum = 0x64;

虽然编译器为变量iNum分配了地址(L-value),其L-value是在编译期就确定了的地址“&iNum”。而R-value是存储在变量iNum中的值0x64,但其赋值是在运行时。

尽管iNum有地址,但iNum++表达式没有地址,因此iNum只有R-value。虽然任何表达式都有R-value,但只有部分表达式有L-value。

3.变量的存储

如果数据从低位到高位用最左位和最右位表述,则一定会产生歧义,因此使用最低有效位(Least Significant,LSB)和最高有效位(Most Significant,MSB)分别表示数据的最低位和最高位。对于有符号数来说,最高有效位就是符号位。假设变量的值用二进制表示为

D31D30D29D28D27D26D25D24D23D22D21D20D19D18D17D16D15D14D13D12D11D10D9D8D7D6D5D4D3D2D1D0

即数据的MSB符号位为D31,LSB为D0。

根据数据中各个字节在连续字节序列中排列顺序的不同,分为2种排列方式:大端和小端。如果A中存放的是数据的MSB最高有效位,即为大端模式(详见图1.4(a));如果A中存放的是数据的LSB最低有效位,即为小端模式(详见图1.4(b))。注意,CPU究竟采用何种存储模式取决于硬件,与编译器无关,Intel x86计算机的CPU就是小端模式。当计算机对存储单元进行编号时,则每个地址编号中只存放一个字节。C规定多字节的int、float、doublie类型变量必须占用相邻的存储单元,且将存储单元的最低地址作为变量的地址。假设一个32位变量占用地址为A、A+1、A+2和A+3存储单元,则变量的地址为A。如果有“intiNum = 0x64;”,那么A中到底存放的是4个字节00H、00H、00H、64H中的哪个字节呢?

4.变量类型别名

大家可能知道,作者的名字叫周立功,但作者在家里还有一个别名——小兵,其实都是同一个人。同样如此,我们也可以给变量的类型取一个别名。如果在“int iNum;”定义前添加typedef,即:

typedef int iNum;

此时,iNum等同于int类型。为了便于理解,将iNum替换成INT32。比如:

typedef int INT32;

typedef的用途是声明类型的别名,它只是为某个已经存在的类型增加了一个新的名字。那么利用这一特性,就可以定义变量了。比如:

INT32  a;                                  //定义int型变量a

除此之外,INT32还可用于类型转换,比如:

float b;

(INT32)b;                               // 将其它的类型b转换为整型

为何还要为int再取一个名称呢?主要是为了提高程序的可移植性。比如,某种微处理器的int为16位,long为32位。如果要将该程序移植到另一种体系结构的微处理器,假设其int为32位,long为64位,而只有short才是16位的,因此必须将程序中的int全部替换为short,long全部替换为int,不仅修改工作量巨大且容易出错。如果在程序中全部用新取的名称,那么只需要修改定义的这些新名称。即只要将以前的:

typedef int INT16;

typedef long INT32;

替换成:

typedefshort INT16;

typedef int INT32;

在编程中使用typedef的好处,除了为变量取一个简单易记且意义明确的新名称之外,其最主要的作用是使用typedef构造新的数据类型。而不要误认为typedef的作用仅仅是简化更复杂的类型声明,将在后续的章节中详细阐述。

由此可见,C语言变量的内涵包括3个要素:变量的类型、变量的值和变量的地址。

  • 变量的类型:即变量存储的数据的类型,程序如何解释变量保存的数据。比如,int类型变量,任何引用存储在变量中的数据都被程序解释为整数。数据类型分为基本类型(字符型与数值型)、构造类型(数组型、结构体型、联合体型、枚举型与位域型)、指针类型与void *类型,所有其它的类型都是通过组合的方式从基本类型构造而来的。

  • 变量的值:程序根据变量的类型解释存储在变量中的数据,数据分为不可修改的常量的值和可以修改的变量的值。

  • 变量的地址:即变量在内存中的位置,当利用一个变量存储一个数据时,则程序将数据存储到变量的地址所指示的存储单元中。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:C++与JAVA编程语言的核心区别
下一篇:程序员快速成长秘笈,程序员成长框架分享

C语言创建windows窗口实例

C++回调函数是什么?

C++ shared_ptr和动态数组

C语言有哪些关键词,C语言44个关键词大全

  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省