《C语言程序设计:问题与求解方法》——2.10节变量

简介:

本节书摘来自华章社区《C语言程序设计:问题与求解方法》一书中的第2章,第2.10节变量,作者:何 勤,更多章节内容可以访问云栖社区“华章社区”公众号查看

2.10 变量
一些动态变化的量(比如车速、温度、股票价格等)称为变量,这些量在源程序中用常量无法表示。
用C语言进行编程,要使用数据区(数据值可变)而不是代码区(数据值不允许变)的内存单元来存放数据,都必须向编译程序提出申请。
在C语言源程序中,向编译程序申请一个(或几个)存放某种类型数据的、值的大小可以变化的内存单元称为定义变量。

2.10.1 变量的定义
定义一个简单变量的格式为:
类型名 变量名;
类型名要使用关键字(比如int、float、char等,参见2.7节),变量名必须使用标识符。
通过这种方式,编译程序为我们在内存中分配一个合适大小的内存单元,用来存放一个此类型的数据。
例如,在定义变量 int num; 之后, C编译程序通常会为变量num在内存中分配地址连续的2个(或4个)字节作为一个内存单元,用来存放变量num的数据,编译程序通过这种方式,把一个变量num与一个可以存放int型数据的内存单元联系了起来,参见图2-1。


dd8fb1d04ce90e33ca075e629b2a44d187fb55a6

延伸与拓展:编译程序为变量分配内存单元的技术内幕
编译程序通过扫描每个函数中的所有变量定义,建立起一张表,即变量名–内存单元地址对照表。接下来在扫描所有的语句时,编译程序就可以通过查找这张对照表,将源程序语句中出现的变量名转变为机器语言指令中的内存单元的地址,即指令中的操作数。
编译程序通过把变量名映射为内存地址的方式,达到了为变量分配相应内存单元的目的(类似于导游通过将游客名对应为房间号,达到了为每个游客分配一个房间的目的)。
定义多个简单变量的格式为:
类型名 变量名列表;
例如:
int age , num ,sum ;
在变量名列表中的多个变量名之间,要用逗号隔开,最后要以分号结束。编译程序会为每一个同类型的变量分配同样字节数的内存单元,用来存放各变量的值。
最好使用意义明确的标识符来定义变量,比如对于兔子的只数,使用标识符rabbit_count作为变量名就比用标识符n作变量名要好得多。

2.10.2 变量名和变量的值
由于变量的内存单元由编译程序分配,因此,在源程序的语句中,可以通过书写变量名来表示要“访问”(即存或取)变量所对应的内存单元中的数据了,这个数据称为变量的值。
比如,语句 num + 2 表示把变量名num所对应的内存单元中的值取出来(简称为把变量num的值取出来)再加上2( num + 2 其实是表达式,细节参见2.14节)。而语句“num = 21 ;”表示要把数值21存入变量名num所对应的内存单元中(简称为把数值21存入变量num中,“num = 21;”其实是赋值语句,细节参见2.16节)。
变量的值是“取之不尽”的。从内存单元取得一个变量的值,其实只是从一个内存单元中复制了这个值而已,该变量的值(没有发生任何变化)仍然可以再次取用;但是,变量的值又是“一存就变”的,只要运行了一条与存数操作有关的语句,(在内存单元中的)变量的“旧值”就被变量的新值覆盖掉了,变量的“旧值”将不复存在。
延伸与拓展:机器语言程序与高级语言源程序的最大不同点
机器语言程序中的指令经常使用内存地址(作为操作数)来指明要存取哪个内存单元中的数据;而高级语言源程序中的语句使用变量名来指明要存取哪个内存单元中的数据。这是机器语言程序与高级语言源程序最重要的不同点之一。内存地址是长长的、难以记忆的二进制位串;而变量名则是程序员自己所起的好记和易懂的(但要符合标识符规定的)名字。
通过这种方式,首先,使得源程序更为简明而可读性又好。其次,高级语言源程序所要加工的数据获得了极为宝贵的内存绝对位置无关性。这使得源程序具有了良好的移植性,也为多道程序同时放入内存中创造了先决条件。
但使用高级语言编程也存在一些缺点,在源程序的语句(或表达式)中,究竟何处是取变量的值(变量值不变),何处是将一个值存到变量之中(变量值将改变),变得有些模糊不清。这给初学者阅读和理解程序的运行带来一定的困难。这个问题读者要给予充分的注意,否则你就很可能读不懂很多程序。

