暂时无法在飞书文档外展示此内容
1、常量(Constant)的定义
常量:是计算机程序运行过程中其值不能发生改变的量。这些固定的值,又叫做字面量。
- 常量可以是
任何的基本数据类型
,比如整数常量、实型常量(浮点常量)、字符常量,或字符串常量,也有枚举常量
。 - 常量就像是常规的变量,常量的值
在定义后不能进行修改
。 - 常量可以直接在代码中使用。
- 也可以通过定义常量来使用,如底下
章节
7、定义常量
。
2、整数常量
整数常量可以是十进制、八进制或十六进制的常量。
前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀
,后缀是 U 和 L 的组合
,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,并且 U 和 L 的顺序任意。
下面列举几个整数常量的实例:
215u /* 合法的 /
0xFeeL / 合法的 /
078 / 非法的:8 不是八进制的数字 /
032UU / 非法的:不能重复后缀 */
以下是各种类型的整数常量的实例:
85 /* 十进制 /
0213 / 八进制 /
0x4b / 十六进制 /
30 / 整数 /
30u / 无符号整数 /
30l / 长整数 /
30ul / 无符号长整数 */
3、实型常量(浮点常量)
3.1、科学计数法
表示方式:
例如:
1.2E+2: 可以理解为小数点向右移动 2 位,1.2E+2 = 120
1.2E-2: 可以理解为小数点向左移动 2 位,1.2E-2 = 0.012
精度:
6 位有效位,指的是不是小数的位数,是以第一个非 0 数字开始数 6 位。
比如:
12345.6789,6 位精度位指的是 12345.6
0.00012456789,6 位精度位指的是 123456
以下是一些使用的例子:
如果您需要存储一个小数点后只有一位的数字,例如温度计度数,您可以使用 float 类型。
float temperature = 25.5f;
如果您需要存储一个小数点后有多位数字的数字,例如圆周率,您应该使用 double 类型。
double pi = 3.14159265359;
3.2、组成成分
浮点常量由整数部分、小数点、小数部分和指数部分组成。
您可以使用小数形式或者指数形式来表示浮点常量。
下面再列举几个浮点数常量的实例:
510E /* 非法的:不完整的指数 / 210f / 非法的:没有小数或指数 / .e55 / 非法的:缺少整数或分数 */
3.3、带后缀
浮点数常量可以带有一个后缀表示数据类型,如下:
后面不加后缀的话 默认表示 double 类型,例如 3.14 就是 double 类型
后面加 f 或 F 认为是 float 型,例如 3.14f 就是 float 类型
4、字符常量(扩展加深)
4.1、定义:
字符
就是我们在键盘上敲出来的单个符号,如:A,a,1,@,#,$,~ 等等。
字符常量
就是用单引号
括起来的单个普通字符(例如 ‘x’) 或 转义字符
(例如 ‘\t’)或一个通用的字符(例如 ‘\u02C0’)。
联系
:C 语⾔中提供了⼀种类型叫 char
,这种类型专⻔是⽤来创建字符变量,字符变量
是⽤来存储字符
的。比如:
char ch = 'a';
4.2、字符常量的值:
字符常量的值是该字符的 ASCII码
的值,不了解 ASCII 码 请先查看底下章节
4.4、ASCII 码
。
4.3、转义字符:
**定义:**反斜线(\)后面跟一个字符或一个代码值表示。
当它们前面有反斜杠时,它们就具有特殊的含义。下表列出了一些这样的转义字符红色为常用的转义字符):
转义字符详细解释:
- ? :在书写连续多个问号时使⽤,防⽌他们被解析成三字⺟词。
- ’ :⽤于表⽰字符常量’?
- " :⽤于表⽰⼀个字符串内部的双引号
- \ :⽤于表⽰⼀个反斜杠,防⽌它被解释为⼀个转义序列符。
- \a :警报,这会使得终端发出警报声或出现闪烁,或者两者同时发⽣。
- \b :退格键,光标回退⼀个字符,但不删除字符。
- \f :换⻚符,光标移到下⼀⻚。在现代系统上,这已经反映不出来了,⾏为改成类似于 \v 。
- \n :换⾏符。
- \r :回⻋符,光标移到同⼀⾏的开头。
- \t :制表符,光标移到下⼀个⽔平制表位,通常是下⼀个 8 的倍数。
- \v :垂直分隔符,光标移到下⼀个垂直制表位,通常是下⼀⾏的同⼀列。
- \ddd :d d d 表⽰ 1~3 个⼋进制的数字。 如:\130 表⽰字符 X
8 进制转义序列拥有 3 个⼋进制位的⻓度限制,但若提前遇到不是合法 8 进制位的字符,则在⾸个这种字符处终⽌。
- \xdd :d d 表⽰ 2 个⼗六进制数字。 如:\x30 表⽰字符 0
16 进制转义序列⽆⻓度限制,并在⾸个不是合法 16 进制位的字符处终⽌。
注意:
\0
:null 字符
,代表没有内容, \0 就是 \ddd 这类转义字符的⼀种,⽤于字符串的结束标志,其 ASCII 码 值是 0。后面字符串要用到,大家的易错点!
再比如之前的实例里的转义字符 ‘\n’,就是代码换行的意思:
C 实例 – Hello World – 来源于(2.4)C 语言编程入门 – C 基础语法
printf("Hello, World! \n"); //输出语句
C 实例 – 成绩录入 – 来源于(2.5)C 语言编程入门 – C 数据类型
printf("成绩是:%d\n", score); //输出语句
4.4、ASCII 码
首先在计算机中所有的数据都是以⼆进制的形式存储的,编码就是每个字符编成⼀个⼆进制序列。后面为了⽅便⼤家相互通信的⽅便,不造成混乱,后来美国国家标准学会(ANSI)出台了⼀个标准 ASCII 编码,C 语⾔中的字符就遵循了 ASCII 编码的⽅式。
4.5、字符常量 和 ASCII 码
4.5.1、字符常量 与 整型常量
比如:字符常量 ‘5’ 与整型常量 5 之间的区别与联系:
**区别:
**5 表示一个整数,而 ‘5’ 表示一个字符
联系:
‘5’ 的 ASCII 码 为整数 53
即:字符类型本质上也是整型!
数字与数字字符之间的转换,如:
'5' - 48 => 5
5 + 48 => '5'
大小写字母之间的转换,如:
'A' + 32 => 'a'
'a' - 32 => 'A'
4.5.2、需要记住的小知识
在后面的代码编写中,我们最好能掌握⼏组特殊的 ASCII 码,如下:
- 字符 A~Z 的 ASCII 码 对应的值是 65~90 ;
- 字符 a~z 的 ASCII 码 对应的值是 97~122 ;
- 对应的⼤⼩写字符 (a 和 A) 的 ASCII 码 的差值是 32 ;
- 数字字符 0~9 的 ASCII 码 对应的值是 48~57 ;
**注意:**在这些字符中 ASCII 码 从 0~31 这 32 个字符是不可打印字符,⽆法打印在屏幕上观察的。
**4.5.3、扩展 1:**打印所有的可打印字符
#include <stdio.h>
int main()
{
int i = 0;
for(i = 32; i <= 127; i++)
{
printf("%c ", i);
if(i % 32)
printf("\n");
}
return 0;
}
输出的结构如下:
4.5.4、扩展 2:使用不同的占位符
字符常量的 ASCII 码 值可以通过占位符的不同打印出不同结果,如下:
#include <stdio.h>
int main()
{
char myChar = 'a';
int myAscii = (int) myChar; //将 myChar 转换为 ASCII 值 97
printf("myChar vlaue is: %c\n", myChar); //以字符形式输出
printf("myChar vlaue is:%d\n", myAscii); //以十进制输出
printf("myAscii vlaue is:%d\n", myAscii); //将myChar转换为ASCII值为97
return 0;
}
5、字符串常量
C 语⾔中有字符类型,但是没有字符串类型,C 语⾔中字符串
就是由双引号引起来的⼀串字符
,比如:“abcdef”;
⼀个字符串中我们直观的能看到⼀些字符,比如:字符串常量 “abcdef” 中,我们看到了 a、b、c、d、e、f 这 6 个字符,但是实际上在末尾还隐藏
⼀个 '\0'
的转义字符
(参考 **4.3、转义字符)**作为字符串结束标志
。
再比如以下图示:用双引号括起来的字符串: “hello, world” , “A”, “”
**注意:**字符串常量的实际字符数总是比其双引号中的字符数多 1,编码过程中的易错点。
6、字符常量与字符串常量
**注意:**字符常量和字符串常量是两个不同的概念
例如:
'a' == a
"a" == a\0
因此底下就出现不同的现象,char ch 是定义了一个单字符变量
,"a" == a \0
是两个字符,字符 'a' + '\0'
, 因此左图报错!
7、定义常量
在 C 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器: #define 可以在程序中定义一个常量,
它在编译时会被替换为其对应的值
。 - 使用 const 关键字:const 关键字用于声明一个只读变量,
即该变量的值不能在程序运行时修改
。
7.1、#define 预处理器
下面是使用 #define 预处理器定义常量的简单形式
:
#define 常量名 常量值
#define PI 3.14159
定义了一个名为 PI 的常量,在程序中使用该常量时,编译器会将所有的 PI 替换为 3.14159。
注意:把常量定义为大写字母形式,是一个很好的编程习惯。
具体请看下面的实例:
#include <stdio.h>
#define LENGTH 10
#define WIDTH 5
int main()
{
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
value of area : 50
7.1.1、边缘效应或者括号问题
define 注意“边缘效应”,例:#define N 2+3, N 的值是 5。
double a;
a = (float)N/(float)2;
在编译时我们预想 a=2.5,实际打印结果是 3.5 原因是在预处理阶段,编译器将 a=N/2 处理成 a=2+3/2,这就是 define 宏的边缘效应,所以我们应该写成 #define N (2+3)。
7.2、const 关键字
您可以使用 const 前缀声明指定类型的常量,如下所示:
const 数据类型 常量名 = 常量值;
const int var = 5;
定义了一个名为 var 的常量,在程序中使用该常量时,其值将始终为 5,并且不能被修改。
const 声明常量要在一个语句内完成:
7.3、#define 与 const 区别
#define 与 const 这两种方式都可以用来定义常量。
通常情况下,建议使用 const 关键字来定义常量,因为它具有类型检查和作用域的优势,而 #define 仅进行简单的文本替换,可能会导致一些意外的问题。
#define 预处理指令和 const 关键字在定义常量时有一些区别:
- 替换机制:
#define
是进行简单的文本替换
,而const
是声明一个具有类型的常量
。#define
定义的常量在编译时会被直接替换为其对应的值,而const
定义的常量在程序运行时会分配内存,并且具有类型信息。 - 作用域:
#define
定义的常量没有作用域限制,它在定义之后的整个代码中都有效。而const
定义的常量具有块级作用域,只在其定义所在的作用域内有效。 - 调试和符号表:使用
#define
定义的常量在符号表中不会有相应的条目,因为它只是进行文本替换。而使用const
定义的常量会在符号表中有相应的条目,有助于调试和可读性。
const 定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型。编译运行的时候起作用存在类型检查。
define 定义的是不带类型的常数,只进行简单的字符替换。在预编译的时候起作用,不存在类型检查。
1、两者的区别
(1) 编译器处理方式不同
- #define 宏是在预处理阶段展开。
- const 常量是编译运行阶段使用。
(2) 类型和安全检查不同
- #define 宏没有类型,不做任何类型检查,仅仅是展开。
- const 常量有具体的类型,在编译阶段会执行类型检查。
(3) 存储方式不同
- #define 宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。(宏定义不分配内存,变量定义分配内存。)
- const 常量会在内存中分配(可以是堆中也可以是栈中)。
(4) const 可以节省空间,避免不必要的内存分配。 例如:
#define NUM 3.14159 //常量宏
const doulbe Num = 3.14159; //此时并未将i放入ROM中
double i = Num; //此时为i分配内存,以后不再分配!
double I = NUM; //编译期间进行宏替换,分配内存
double j = Num; //没有内存分配
double J = NUM; //再进行宏替换,又一次分配内存!
const 定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象 #define 一样给出的是立即数,所以,const 定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define 定义的常量在内存中有若干个拷贝。
(5) 提高了效率。 编译器通常不为普通 const 常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
(6) 宏替换只作替换,不做计算,不做表达式求解;
宏预编译时就替换了,程序运行时,并不分配内存。
每日一更!
公众号、CSDN等博客:小菜狗编程笔记
谢谢点赞关注哈!目前在飞书持续优化更新~
日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!