《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节)。

相关文章
|
7月前
|
存储 人工智能 程序员
一文彻底搞清楚C语言的数据类型和变量
本文介绍了数据类型(基本、构造、指针、空类型)、变量(使用、命名规则、作用域)和常量(字面、符号、枚举、表达式),帮助初学者理解编程基础概念。坚持学习,定能创造奇迹!
697 1
一文彻底搞清楚C语言的数据类型和变量
|
8月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
358 16
|
8月前
|
算法 C语言
【C语言程序设计——循环程序设计】求解最大公约数(头歌实践教学平台习题)【合集】
采用欧几里得算法(EuclideanAlgorithm)求解两个正整数的最大公约数。的最大公约数,然后检查最大公约数是否大于1。如果是,就返回1,表示。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。作为新的参数传递进去。这个递归过程会不断进行,直到。有除1以外的公约数;变为0,此时就找到了最大公约数。开始你的任务吧,祝你成功!是否为0,如果是,那么。就是最大公约数,直接返回。
200 18
|
8月前
|
Serverless C语言
【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】
根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码,求解出数值x的平方根;运用迭代公式,编写一个循环程序,求解出数值x的平方根。注意:不能直接用平方根公式/函数求解本题!开始你的任务吧,祝你成功!​ 相关知识 求平方根的迭代公式 绝对值函数fabs() 循环语句 一、求平方根的迭代公式 1.原理 在C语言中,求一个数的平方根可以使用牛顿迭代法。对于方程(为要求平方根的数),设是的第n次近似值,牛顿迭代公式为。 其基本思想是从一个初始近似值开始,通过不断迭代这个公式,使得越来越接近。
163 18
|
8月前
|
C语言
【C语言程序设计——循环程序设计】统计海军鸣放礼炮声数量(头歌实践教学平台习题)【合集】
有A、B、C三艘军舰同时开始鸣放礼炮各21响。已知A舰每隔5秒1次,B舰每隔6秒放1次,C舰每隔7秒放1次。编程计算观众总共听到几次礼炮声。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。开始你的任务吧,祝你成功!
164 13
|
8月前
|
存储 安全 C语言
【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】
分支的语句,这可能不是预期的行为,这种现象被称为“case穿透”,在某些特定情况下可以利用这一特性来简化代码,但在大多数情况下,需要谨慎使用。编写一个程序,该程序需输入个人数据,进而预测其成年后的身高。根据提示,在右侧编辑器补充代码,计算并输出最终预测的身高。分支下的语句,提示用户输入无效。常量的值必须是唯一的,且在同一个。语句的作用至关重要,如果遗漏。开始你的任务吧,祝你成功!,程序将会继续执行下一个。常量都不匹配,就会执行。来确保程序的正确性。
238 10
|
8月前
|
小程序 C语言
【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】
目录 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果: 任务描述 相关知识 编程编写一个程序,从键盘输入3个变量的值,例如a=5,b=6,c=7,然后将3个变量的值进行交换,使得a=6,b=7,c=5。面积=sqrt(s(s−a)(s−b)(s−c)),s=(a+b+c)/2。使用输入函数获取半径,格式指示符与数据类型一致,实验一下,不一致会如何。根据提示,在右侧编辑器补充代码,计算并输出圆的周长和面积。
161 10
|
8月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
196 3
|
8月前
|
存储 C语言
【C语言程序设计——循环程序设计】利用数列的累加和求 sinx(头歌实践教学平台习题)【合集】
项的累加和,一般会使用循环结构,在每次循环中计算出当前项的值(可能基于通项公式或者递推关系),然后累加到一个用于存储累加和的变量中。在C语言中推导数列中的某一项,通常需要依据数列给定的通项公式或者前后项之间的递推关系来实现。例如,对于一个简单的等差数列,其通项公式为。的级数,其每一项之间存在特定的递推关系(后项的分子是其前项的分子乘上。,计算sinx的值,直到最后一项的绝对值小于。为项数),就可以通过代码来计算出指定项的值。对于更复杂的数列,像题目中涉及的用于近似计算。开始你的任务吧,祝你成功!
190 6
|
8月前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
167 2