第二章笔记

1、
变量本身数据类型不固定的称为动态语言,如
a = 123
a = ‘hello’
a = 3.14
相对的是静态语言,如
int a = 123 #a是整数类型变量
a = ‘abc’ #错误,不能把字符串赋给整数型变量

2、变量在计算机内存中的表示
当写入 a = ‘abc’ 时,python解释器做了两件事:
一、在内存中创建一个 ‘abc’ 的字符串;
二、在内存中创建一个 ‘a’ 的变量,并把它指向 ‘abc’
当我们把 a 赋值给 b 时,实际上是 b 指向 (a 指向的数据).
如 a = ‘abc’
b = a # b 指向 a 指向的字符串 ‘abc’
a = ‘xyz’
print(b)
print(a)
输出是’abc’和’xyz’.
3、python的整数没有大小限制,浮点数也没有,但是超过一定范围就直接表示为inf(infinite)。

4、8个比特 (bit) 作为一个字节 (byte) ,一个字节能表示的最大整数为255(二进制11111111=十进制255)。如果要表示更大的整数,就要更多字节,如两个字节最大整数为65535,四个字节最大整数为4294967295。

5、具体

这里写链接内容

6、 因为计算机由美国人发明,最早只有127个字符编码在计算机中(大小写字母,符号), 称为ASCII编码
但是处理中文一个字节是不够的,而且不能与ASCII编码冲突,所以中国制定了GB2312编码。但世界上语言太多,若各个语言有各个标准,就会有冲突,乱码等等。
因此Unicode应运而生,它把所有语言统一到一套编码中。其中常用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。ASCII编码适用范围小(大小写字母,部分符号),其中ASCII编码中A的编码为01000001,Unicode中为00000000 01000001。以此类推,若写的程序基本是英文的话,使用Unicode编码会比ASCII编码多使用一倍的存储空间。于是,又出现了把Unicode转化为“可变长编码”的UTF-8编码。
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

7、 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。所以你看到很多网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码。

8、对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符。

>>>ord('a')
97
>>>ord('中')
20013
>>>chr(66)
'B'
>>>chr(25991)
'文'

9、encode()方法可以编码为指定的bytes。

>>>'鱼'.encode('utf-8')
b'\xe9\xb1\xbc'
>>>'Python'.encode('ascii')
b'Python'
>>>'Python'.encode('utf-8')
b'Python'

10、反之,要把bytes变为str,就需要用decode()方法。

>>>b'\xe9\xb1\xbc'.decode('utf-8')
'鱼'

11、在操作字符串时,我们经常遇到str和bytes的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对str和bytes进行转换。

12、保留2位小数的方法有:

a = 0.180556
>>>print('%.2f'%a)
0.18
>>>round(a,2)
0.18
>>>from decimal import Decimal
>>>Decimal(a).quantize(Decimal('0.00'))
Decimal('0.18')

13、
列表list[]是一个有序,随时可以添加和删除的数据类型。
方法listname.insert(index, ’ contant’)可以在指定位置插入指定元素;
方法listname.pop()删除列表末尾的元素,且删除的元素还可以继续使用;
方法listname.pop(index)删除指定位置元素,且删除的元素还可以继续使用;
方法append(x)添加x到列表末尾;
方法clear()清除列表元素;
方法count(x)计算元素x在列表中出现多少次;
方法extend()同时将多个元素添加到列表末尾;
方法index(x)获取元素x在列表中第一次出现的索引;
方法remove(x)删除第一个元素x(并且不能在使用,不像pop());
方法reserve()按相反的顺序排列列表元素(永久性);
方法sort()对列表进行排序(永久性);
方法copy()复制列表副本,使得变量指向不同列表。

>>>a = [1,2,3]
>>>b = a    #a,b指向同一个列表
>>>b[1] = 4
>>>a
[1,4,3]
>>>b
[1,4,3]
#方法copy
>>>a = [1,2,3]
>>>b = a.copy()   #b是a的副本,不指向同一个列表
>>>b[1] = 4
>>>b 
[1,4,3]
>>>a
[1,2,3]
#方法sort接收两个可选的关键字参数(key和reverse)
>>>x = ['eon','erik','edward','hank','hance','jemmy']
>>>x.sort(key=len)
>>>x
['eon', 'erik', 'hank', 'hance', 'jemmy', 'edward']
>>>x.sort(key=len,reverse=True)
>>>x
['edward', 'hance', 'jemmy', 'erik', 'hank', 'eon']