2.10.3 各种基本类型的变量定义
1)整型变量(int):在程序运行时,需要内存单元存放(数值可以变化的)可正可负的整数时,要用此类型来定义。C编译器一般分配2个(16位系统)或4个字节(32位系统)的内存空间给一个int型变量。
占用两个字节的int型变量的取值范围在–32768~32767之间,这个范围比较小。
2)单精度浮点型变量(float):在程序运行时,需要内存单元存放以实数形式(即有小数分量)出现的量(比如34.1、–678.34、0.368等),要用此类型来定义。
比如,“float x,y;”就定义了两个单精度浮点型变量x和y。
一般C编译器分配4个字节的内存空间给一个float型变量。
单精度浮点型变量的精度是十进制的7位。也就是说,只有数值中的高7位数字肯定是正确无误的。
float型变量的优点是:取值范围远比int型变量大(大约正数是在1.17×10–38~3.4×1038之间,负数取值范围与正数是关于原点对称的)。float型变量的缺点是:运算速度不如int型变量快,所存入的数据通常也只是一个近似值。
3)字符型变量:用类型关键字char来定义字符型变量。
在程序运行时,需要用内存单元存储单个字符(通常是ASCII字符时),要用此类型来定义。C编译器分配1个字节的内存空间给一个char类型的变量。比如,“char ch1,ch2;”定义了两个字符变量ch1和ch2。
字符型变量属于一种从表面上看来是非数值型的量—字符。但其实在计算机的内存中,它通常就是一个以ASCII码形式存储的,占用一个字节内存的二进制码。在C语言中,把这个ASCII码当作一个小整数来对待。比如字符'a',实际上被编译程序看成是占用一个字节的整数97(但在有些高级语言比如Pascal语言中,不能把字符量当成整型量来对待)。
在高级编程语言中,任何类型变量的值都有一定的限定范围(这是由于存储变量值的字节数有限而造成的),程序运行时超出了变量允许的取值范围称为发生了溢出(关于溢出的讨论,请参见本书后面的讨论)。这是在编程时要注意避免和进行处理的。
变量允许的取值范围与所分配到的字节数有关,不同编译器为同一种类型变量分配的字节数很可能不一样,C语言标准只是规定了各种类型变量所占用内存的最少字节数(参见后续内容)。
延伸与拓展:“变量类型”的技术内幕
对于不同类型的变量,编译程序分配给变量的内存单元字节数很可能不一样,数据的外部形式、机内形式不一样,运算时选用的运算指令类型不一样(比如对于实型量加法,编译程序选用浮点数加法指令;而对于整型量加法,则选择整数加法指令),输入输出变量值的转换工作不一样,变量取值的允许范围可能不一样,允许进行的运算也不一样;但上述所有这些不一样,除了最后两项需要编程者注意外,大多都不需要编程者来具体操心。这些原本极为琐碎的基础性的编程工作,只要我们恰当地定义了变量的类型,并在程序语句中合理地使用变量,编译程序(包括标准输入输出库函数)基本上就可以为我们代劳了。

2.10.4 变量的初始化
变量的初始化就是存入一个初始数据到变量对应的内存单元中。
在C语言中,变量定义后,通常还要进行初始化,也就是事先要将一个数据存放在变量对应的内存单元中。有了一个有效的确定值,该变量才能在语句和表达式中用来参与运算或进行输出。否则,变量所对应的内存单元中(以前运行别的程序遗留下)的无效数据(我们将其称为垃圾数据),就会在程序语句的执行运算或输出时被误用,造成程序运行错误。
最简单的初始化变量的方法是在定义变量时,在变量后面用一个等号“=”给予它一个初始值。初始值必须是常量(或常量表达式)。比如以下变量定义:

int   number  ,  sum = 100;
char  ch1 = 'a'   ,  ch2;     
float  area = 65.432 ;

这三条变量定义的“变量内存取值示意图”如图2-2所示。
变量名 number sum ch1 ch2 area
变量的值 垃圾数据 100 'a' 垃圾数据 65.432


4feeef46afb90819a061f0e65c82ea8765ef1d07

可见,除了变量 number和ch2中的值是垃圾数据外,int型变量sum、char型变量ch1和float型变量area都得以初始化了。
初始化变量还有其他两种方法,即使用scanf()输入库函数和赋值语句(请参见2.12节和2.16节)。

相关文章
|
25天前
|
存储 C语言
【c语言】数据类型和变量
本文介绍了C语言中的数据类型和变量。数据类型分为内置类型和自定义类型,内置类型包括字符型、整型、浮点型等,每种类型有不同的内存大小和取值范围。变量分为全局变量和局部变量,它们在内存中的存储位置也有所不同,分别位于静态区和栈区。通过示例代码和图解,详细阐述了这些概念及其应用。
34 1
|
28天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
Java 编译器 C语言
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
【一步一步了解Java系列】:Java中的方法对标C语言中的函数
21 3
|
1月前
|
存储 C语言
C语言:设置地址为 0x67a9 的整型变量的值为 0xaa66
在C语言中,可以通过指针操作来实现对特定地址的访问和赋值。要将地址为 0x67a9 的整型变量值设为 0xaa66,可以先定义一个指向该地址的指针,并通过该指针对该内存位置进行赋值操作。需要注意的是,直接操作内存地址具有一定风险,必须确保地址合法且可写。代码示例应考虑字节序及内存对齐问题。
|
1月前
|
C语言 C++
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
|
1月前
|
存储 C语言
初识C语言:常量与变量中寻找数据类型
初识C语言:常量与变量中寻找数据类型
|
2月前
|
存储 C语言
【C语言基础考研向】02 数据类型-常量-变量
本文介绍了编程中的基本概念,包括数据类型分类、常量与变量的定义及使用。首先概述了四大类数据类型:基本类型(整型、浮点、字符型)、构造类型(数组、结构体)、指针类型和空类型。接着阐述了常量与变量的区别及命名规则,并详细说明了整型、浮点型和字符型数据的特点与应用。最后总结了常见的易错点,如字符串与字符常量的区别及浮点数的默认输出格式。
|
2月前
|
存储 传感器 物联网
结合物联网开发探讨C语言的变量
在物联网(IoT)开发中,C语言的变量起着至关重要的作用。由于物联网设备资源有限,C语言的高效性和对硬件的直接控制使其成为开发嵌入式系统的首选。
|
1月前
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
18 0
|
2月前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。