数据类型,变量和常量
第 2 讲数据类型、变量与常量第 2 讲数据类型、变量与常量1. 阅读前问题卡C 语言的数据类型、变量与常量1.1 阅读前先看这几个问题1.2 读完后完成这 3 个任务1.2.1 任务 1验证基本类型的长度1.2.2 任务 2拆解转义序列与字符串长度1.2.3 任务 3区分变量与常量1.3 自检清单2. 基本数据类型2.1 字符型2.2 整型2.3 浮点型2.4 布尔类型3. 类型修饰符3.1 short 和 long3.2 signed 和 unsigned3.3 取值范围4. ASCII 字符集和转义字符4.1 ASCII 字符集4.2 转义序列4.3 练习5. 变量和常量5.1 变量5.2 变量的分类5.3 常量5.3.1 字面常量5.3.2 符号常量5.3.3 const 修饰的常变量1. 阅读前问题卡C 语言的数据类型、变量与常量建议先读请先读“2. 基本数据类型”建立类型与数据的对应关系再进入类型修饰符、字符表示和变量分类。1.1 阅读前先看这几个问题C 语言如何用字符型、整型、浮点型和布尔类型描述不同的数据char、int、float、double和_Bool分别表示什么示例中的字面值默认属于什么类型short、long、signed和unsigned分别改变类型的哪一方面它们可以修饰哪些类型sizeof的结果为什么使用size_t表示并用%zu打印不同平台上的类型长度可能有什么差异char为什么也属于整型家族ASCII 字符值、字符转义序列和数字转义序列之间是什么关系全局变量与局部变量在作用域、生命周期、初始值和存储区域上有哪些区别字面常量、符号常量、const修饰的常变量和枚举常量分别是什么1.2 读完后完成这 3 个任务1.2.1 任务 1验证基本类型的长度做什么编译并运行文档中的sizeof示例记录char、_Bool、short、int、long、long long、float、double和long double的长度。验证标准能得到 9 个类型的字节数并指出自己的结果与文档平台对照表是否一致。1.2.2 任务 2拆解转义序列与字符串长度做什么逐段标注字符串c:\add\test\007\vip.c中的普通字符和转义序列先手工计算长度再运行strlen示例验证。验证标准手工结果与程序输出一致并能说明每个转义序列为什么只计为 1 个字符。1.2.3 任务 3区分变量与常量做什么用一个表格对比全局变量、局部变量、符号常量和const修饰的常变量。验证标准表格至少覆盖定义位置或形式、值能否修改、作用域或存储特点并能指出全局变量与局部变量同名时使用哪一个。1.3 自检清单我能根据数据的含义选择字符型、整型、浮点型或布尔类型。我能说明 4 个类型修饰符各自改变什么。我能使用sizeof查看类型长度并用正确的占位符打印结果。我能读懂常见 ASCII 值和两类转义序列。我能从作用域、生命周期和存储区域区分全局变量与局部变量。我能区分文档列出的 4 种常量形式。目标掌握 C 语言中的基本数据类型和修饰符。掌握 ASCII 字符集和转义字符。学习变量和常量的知识能在代码中熟练使用。2. 基本数据类型✍ 编程是为了解决生活中的问题那就得能描述生活中的问题生活中有各种各样的数据商品的价格、商品好评比例购物小票上的各种数据…那怎么描述这些信息呢C 语言提供了丰富的数据类型来描述生活中的各种数据。购物小票中可能包含的信息如下货号品名单位单价元数量小计15897463麻辣王子袋5.00315.0015869743鼠标个35.213105.63在这个小票当中我们包含了很多信息货号、品名、单位、单价、数量、小计。分析后发现信息类型货号整数 / 字符串品名字符串单位字符串单价小数数量整数小计小数使用整型类型来描述整数使用字符类型来描述字符使用浮点型类型来描述小数。 所谓“类型”就是相似的数据所拥有的共同特征。编译器只有知道了数据的类型才知道怎么操作数据。下面盘点一下 C 语言提供的各种数据类型本章节主要探讨内置数据类型。数据类型内置类型字符型char整型int浮点型float、double布尔类型_Bool派生类型指针类型char*、int*、float*、…自定义类型数组结构体struct枚举enum联合体union2.1 字符型字符的英文单词是character在 C 语言中使用char表示字符类型。char //characterchar ch; //使用char创建字符变量C 语言中字符使用一对单引号括起来比如x、a、w这些字符的类型就是char。2.2 整型整数的英文单词是integer在 C 语言中使用int表示整型类型。intint num; //使用int创建整型变量在 C 语言中100、20、35这些整数的类型就是int。2.3 浮点型float //单精度浮点型double //双精度浮点型float num1; //使用float创建变量double num2; //使用double创建变量在 C 语言中3.14、5.5这些小数的类型默认是double类型3.14f这种写法表示float类型。2.4 布尔类型C 语言在 C89/C90 时期并没有为布尔值单独设置一个类型使用整数0表示假非零值表示真。后来在 C99 标准中引入了专门表示真假的布尔类型。_Bool布尔类型变量的取值是true或者false这 2 个符号定义在stdbool.h头文件中。#define bool _Bool#define false 0#define true 1布尔类型的使用一般得包含头文件stdbool.h。代码演示#include stdbool.h_Bool flag true;if (flag)printf(“I like C\n”);一直到 C23 标准才把bool、true、false定为 C 语言关键字。使用bool类型不再依赖stdbool.h这个头文件了。标准布尔类型C89/C90没有布尔类型0表示假非0表示真C99引入_Bool类型需要包含stdbool.h兼容 C89/C90 写法C23引入bool类型不再需要包含stdbool.h兼容之前的写法AI 提示词C 语言中的布尔类型是如何演变的为什么 C99 中不直接使用bool而是使用_Bool3. 类型修饰符有前面介绍的数据类型其实已经能解决一部分问题但是在真实的开发过程中还是不够。为了让内置类型提供更精细的数据表示能力C 语言中还引入了类型修饰符//和内存长度有关的shortlong//和符号相关的signedunsigned就像最开始人类发明了汽车觉得很好了但是随着汽车的普及又衍生出了各种细分的汽车。3.1 short 和 longshort和long是和内存长度有关的两个类型修饰符。int //标准的整型//修饰整型short [int] //短整型long [int] //长的整型long long [int] //长的整型// []中的内容是可以省略的//修饰浮点型long double //C99中引入short和long用来修饰整型类型。常规的整型类型是int长度是 4 个字节short int类型的长度是 2 个字节。C 语言标准规定long int的长度大于等于int的长度。要想知道每个数据类型的长度我们可以使用sizeof来计算。sizeof是 C 语言的一个操作符可以算出一个数据类型的长度单位是字节使用方法是sizeof(type)type就是对应的数据类型。sizeof计算的结果是size_t类型打印时应该使用%zu占位符。请看下面的代码#include stdio.hint main(){printf(“char: %zu\n”, sizeof(char));printf(“_Bool: %zu\n”, sizeof(_Bool));printf(“short: %zu\n”, sizeof(short));printf(“int: %zu\n”, sizeof(int));printf(“long: %zu\n”, sizeof(long));printf(“long long: %zu\n”, sizeof(long long));printf(float: %zu\n, sizeof(float)); printf(double: %zu\n, sizeof(double)); printf(long double: %zu\n, sizeof(long double)); return 0;}类型VS 2026 / MSVCmingw64 GCCLinux GCCchar111_Bool111short222int444long448long long888float444double888long double81616注long和long double类型的长度与平台采用的数据模型有关。数据模型指的是在特定操作系统、CPU 架构和 ABI应用程序二进制接口下C/C 等语言中基本整数类型short、int、long、long long以及指针类型的具体位宽字节数的约定。参考资料数据类型长度和取值范围 - 官方介绍数据类型的长度关系如下//整型家族1 sizeof(char) sizeof(short) sizeof(int) sizeof(long) sizeof(long long)//浮点型家族sizeof(float) sizeof(double) sizeof(long double)3.2 signed 和 unsignedsigned和unsigned是和符号相关的两个类型修饰符专门修饰字符型和整型类型。我们生活中表示的数值有的有正有负有的只有正数。比如温度、海拔高度、财务盈亏、电梯楼层、银行账户流水等数据有正也有负年龄、长度、身高、体重等数据只有正数和 0 的可能。signed关键字表示一个类型带有正负号可以表示正整数、负整数和 0。unsigned关键字表示该类型不带有正负号只能表示零和正整数。类型有符号类型无符号类型charsigned charunsigned charshort [int][signed] short [int]unsigned short [int]int[signed] intunsigned intlong [int][signed] long [int]unsigned long [int]long long [int][signed] long long [int]unsigned long long [int]对于int类型默认是带有正负号的也就是说int等同于signed int。由于这是默认情况关键字signed一般都省略不写但是写了也不算错。但是C 语言中的char有可能是signed char也有可能是unsigned char具体等价于哪个是由编译器的具体实现定义的。这一点和int类型有差异。我们前面通过sizeof算出长度的类型是size_t。size_t就是无符号整型因为长度不可能是负数。sizeof操作符的返回值C 语言只规定是无符号整数并没有规定具体类型而是留给系统自己决定。不同系统中返回值的类型有可能是unsigned int也有可能是unsigned long甚至是unsigned long long对应的printf()占位符分别是%u、%lu和%llu。这样不利于程序的可移植性。C 语言提供了一个解决方法创造了一个类型别名size_t用来统一表示sizeof的返回值类型。对应当前系统的sizeof返回值类型可能是unsigned int也可能是unsigned long long。size_t类型的值在打印时的占位符是%zu。3.3 取值范围我们看到不同的数据类型长度是不同的长度不同又决定了存放数据的范围不同。这里看一下不同数据类型的取值范围。整型家族的取值范围可以在limits.h这个头文件中查看。浮点型家族的取值范围可以在float.h这个头文件中查看。类型大小字节取值范围有符号char1-128 到 127short2-32,768 到 32,767int432/64 位系统-2,147,483,648 到 2,147,483,647long4 或 8-2,147,483,648 到 2,147,483,64732 位/ -9.22e18 到 9.22e1864 位实测long long8-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807float4±1.2E-38 到 ±3.4E38约 6~7 位有效数字double8±2.3E-308 到 ±1.7E308约 15~16 位有效数字long double8 或 16在 x86 架构下通常是 80 位10 字节取值范围比 double 更大为了代码的可移植性需要知道某种整数类型的极限值时应该尽量使用这些常量。SCHAR_MINSCHAR_MAXsigned char的最小值和最大值。SHRT_MINSHRT_MAXshort的最小值和最大值。INT_MININT_MAXint的最小值和最大值。LONG_MINLONG_MAXlong的最小值和最大值。LLONG_MINLLONG_MAXlong long的最小值和最大值。UCHAR_MAXunsigned char的最大值。USHRT_MAXunsigned short的最大值。UINT_MAXunsigned int的最大值。ULONG_MAXunsigned long的最大值。ULLONG_MAXunsigned long long的最大值。4. ASCII 字符集和转义字符4.1 ASCII 字符集在 C 语言中char类型是字符类型用来表示字符但它也属于整型家族。那么这些字符的值是多少呢比如a的值是多少x的值是多少呢这里的值可能根据计算机的不同而不同因为不同的机器可能使用不同的字符集。当前我们见到的 Windows/Linux/macOS 平台上采用 ASCII 字符集而 IBM 大型机等老旧或专用系统还使用 EBCDIC 字符集。我们主要掌握现在主流的 ASCII 字符集就行。ASCII 字符集中规定了 128 个字符对应的数值如下图。后来 ASCII 码常被扩展为 256 个字符目的是兼容更多国家语言中的字符。参考https://zh.cppreference.com/w/cpp/language/ascii我们不需要记住 ASCII 码表中的所有数字使用时查看就可以不过最好能掌握几组特殊的数据字符 A~Z 的 ASCII 码值从 65~90按照字母顺序递增 1。字符 a~z 的 ASCII 码值从 97~122按照字母顺序递增 1。对应的大小写字符a 和 A的 ASCII 码值差值是 32。数字字符 0~9 的 ASCII 码值从 48~57按照数字顺序递增 1。换行\n的 ASCII 值是 10。在这些字符中ASCII 码值从 0~31 的 32 个字符是不可打印字符无法打印在屏幕上观察。这里通过代码看一下这些字符对应的数值。#include stdio.hint main(){printf(“%d\n”, ‘X’);printf(“%d\n”, ‘#’);return 0;}4.2 转义序列通常情况下字符是被单引号括起来的单个字符比如a、x。但是 ASCII 码值从 0~31 的字符是不可打印字符比如换行符无法通过单引号括起来的单个字符表示。这些单个字符都已经有具体的意义了那这些字符如何表示呢为了使程序可以处理字符集中的每一个字符C 语言提供了一种特殊的表示法转义序列。转义序列有 2 种字符转义序列和数字转义序列。字符转义序列转义字符解释\?在书写连续多个问号时使用防止它们被解析成三字母词在新的编译器上没法验证了。\用于表示字符常量。\用于表示一个字符串内部的双引号。\\用于表示一个反斜杠防止它被解释为一个转义序列符。\a警报这会使终端发出警报声或出现闪烁或者两者同时发生。\b退格键光标回退一个字符但不删除字符。\f换页符光标移到下一页。在现代系统上这已经反映不出来了行为改成类似于\v。\n换行符一般用于在屏幕上打印信息时实现换行效果。\r回车符光标移到同一行的开头。\t制表符光标移到下一个水平制表位通常是下一个 4/8 的倍数。\v垂直分隔符光标移到下一个垂直制表位通常是下一行的同一列。除了上面的这些转义字符之外字符转义序列不能表示其他的不可打印字符所以就有了数字转义序列。数字转义序列转义字符解释表示形式\dddddd 表示 1~3 个八进制数字。如\130表示X字符的 8 进制表示形式\xdddd 表示 2 个十六进制数字。如\x30表示字符0字符的 16 进制表示形式数字转义序列可以表示 ASCII 字符集中的所有字符。需要把一个字符写成数字转义序列时查看一下 ASCII 字符集中字符对应的 8 进制数值和 16 进制数值就很好转化了。4.3 练习#include stdio.h#include string.h //strlen 函数需要int main(){printf(“%zu\n”, strlen(“c:\add\test\007\vip.c”));return 0;}strlen是求字符串长度的库函数统计的是字符串中\0之前的字符个数\0是字符串的结束标志。注意识别字符串中的转义字符一个转义字符在统计时只算一个字符。5. 变量和常量清楚了 C 语言中的数据类型后数据类型最主要的功能就是创建变量和常量。什么是变量什么是常量呢变量和常量都是用来存储数据的“容器”但它们最核心的区别在于变量的值可以改变而常量的值一旦设定就不能再修改。5.1 变量变量创建的语法形式是这样的data_type name;| || |数据类型 变量名变量命名的一般规则变量的名字要有意义见名知意。只能由字母包括大写和小写、数字和下划线_组成。不能以数字开头。长度不能超过 63 个字符。变量名区分大小写。变量名不能使用关键字。举例char ch;int age;double weight;int 2b;//这个正确吗变量在创建时就给一个初始值叫作初始化。char ch ‘w’;int age 18;double weight 48.0;unsigned int high 180;5.2 变量的分类全局变量在函数之外定义的变量称为全局变量。作用域从定义位置开始到整个源文件末尾都可见如果其他文件想用可通过extern声明。生命周期在程序启动时创建程序结束时才销毁存储在内存的静态存储区 / 数据段。初始值如果没有显式初始化系统会自动初始化为 0或\0、NULL。使用注意过多使用全局变量会导致模块间耦合度高、调试困难建议谨慎使用。 全局变量就类似马路上的共享单车大家都可以使用。#include stdio.hint globalVar 100; // 全局变量void show(){printf(“全局变量值: %d\n”, globalVar);}int main(){show();globalVar 200; // 直接修改全局变量printf(“修改后: %d\n”, globalVar);return 0;}局部变量在大括号内部定义的变量就是局部变量。作用域仅限于定义它的函数或代码块内部外部无法访问。生命周期在进入函数 / 代码块时创建退出时自动销毁存储在内存的栈区。初始值如果没有显式初始化其值是垃圾值不确定的随机数建议对局部变量进行初始化。优先级当局部变量与全局变量同名时优先使用局部变量。 局部变量就类似于你们家自己的自行车只有你家里人有权利使用它。#include stdio.hvoid func(){int localVar 10; // 局部变量printf(“%d\n”, localVar);}int main(){// printf(“%d”, localVar); // 错误main函数无法访问func中的localVarreturn 0;} AI 提示词 1在 C 语言中什么是作用域什么是生命周期AI 提示词 2软件开发中什么是高内聚低耦合AI 提示词 3对比一下 C 语言中的全局变量和局部变量AI 提示词 4什么情况下使用全局变量什么情况下使用局部变量全局变量和局部变量在内存中存储在哪里呢一般我们在学习 C/C 语言的时候会关注内存中的 3 个区域栈区、堆区、静态区。局部变量放在内存的栈区。全局变量放在内存的静态区数据段。堆区用于动态内存管理后期会介绍。栈区局部变量、函数参数。堆区动态内存管理malloc、calloc、realloc、free。静态区全局变量、静态变量。5.3 常量C 语言中常量主要以下面这几种形式呈现字面常量符号常量const常量枚举常量5.3.1 字面常量//字符常量‘a’‘x’//整型常量//十进制字面常量123-4560//八进制字面常量以 0 开头037等于十进制的 31//十六进制字面常量以 0x 或 0X 开头0x1F (等于进制的31)。//后缀u 或 U表示无符号整数unsigned如 100U。l 或 L表示长整型long如 123L。ll 或 LL表示长长整型long longC99 起如 123LL。可组合100ULunsigned long。//浮点型字面常量3.14 //double类型3.14f //float 类型3.14L //long double类型1.2e3 //科学计数法表示1.2×10³5.3.2 符号常量//符号常量通常名字是全大写的#define M 100#define PI 3.14159int main(){int Max M;printf(“M %d\n”, M);printf(“Max %d\n”, Max);printf(“pi %lf\n”, PI);return 0;}5.3.3 const 修饰的常变量使用const关键字修饰的变量其值在初始化后不可修改但本质上仍然是变量有类型、有地址只是编译器禁止赋值操作。const double e 2.71828; // 浮点常变量const int days_in_week 7;days_in_week 8; // 错误不能修改 const 变量总结一下变量值可以变就像一个小白板可以反复擦写。常量值不能变就像刻在石碑上的字一旦确定就不允许更改。6.回答上面的问题问题1.C 语言如何用字符型、整型、浮点型和布尔类型描述不同的数据答使用整型类型来描述整数使用字符类型来描述字符使用浮点型类型来描述小数。问题2char、int、float、double和_Bool分别表示什么示例中的字面值默认属于什么类型答char代表字符型int代表整型float和double代表浮点型-Bool代表布尔类型。问题3.short、long、signed和unsigned分别改变类型的哪一方面它们可以修饰哪些类型答short和long改变长度用来修饰整数类型。signed和unsigned改变数值的正负专门修饰字符型和整型类型问题4sizeof的结果为什么使用size_t表示并用%zu打印不同平台上的类型长度可能有什么差异答sizeof计算的结果是size_t类型打印时应该使用%zu占位符长度与平台的数据模型有关问题5char为什么也属于整型家族ASCII 字符值、字符转义序列和数字转义序列之间是什么关系答转义序列能够处理ASCII中的每一个字符而字符转义序列和数字转义序列属于转义序列问题6全局变量与局部变量在作用域、生命周期、初始值和存储区域上有哪些区别答全局变量的作用在函数外而局部变量在定义它的函数内前者的生命周期更长直到程序结束局部变量的初始值无显化后者的储蓄区域在内存的扎区前者在内存的静态区数据段问题7字面常量、符号常量、const修饰的常变量和枚举常量分别是什么答字面常量是直接写在代码的数值本身符号常量是预编译阶段的文本替换const修饰的常变量是值不能修改的的数据类型本质是变量。枚举常量是用enum枚举类型定义出来的常量。