替换列表某个元素可以直接赋值,listname[index] = ‘something’。
列表内元素的数据类型可以不同。(字符串,数字,布尔值,列表等等)

>>>a = ['c','java','c++','javascript','python']
>>>a.insert(2,'python')
>>>print(a)
['c', 'java', 'python', 'c++', 'javascript', 'python']
>>>a.pop()
'python'
>>>print(a)
['c', 'java', 'python', 'c++', 'javascript']
>>>a[1] = 'python'
>>>print(a)
['c', 'python', 'python', 'c++', 'javascript']

14、元组tuple()有序,一旦初始化就不能修改。可以正常地使用tuplename[0]获取元素,但是不能赋值。空元组是(,),而不是()。
例子,“可变的元组”:

>>>t = ('a','b',['A','B'])
>>>t[2][0] = 'X'
>>>t[2][1] = 'Y'
>>>print(t)
('a', 'b', ['X', 'Y'])

tuple指向3个元素,表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向’a’,就不能改成指向’b’,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

15、关于字符串格式设置方法:

#第一种, 百分号% 
>>>a = "Hello, %s. %s enough for ya?" #%s称为转换说明符,指出了要将值插入什么地方,s意味着将值视为字符串进行格式设置,%右边指定要设置其格式的值
>>>b = ('world','Hot')
>>>a % b
'Hello, world. Hot enough for ya?'
#第二种,模板字符串
>>>from string import Template
>>>tmpl = Template("Hello, $who! $what enough for ya?")
>>>tmpl.substitute(who='Eon',what='Hot')
'Hello, Eon! Hot enough for ya?'
#第三种,字符串方法format
>>>print("Hello, {}".format('eon'))
Hello, eon
>>>print("{1}, {0}".format('eon','Hello'))
Hello, eon
>>>import math
>>>"{name} is approximately {value:.2f}".format(name='π',value=math.pi)
'π is approximately 3.14'   #使用了格式说明符.2f,取2位小数

16、设置字符串的格式,一般用方法format()。括号内每个值都被插入字符串中,以替换花括号括起的替换字段{}。替换字段由以下组成(都可选):
一、字段名:索引或标识符,指出要设置哪个值的格式并使用结果来替换该字段。
二、转换标志:跟在叹号!后面的单个字符。有r(repr),s(str)和a(ascii)。
三、格式说明符:跟在冒号:后面的表达式。能详细地指定最终的格式,包括格式类型(如字符串,浮点数或十六进制数),字段宽度,数的精度,千位分隔符,对齐方式和填充方式。

#替换字段名
>>>"{x} {} {y} {}".format(1,4,x=3,y=5)
'3 1 5 4'
>>>"{1} {0} {x} {2}".format(1,3,4,x=5)
'3 1 5 4'
#替换提供值的部分元素
>>>"{1} {2} {0} {3}".format(list[-2],list[2],list[0],list[-3])
'3 1 5 4'
>>>"{l[2]} {l[0]} {l[4]} {l[3]}".format(l=list)
'3 1 5 4'
#基本转换
>>>print("{pi!s} {pi!r} {pi!a}".format(pi='π'))
π 'π' '\u03c0'   #s字符串,r原样,a编码

字符串格式设置中的类型说明符


b————将整数表示为二进制数
o————将整数表示为八进制数
d————将整数视为十进制数处理(整数默认使用)
x————将整数表示为十六进制数并使用小写字母
c————将整数解读为Unicode码点
e————使用科学计数法来表示小数,用e来表示指数
E————同e,用E来表示指数
f————将小数表示为定点数
F————同f,但对于特殊值nan(not a number)和inf(infinite)用大写表示
g————自动在定点表示法和科学表示法之间做选择(小数默认使用,默认状态下至少有一位小数)
G————同g,但使用大写来表示指数和特殊值
n————同g,但插入随区域而异的数字分隔符
s————保持字符串格式不变(字符串默认使用)
X————同x,但使用大写字母
%————将数表示为百分比值(乘以100,按说明符f设置格式,再在后面加%)


设置宽度、精度和千位分隔符

