常量与变量
#include<stdio.h>
int main(void) //这个程序功能为用户输入圆的半径,计算圆的面积并输出
{
float r,result; //声明定义r和result
scanf("%f",&r); //读取用户输入的值并赋值给半径r
result = r*r*3.14; //计算圆的面积
printf("%f",result);//输出圆的面积
}
-
常量
在上面的代码中我们可以看到,无论输入的半径r是多少,我们都是通过常数3.14计算面积,在这里我们就把3.14这样不变的量叫做常量。(0基础的同学对于常量了解这些就足够啦)
像这种在程序中直接使用的常数,我们给它一个名字,叫做“幻数”。“幻数”的使用有时候会带来一些麻烦和问题。
(1)可读性差,我们都很熟悉3.14是圆周率π的近似值,因此可以很容易理解上面代码的含义,但在很多情 况下我们会忘记所用常数的含义。
(2)当我们在程序中很多地方使用幻数时,特别是多位小数时容易出现书写错误。
(3)当我们需要修改代码中的常数时,我们需要修改每一句用到该常数的语句。
对于这些问题,有些有一定基础的读者可能会这样解决,定义一个float类型的变量pi,并赋值为3.14,这样在使用3.14的时候全部用pi代替,修改的时候也只用改动赋值的代码即可。这个思路非常正确,在平时刷题考试的时候我们也常常使用这种方法。但这又带来一个问题,这个pi是一个变量,是能够被在程序的其他地方修改的,这就有可能影响答案的准确,
下面我们介绍两种不可修改的定义常量的方法。
一、宏常量(明示常量)与宏替换
对于上面的代码,我们可以改成这样
#include<stdio.h> #define PI 3.14 //定义宏常量PI int main(void) { float r,result; scanf("%f",&r); result = r*r*PI; printf("%f",result); }
通用格式如下:
#define 宏常量名字 宏常量的值
该语句置于程序顶部,宏常量习惯上以纯大写命名,且宏常量的值可以是任何类型,整形,字符串等
具体实现的原理其实很简单,就是在程序编译时,编译器会自动将代码中的所有PI总动替换成3.14,在程序运行时代码中所有的PI已被替换完成。
需要注意的是,由于宏定义是一种编译预处理指令,一般是不需要加分号的“;”(否则宏替换的时候会把分号也一起替换)。同时,#define、宏常量名字和宏常量的值之间的空格可以是任意多个的。并且,宏替换时不会进行语法检查,非常容易产生意想不到的错误。
二、const常量
使用const常量可以解决由于宏定义不进行语法检查而导致的问题。
#include<stdio.h>
int main(void)
{
const float PI = 3.14; //定义常量PI
float r,result;
scanf("%f",&r);
result = r*r*PI; //计算面积
printf("%f",result);
}
在声明语句中,将const放在类型修饰符前面即可。在编译的过程中,编译器会将该常量放在只读存储区(这个过程的具体原理暂时不需要了解),不允许在程序中更改它的值。
如果我们在计算面积之前加上如下语句
PI = 3.0;
在编译时会得到如下报错
意思是PI是只读的,只能在声明时更改它的值,在程序其他位置不可更改。
(感谢评论区用户CapriceH的补充: const常量在C语言中并不推荐使用,在有些编译环境下const场景不能作为数组的长度,另外在被指针指向的情况下const常量可以被修改,所以const常量也被叫做只读变量,在C语言中一般不推荐)
在具体的使用场景中,我们可以根据需要自己选择适合的定义常量的方法。
-
变量
变量不同于常量,它的值是在程序中是可以改变的,比如代码中的r和result,就由用户的输入所决定,并不是一成不变的。 变量有不同的类型,这决定了编译器为其分配内存的多少字节。
字节
在日常生活中,我们通常使用的是十进制,也就是常说的“满十进一”的表示方法,关于这种习惯有一种说法是人有十根手指,能表达十进制需要的十种形态。但在计算机硬件中,只有电路的通和断两种形态(即1和0),因此计算机中的一切数据都已二进制的形式保存,八进制和十六进制在本质上都是二进制(即3位二进制数表示1位八进制数,4位二进制数表示1位十六进制数)。我们代码中的所有符号,数字也好,字符也好,都会在编译时转化为二进制,得到的结果我们一般称为机器码(即机器阅读的代码)。
在描述计算机的数据单元或存储单元时,最小单位是位(bit,中文为比特),代表的是一位二进制数,我们常说的32位或64位计算机就是CPU一次最大能处理32位数据或64位数据的意思。但一位所能存储的数据太少了,我们更多的是使用字节(Byte)这个概念。几乎对于所有的机器,一字节均为8位。
具体如下表所示:
英文称谓 中文称谓 字节大小(大约) 换算方法 b(bite) 比特 B(Byte) 字节 一个字节 1 B = 8 bit KB K 一千字节 1 KB = 1024 B = 2^10 B MB 兆 百万字节 1 MB = 1024 KB = 2^20 B GB 吉 十亿字节(千兆) 1 GB = 1024 MB = 2^30 B TB 太 万亿字节 1 TB = 1024 GB = 2^40 B
具体的变量类型会在下一篇文章中讨论。
-
命名规则
在正式进入代码学习之前,笔者认为有必要介绍一下C语言各种变量、常量甚至是函数的命名规则。
我们一般把这些名字叫做标识符,各位读者需要明确一点,在C语言中标识符是区分大小写的(即大小写敏感)。比如我们前面代码中用到的变量result,和Result或rEsult等等在计算机看来都是不一样的。
其次,为了避免混淆,在命名过程中要尽量避免与关键字重复。关键字是C语言中有特殊含义的标识符。
C语言关键字整理如下:
auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while 以上是ANSI C定义的32个关键字,这些并不需要去死记硬背,只需要有个印象,我们在学习中会自然而然记住它们,比如我们前文提到的const常量中的const就是关键字之一。
除此之外,我们一般还遵循以下规则:
(1)标识符只能由英文字母、数字和下划线组成,建议使用见名知意的名字,可以使用英文单词大小写混排或中间加下划线的方式,但并不建议使用拼音。
(2)标识符必须以字母或下划线开头(而不是数字)。
(3)标识符基本可以包含任意多个字符,最大长度与编译器有关(基本不会达到限制)。
(注:未经允许不得转载)
我理解的C语言 #6:选择控制结构与goto语句
我理解的C语言 #5:循环控制结构
我理解的C语言 #4:格式化输入与输出
我理解的C语言 #3:基本数据类型与类型转换
我理解的C语言 #2:运算符、表达式和语句
我理解的C语言 #0:第一个程序——hello world