《小菜狗 C 语言入门 + 进阶笔记》(6)常量 - 转义字符 - ASCII 码

文章目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介

暂时无法在飞书文档外展示此内容

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 进制位的字符处终⽌。

注意:\0null 字符,代表没有内容, \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 中,有两种简单的定义常量的方式:

  1. 使用 #define 预处理器: #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值
  2. 使用 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) 宏替换只作替换,不做计算,不做表达式求解;

宏预编译时就替换了,程序运行时,并不分配内存。

文章目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介

每日一更!

公众号、CSDN等博客:小菜狗编程笔记

谢谢点赞关注哈!目前在飞书持续优化更新~

日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜狗编程笔记

你的鼓励将是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值