欢迎大家访问http://melonc.io来学习C语言,可以在浏览器中直接编辑和运行C语言,同时也有ChatGPT辅助解释和诊断,提供还提供了其他文章和C语言项目。
本文在melonc.io中的中文文章中亦可找到(传送门),且会直接在文章中给出在线尝试功能,推荐读者在melonc.io中进行学习。
本文重写自笔者以前所写的同名文章,重写原因是因为,曾经的文章中有些类比描述过于复杂,所述的文章中提及的细节并不利于让零基础的初学者快速上手,因此对这部分做了重写和删减,希望改进后的文章可以更好的帮助即将学习C语言的你。
变量
我们先描述一下变量这个概念。其实这个概念与数学中变量的概念是一致的,即一个符号所指代的值是可改变的。所以变量或许被叫做可变量更准确。这就好比一个纸箱,箱子里最开始装了10个苹果,然后我将它们逐个取出,每取一个,其内部苹果的数量就减一,那么这个纸箱就是一个变量。我们可以用如下形式进行书写:
box = 10;box = box - 1;
在计算机的世界中,纸箱就等价于内存,我们所有变量的数据都是存放在内存上的(这里并不准确,事实上有部分数据存放在寄存器上,但本文暂不过多涉及)。
常量
有了变量,那么就要说说常量。常量的含义与变量刚好相反,即一个符号所指代的值一旦指定后就不可变了。对于上面的那个类比就是,一个纸箱内部必须有10个苹果,且不可以多一个也不可以少一个,必须正好是10。这样,当后续再次提及这个箱子时,所有人都知道它等价于10个苹果,不会有出入。
数据类型
有了变量和常量的概念,那么下一个问题就是,这个可存储数据的空间大小是多大呢?或者说这个箱子的规格是什么样的呢?这就涉及到了数据类型。
在C语言中,这些类型有:
- 整型,即整数
- 浮点型,即实数
- 字符型,即单个的可打印字符(什么叫可打印的我们后面会说到)
- 空类型,即无类型
- 指针类型
下面我们将逐个类型说明,初学者暂时不需要死记硬背每一个类型的数值范围,在有需求时查阅范围即可。
整型分为:
- 有符号短整型,对应关键字为short,占用2字节内存,即该类型的数据值范围为-32,768 到 32,767
- 无符号短整型,对应关键字为unsigned short,占用2字节内存,数据值范围0 到 65,535
- 有符号整型,关键字int,占用4字节(注意,在windows上这个类型占2字节),数据值范围-2,147,483,648 到 2,147,483,647
- 无符号整型,关键字unsigned int,占用4字节,数据值范围0 到 4,294,967,295
- 有符号长整型,关键字long,32位系统上占4字节,数据值范围-2,147,483,648 到 2,147,483,647,64位系统上占8字节,数据值范围-9223372036854775808到9223372036854775807
- 无符号长整型,关键字unsigned long,32位系统上占4字节,数据值范围0 到 4,294,967,295,64位系统上占8字节,数据值范围0到18446744073709551615
- 还有long long和unsigned long long,占8字节内存,数据值范围分别为-9223372036854775808到9223372036854775807和0到18446744073709551615
浮点型分为:
- 单精度浮点型,关键字为float,占4字节,数值范围1.2E-38 到 3.4E+38,精度是精确到6位小数
- 双精度浮点型,关键词为double,占8字节,数值范围2.3E-308 到 1.7E+308,精度是精确到15位小数
- 还有一种,我词穷了,不知道中文该怎么叫了,关键词为long double,占16字节,数值范围3.4E-4932 到 1.1E+4932,精度是精确到19位小数
可以看到,实数都是有一个精度范围的,如果超出这个精度范围就会造成精度损失,因此在运行一些除法运算后再执行乘法力图恢复初始值时有时是不可能的。
字符型分为:
- 有符号字符,关键词char,占1字节,数值范围-128 到 127
- 无符号字符,关键词unsigned char,占1字节,数值范围0 到 255
其中char型字符为可输出字符,参考ASCII码表来找到其对应的输出到终端上的字符:
其中,值为0~31和127的字符是控制类字符,剩余为可显示字符。
空类型:又称为void型,关键字为void,表示无类型或者不知其类型。
指针类型:本节暂时不讨论,留待后续专门讨论指针的文章中详述。
看一些例子
到此,我们来看一下各种类型的例子,巩固一下前面的内容。
整型示例:
short var_1 = -1; //有符号短整型unsigned short var_2 = 65535; //无符号短整型int var_3 = 1000000; //有符号整型unsigned int var_4 = 999999999; //无符号整型long var_5 = 9876278913; //有符号长整型unsigned long var_6 = 12871236897; //无符号长整型long long var_7 = -1238123871; //码哥词穷,这类型你就当是长长整型吧...unsigned long long var_8 = 1987623453;const int a = 10; //整型常量a的值为10const short b = 127; //短整型常量b的值为127
浮点型示例:
float var_1 = 3.141592; //单精度浮点数double var_2 = 1.124987651; //双精度浮点数long double var_3 = 3231.3123817682;const float pi = 3.141592; //单精度浮点型常量pi的值为3.141592
字符型示例:
char var_1 = 70; //有符号字符型char var_2 = 'F'; //有符号字符型,var_2和var_1其实是相等的,在ASCII码表中,F的十进制值即为70
//如果要给char型变量赋值ASCII码表中可显示字符,需要用单引号扩住,且单引号内只能有一个字符
//但有一种特例,叫做转译字符例如下面:
char var_3 = '\n'; //这里的 \ 就是转义字符,当编译器遇到转自字符时会吞掉转义字符,
//并查看其后字符是什么字符,然后转成相应特定字符,本例中\n为换行符,即ASCII中值为10的换行符。unsigned char var_4 = 255; //无符号字符型const char enter = '\n'; //字符型常量enter的值为 \n
变量以及常量的命名要求
上面的示例中对变量和常量的名字命名都是形如:
var_xxx
其实在C语言中,变量与常量的名字命名是有规范的,要求如下:
名字必须以字母或者下划线开头,后面的字符既可以是字母也可以是下划线也可以是数字。
所以,形如如下名字是不合法的:
123_abc
-a
+a
123bcd
类型转换
先来看一个例子体会一下:
int a = 5.0 / 2;
/表示➗,即除法。这时a的值是多少呢?
答案是2,而不是2.5。这里就是类型转换起了作用。5.0是浮点数,浮点数除整数,得到的结果还是浮点数,但是这个值赋给了整型变量a,因此除法的结果需要满足a的类型约束,只保留整数部分,因此就是2。这里也不存在四舍五入一说,即便是2.99999也会是2,而不是3。
上面的这种转换叫做自动类型转换,与之相对的转换模式叫强制类型转换。
我们先看下强制类型转换的例子,也就能理解上面这个例子叫自动类型转换了。
int b = (int)2.5;
在这个例子中,如果不在2.5前加(int),那么编译器会给出警告,说你这么写等于是“偷摸地”将双精度浮点数转换为整型了。为了避免这个警告(当然,取整数也是符合这个例子中我的预期的,即我要的也是整数),在2.5前加入:
(基础数据类型) //本例为(int)
将2.5先转成整型2,然后赋给变量b。
下面看一些其他类型转换的例子:
unsigned char var_1 = (unsigned char)'F'; //因为'F'默认为char型short var_2 = (short)999999; //999999为int型,直接赋值会爆出警告,强制类型转换后不会有警告,但是var_2的值为16959
这里var_2的值为16959的原因是:
整型999999占4字节,其十六进制为0x000F423F。short类型占2字节,因此会将int型的低16位(即后两字节)内容赋给变量var_2,也就是0x423F,这个十六进制数转换为十进制后的值就是16959。
对于十六进制不了解的读者,可以去网上先充一下电,因为十六进制在编程中用到的频度不比整数低。
感谢阅读!