#设置浮点数格式时,默认6位小数
>>>"The number is {x:f}".format(x=42)
'The number is 42.000000'
>>>"The number is {x:.2f}".format(x=42)  #注意添加.
'The number is 42.00'
#设置格式宽度
>>>"{num:10}".format(num=10)
'        10'    #10位,前8位用空格填充
>>>"{num:10}".format(num='x')
'x         '    #数和字符串对齐方式不同
#可以同时指定宽度和精度
>>>"{num:10.2f}".format(num=42)
'     42.00'
#千位分隔符
>>>"One googol is {:,}".format(10**100)   #如果同时指定其他格式设置元素时,逗号因放在宽度和精度之间
'One googol is 10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000'
#当同时包含字符串和数或者负数时,因为默认对齐方式不同,可能要修改对齐方式
>>>"{:010.2f}".format(pi)   #10前面的0表示用0来填充空白处
'0000003.14'
>>>print('{0:<10.2f}\n{1:^10.2f}\n{0:>10.2f}\n{0:10.2f}'.format(pi,2.14))
3.14  #冒号前数字为索引,<左对齐,^居中,>右对齐      
   2.14   
      3.14
      3.14   #数字默认右对齐
#可以用指定字符来填充空白位置
>>>"{:$^10.2f}".format(pi)
'$$$3.14$$$'

17、字符串方法
center(x)在两边填充x让字符串居中,ljust()左对齐,rjust()右对齐,zfill()右对齐填充0

>>>"eon".center(10)
'   eon    '
>>>"eon".center(10,'*')
'***eon****'
>>>'eon'.ljust(10)
'eon       '
>>>'eon'.ljust(10,"*")
'eon*******'
>>>'eon'.rjust(10,'*')
'*******eon'
>>>'eon'.zfill(10)    #有且仅有一个形参
'0000000eon'

方法find()在字符串中查找子串,有就返回第一个字符的索引,无就返回-1

>>>'eon is noob'.find('is')
4
>>>'eon is noob'.find('stupid')
-1
#还可以指定搜索的起点终点
>>>'eon is noob'.find('is',5)  #指定起点
-1
>>>'eon is noob'.find('is',1,4)   #指定起点终点,但不包含终点(,]
-1

方法join()作用跟split()相反,用于合并元素(所合并序列的元素必须都是字符串!!!)

>>>x = ['1','2','3','4','5']   #注意,这是一个字符串列表,数值列表会引发TypeError
>>>y = '+'
>>>y.join(x)   #注意格式!!!!  x.join(y)是将x加入到y中
'1+2+3+4+5'
>>>x = '','usr','bin','env'
>>>'/'.join(x)
'/usr/bin/env'

方法replace()

>>>"This is a test".replace('is','ez')
'Thez ez a test'

方法strip()删除前后空白,还可以指定删除哪些字符

>>>"$$$$eon $is $noob$$$".strip('$')
'eon $is $noob'  #只删除头尾
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
<think>嗯,用户让我介绍《编译原理(第三版)》清华大学出版社第二章笔记。首先,我需要确认这本书的作者是谁,可能是不是陈火旺或者其他人?不过可能用户没有提到具体作者,但第三版应该是比较经典的版本。第二章通常是词法分析部分,但不同教材的结构可能有所不同,所以得先回忆一下常见的编译原理教材结构。比如,龙书(紫皮书)的第一章是引言,第二章可能开始词法分析,而其他教材可能结构不同。但清华大学出版社的版本,可能需要查证一下。不过用户可能指的是张素琴等编写的《编译原理》第三版,清华大学出版社,常见的章节安排。 假设第二章是关于词法分析的话,通常会包括词法分析的作用、正则表达式、有限自动机(DFA、NFA)、从正则表达式到NFA的转换,NFA到DFA的转换,DFA的最小化,以及词法分析器的生成工具如Lex。但需要更准确地确认内容。 不过用户可能希望得到一个结构清晰的笔记,所以需要分点列出。根据系统指令,要使用中文,注意数学公式的格式,行内用$...$,独立公式用$$...$$。同时要确保内容正确,比如正则表达式的定义、自动机的转换步骤是否正确。 另外,用户可能需要的是重点知识总结,而不是详细的内容。因此需要提炼关键概念,比如词法分析的任务、单词的分类、正则表达式、有限自动机、算法(子集构造法、最小化算法)、Lex工具等。 可能需要注意常见的错误点,比如确定有限自动机和非确定有限自动机的区别,NFA到DFA的转换过程,以及最小化的步骤。另外,正则表达式与自动机的关系也是重点。 需要检查是否有遗漏的部分,比如词法分析中的错误处理,或者某些具体例子,比如如何用正则表达式描述标识符、数字等。此外,可能还要提到词法分析器的输出形式,比如词法单元序列,属性值等。 最后,组织内容时按照逻辑顺序,先介绍任务和作用,然后正则表达式,接着自动机,转换算法,最后工具。确保每个部分简明扼要,重点突出,符合用户的笔记需求。</think>以下为《编译原理(第三版)》(清华大学出版社)第二章内容的系统性笔记整理,按核心知识点分层归纳: --- ### 第二章:词法分析 #### 1. 词法分析的任务与作用 - **输入**:源代码字符串(字符流) - **输出****: 词法单元序列(Token序列),格式为:$(\text{种别码}, \text{属性值})$ - **核心功能**: - 过滤注释与空白符 - 识别单词并分类(如标识符、常量、运算符等) - 错误检测(如非法字符) --- #### 2. 单词的分类与描述 - **单词类别**: - **关键字**:具有固定含义的单词(如 `if`, `while`) - **标识符**:用户定义的名称,需满足正则规则:$[a-zA-Z][a-zA-Z0-9]*$ - **常量**:整型、浮点型、字符串等(如 `123`, `"hello"`) - **运算符**:`+`, `-`, `*`, `/` 等 - **界符**:`;`, `(`, `)` 等 --- #### 3. 正则表达式(RE) - **定义**:描述单词构成规则的符号系统 - **基本运算**: - 并:$A|B$(A或B) - 连接:$AB$(A后接B) - 闭包:$A^*$(A重复0次或多次) - **扩展语法**: - `[0-9]` 等价于 $0|1|…|9$ - `A+` 等价于 $AA^*$ - `A?` 等价于 $A|\varepsilon$ --- #### 4. 有限自动机(Finite Automata) - **非确定有限自动机(NFA)**: - 定义:五元组 $(Q, \Sigma, \delta, q_0, F)$ - 特点:允许$\varepsilon$-转移,同一状态对同一字符有多个转移 - **确定有限自动机(DFA)**: - 定义:五元组 $(Q, \Sigma, \delta, q_0, F)$ - 特点:无$\varepsilon$-转移,每个状态对每个字符有唯一转移 --- #### 5. 正则表达式到自动机的转换 - **Thompson算法**: 1. 将正则表达式分解为基本单元(字符、空串) 2. 递归构建NFA(通过连接、并、闭包操作组合子NFA) **示例**:正则表达式 `a(b|c)*` 的NFA构造 (此处可插入NFA状态图描述) --- #### 6. NFA到DFA的转换(子集构造法) - **步骤**: 1. 计算NFA初始状态的$\varepsilon$-闭包 2. 对每个未处理的状态集合$T$,计算所有字符输入后的转移闭包 3. 生成DFA状态,直到无新状态产生 **公式表示**: $$ \delta_{\text{DFA}}(T, a) = \varepsilon\text{-closure}\left( \bigcup_{q \in T} \delta_{\text{NFA}}(q, a) \right) $$ --- #### 7. DFA最小化(划分法) - **目标**:合并等价状态,减少DFA状态数 - **步骤**: 1. 将状态分为接受态和非接受态 2. 递归细分集合,直到同一集合内状态对所有输入字符的转移目标属于同一集合 --- #### 8. 词法分析器生成工具(Lex/Flex) - **工作原理**: - 输入:正则规则与动作代码 - 输出:可识别Token的C程序 - **文件结构**: ```lex %{ // 声明部分(头文件、变量) %} // 正则定义段 digit [0-9] %% // 规则段 {digit}+ { printf("整数: %s", yytext); } %% // 用户代码段 ``` --- #### 9. 关键问题总结 - **冲突解决**:最长匹配原则 & 优先级规则 - **错误处理**:跳过非法字符并报错 - **性能优化**:预计算转移表加速DFA执行 --- 如需更详细的公式推导或实例分析,可指定具体知识点进一步展开。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值