前言(计算机知识)
计算机能完成的工作
1.算术运算 2.逻辑判断 3.数据存储 4.网络通信......更多更复杂的任务
下面这些都可以称为计算机:
台式机, 笔记本, 手机, 服务器(使用电脑访问B站,本地的计算机给B站的服务器发送一个网络请求,B站服务器收到这个请求后就会找到对应的视频数据,通过网络再发送回用户本地计算机) , 路由器, 智能家电等等
一台计算机应该由以下组件构成:
1.CPU中央处理器(大脑),算术运算,逻辑判断
ps: cpu内部结构非常复杂,可以称得上 人类当前科技的巅峰之作,能和cpu相提并论的 : 氢弹
2.存储器(内存,外存)存储数据
ps:内存和外存(硬盘)区别:
①内存的存储空间较小,外存的存储空间较大
②内存的访问速度快,外存的访问速度慢
③内存比外存成本更高
④内存上的数据容易丢失(断电数据就没了),外存上的数据能够持久化存储(断电数据也在)---只是相对于内存来说,存的更长久,一般机械硬盘存储数据的时间是 几年到十几年
3.输入设备(键盘,鼠标,麦克风)
4.输出设备(显示器,音箱,耳机,打印机)
---输入输出设备都是负责和用户进行交互的~~~
---有的设备既是输入设备,又是输出设备(触摸屏,网卡)
ps:显卡的定位和CPU是类似的
CPU"通用计算芯片" , 显卡(GPU)"专用计算芯片"(例如密集的浮点数运算(运算量大但是运算简单),复杂游戏画面,机器学习中复杂建模)
一.基础知识(1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在Python中,2/3得到的是0.66666而不是0
而在C/Java中,整数/整数 得到的是整数,小数部分会被直接舍弃
为什么不是四舍五入呢?事实上,在编程中,一般没有四舍五入这样的规则
浮点数是有标准的,为IEEE754标准,在这套规则下,在内存中表示浮点数的时候会存在微小误差
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
引言 : 和计算器上的M键功能相似,主要用来保存中间结果,而且python中可以创建任意多个变量来保存中间结果;
变量可以视为一块用来存储数据的空间(位于内存)(想象成一个盒子);
1.定义: a = 10
2.命名的规则
①硬性规则:不遵守就会报错
1. 必须由数字,字母,下划线组成,不能包含特殊符号 eg: a*a = 20 就是非法的
2.数字不能开头 eg: a1合法 而 1a 非法
3.变量名不能和Python的关键字重复 eg: if = 5 非法
4.大小写敏感:区分大小写 eg: num = 5 和 Num = 5 就定义了两个不同的变量
②软性规则:建议遵守
1.给变量命名时,尽量使用描述性的单词表示,尽量通过名字表现出变量的作用
eg: count 计数器
2. 当一个单词描述不清楚,可以使用多个单词命名,这时候就产生了两种命名方式
1) 驼峰命名法 : 第一个单词首字母小写,其他单词首字母大写
eg: personInfo totalCount
2) 蛇形命名法 : 单词之间采用下划线_分隔
eg: person_info total_count
3.使用变量:
①读取变量
a = 10
print(a)
首次使用 = 对a进行赋值,这个过程是创建变量(初始化)
②修改变量
a = 10
a = 20
print(a)
后续对a 再次使用 = 操作,则是相当于修改 a 的内容(赋值)
4.变量的类型
变量是有种类的,不同种类变量存储的数据是不一样的,支持的操作也是不一样的
变量的类型: 通过type(变量名)查看变量类型
Python中变量类型不需要在定义变量的时候显示声明,而只是依靠初始化语句,根据初始化的值的类型来确定的
1.整数 int
在Python中,int能表示的数据范围是无穷的,Python中的int可以根据要表示的数据的大小,自动扩容,因此python中就没有 long这样的类型,像byte,short这些类型在Python中也不存在
而Java int 最大只能表示到 -21亿 -> +21 亿
2. 浮点数(小数) float
像C++/Java 里面,float 是四个字节,也叫作"单精度浮点数",因此还存在double这样的双精度浮点数
而Python中,float就是双精度浮点数,等同于C++/Java里面的double
Python中的一个设计哲学:解决一个问题,只提供一种方案
3.字符串
把一个个字符放到一起就是字符串
什么是字符?英文字母,阿拉伯数字,标点符号,汉字字符都可以认为是“字符”
Python中要求用引号把一系列字符引起来就构成字符串,引号可以是单引号,也可以是双引号
字符串这个单词 是 string Python中采用缩写str来表示字符串类型
问题来了,单引号和双引号都可以引一串字符,为什么还要设置这两种引号呢?
就是当遇到下述情况时: 即当字符串里面包含字符串的时候
如何解决呢?
外面用单引号,里面用双引号即可
如果同时有单引号和双引号怎么办?
Python中还有一种字符串使用三引号表示~
字符串支持操作
①len : 求字符串长度,字符串包含了几个字符
②+ : 字符串拼接,将后一个字符串拼接到前一个字符串的前面,生成了一个更大的新的字符串,对原来来的a1,a2没有影响
注意区分整数+整数 与 字符串+字符串 ,前者进行的是算术运算,后者进行的是字符串拼接
注意:字符串和数字不能混合相加
拓展:在Python中报错有两种情况:
1.语法错误:在程序运行之前,Python解释器就能把错误识别出来
2.运行错误:在程序运行之前,Python解释器识别不了,必须执行到对应的代码,才能发现问题
4.布尔类型:非常特殊:取值只有两种,True(真)和False(假),----注意Python中True 和 False 首字母都要大写,因此布尔类型主要用于逻辑判定
类型带来的意义:
1.不同的类型占用的空间是不同的(占几个字节)
int 默认四个字节,不够时动态扩容
float 固定8个字节
bool 一个字节就足够了
str 变长的
2.不同类型对应的操作也是不一样的
int/float: + - * / 不能使用len
str 可以+ ,但不能- * / 可以使用len
Python的动态类型机制
动态类型指的是 在程序运行的过程中变量类型可能会发生改变
a = 10
print(type(a))
a = "hello"
print(type(a))
a = True
print(type(a))
会发现 a的类型随着程序的运行而发生改变
静态类型:程序运行过程中,变量的类型始终保持不变 C++/Java都是静态类型
eg int a = 10; a这个变量在程序运行的过程中始终是int ,若尝试 a = "hello'' , 编译阶段就会报错
注意:一个编程语言是否是动态数据类型只取决于运行时类型是否发生改变,不取决于变量定义的时候是否声明类型
事实上,Python作为一个动态类型语言,变量在定义的时候也可以声明类型
如上述代码所示,在给变量赋值的时候 加一个冒号,后面写上其类型即可,这样便声明了变量类型
动态类型这种写法是很灵活的,提高了语言的表达能力,但是在编程中"灵活"这个词往往是"贬义"的,意味着更容易出错,相比之下,静态类型语言还是更好一些的(尤其是在大型的程序中,多人协作开发)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
对代码进行解释说明,提高代码的可读性
注释语法:
1.行注释: #
#开头的注释一般是写在要注释代码的上方,也有少数情况是写在代码的右边,很少写在代码的下方
2.文档字符串: 三引号 ''' 或者 """,与行注释不同的是文档字符串可以被Python解释器识别
注释的规范
1.注释内容要准确,起到误导作用的注释还不如不写(经常出现在 项目要进行"迭代"(也就是更新),忘记注释与代码同步更新了)
2.篇幅合理,既不要太精简,也不要长篇大论
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
程序需要和用户进行交互
······用户把信息传递给程序的过程叫"输入"
······程序把结果展示给用户的过程叫"输出"
输出输出最基本的方式是控制台.
拓展:
什么是控制台?
对于机械的操作面板,就叫控制台,控制台上会有一些按钮,开关,操作杆...后来有了计算机之后,控制台的概念就延续下来了,只不过计算机是通过键盘鼠标等进行操作,把操作结果显示到屏幕上
计算机里,就把用户输入命令,向计算机安排工作,计算机再把结果显示出来,这样的程序就称为控制台
控制台是一种人和计算机交互最基本的方式,但是日常生活中却不常用(因为要通过命令来操作,用户得熟悉各种各样的命令,更常见的交互方式是图形化界面,但图形化界面的程序编写起来并不容易)
①基于控制台的输出 print() 把变量内容输出到控制台上
若有 a = 10,想要输出 a = 10 ,如何打印呢?
明显的,此处是想要把字符串和数字混在一起打印
这个语法,叫格式化字符串 : f-string 此处的 f 表示format,此时我们就可以通过{}的语法往字符串里面嵌入变量或者表达式
下面是嵌入表达式的代码示例
②通过控制台输入
num = input("请输入一个整数: ")
print(f"您输入的数字是{num}")
关于input的两点:
1.input执行的时候就会等待用户进行输入,这个等待的时长完全取决于用户什么时候输入,如果用户始终不输入,程序就会死等,不见不散~
2.input返回值是一个字符串类型
如果只是单纯拿到用户的输入然后打印,那么按照字符串打印即可~
但是需要根据用户输入的内容进行算术计算,此时需要就需要先把读到的str->int 此时可以用int()进行数据类型转换
原意是想要把输入的两个数字相加,但由于input的返回值是字符串,所以两个数字被拼接到了一起
1.算数运算:
算数运算符: + - * / ** //
规则 : 先算乘方,其次算乘除,最后算加减,若想改变顺序,加()即可
------除法注意事项:
1.不能除0
这种运行时出现的错误,也叫做"抛出异常",引起不同异常的原因不一样,此处是"除零异常"
如果程序运过程中抛出异常,那么程序会在该代码处终止,后面的代码就不会执行
可以看到,当抛出异常后,后面的打印hello的语句压根没有执行
值得注意的是,如果除以小数0,结果是什么呢?
可以看到,依然会抛出除零异常,所以Python中,无论是/整数0还是/小数0,都认为是除0异常
但是有些编程语言中,/整数0也是会抛出异常,而/小数零则会得到无穷大~
2.截断的问题
Python中,整数/整数,如果不能整除,得到的就是小数,不会出现截断的情况
而在C++/Java,直接会舍弃小数部分,得到整数
除Python之外,大多数编程语言都是 整数/整数 结果还是整数
% --- 求余数,要注意的是余数一定小于余数
** --- 乘方运算,既能够支持整除次方,也能够支持小数次方(开方运算)
//--- 地板除法(取整除法),会针对计算的结果进行"向下取整"
值得注意的是,负数"向下取整"很容易出错,例如 7//2 得到的是3,而-7//2 得到的是-4,"向下取整"意味着得到更小的数字
2.关系运算:比较两个操作数之间的大小/关系
> < >= <= != ==
最需要注意的便是 == 与 = 的区别 ,前者是判断相等,后者是赋值
关系运算符对应的表达式,值是布尔类型,表达式符合要求,为真,不符合要求,为假
eg:
值得注意的是: == 除了可以比较数字,还可以用来比较字符串
而这点在Python中与在C/Java中是截然不同的
·······C: strcmp 如果直接使用 == ,比较的是两个字符首元素地址
·······Java: equals 方法,如果直接使用 ==, 本质上在比较两个字符串是否是同一个对象
总结: == 比较字符串是大多数编程语言所遵守的行为,而C/Java字符串比较方法就是小众行为了
那么字符串比较比的是什么呢?是长度吗?显然不是
字符串比较的就三个字: "字典序" 也就是按照英文词典上单词的先后顺序,先看首字母的顺序,小的排前面,若首字母相等,就继续往后比后面的字母(与C语言是类似的)
可以看出,程序仍然有运行结果,但是针对中文进行字符串比较是没有任何意义的,至少按照默认的字典序来说,是没有任何意义的
在计算机里,表示中文其实是用多个字节构成的一个较大的数字来进行比较的
划重点:
针对浮点数来说,使用 == 比较相等,存在一定的风险
因为浮点数在内存中的存储和表示,是可能存在误差的!! 这样的误差在进行算术运算的时候可能被放大,从而导致 == 的判断出现误判
问题在哪呢???
正如现在你看到的,在计算0.1+0.2时出现了问题,这就是上面说的,浮点数在内存中的存储存在误差,进行算术运算时误差会被放大
那怎么比较浮点数相等呢?
我们可以限定一个误差范围
这样便得到了正确的结果
ps: -0.000001< a - b < 0.000001 这样连续小于的写法,Python是支持的
3.逻辑运算
三个逻辑运算符 :
······and(并且): 两个操作数均为True,表达式的值为True,否则为假(一假则假)
······or(或者):两个操作数均为False,表达式的值为False,否则为真(一真则真)
······not(逻辑取反):只有一个操作数,操作数为True,则返回False,为False,则返回True(唱反调)
第一行输出代码下面有波浪线,鼠标放上去之后会有"简化链式比较"的提示,其实我们可以直接写成
a < b < c,这也是上文提到过的
对比C++/Java里面的逻辑运算符 :
&& 逻辑与 并且
|| 逻辑或 或者
! 逻辑非 逻辑取反
可以看出,在这点上Python中的逻辑运算符更加直观易懂
逻辑运算符中的重要细节:短路求值(大多数编程语言都有该行为)~~~
对于 and 操作,如果左侧表达式为False,那么整体的值一定是False,右侧表达式不必求值
对于 or 操作,如果左侧表达式为 True ,那么整体的值一定是True, 右侧表达式不必求值
我们可以写一段代码来简单说明一下
可以看到,程序没有抛出"除零异常",因此当 a >b 为假时,右边操作压根没有执行
对于or 也是同理的,就不再赘述
4.赋值运算
= 表示赋值,意思就是把右侧的值填充到左侧的空间(必须是变量)中,例如 10 = 20 就会报错
链式赋值:
a = b = 20 这句代码的意思就是 ①b = 20 ②a = b
但是不建议使用链式赋值,尽量一行包含一个操作
多元赋值:
a , b= 10 , 20
也不是很推荐,但是能解决一些特殊问题
eg:交换两个变量(通常是借助第三变量)
复合赋值运算:
+= -= *= /= %= 等等
a = a + 1 <=> a += 1
ps: C/Java中有++/-- 这样自增自减的操作,那么Python中是什么样呢?
结论:在Python中不支持++/--这样的自增自减的操作的!!!(这也是上文提到的Python的设计哲学,一种问题尽量只提供一种解决方案,a+= 1 已经能很方便的完成自增了,而且前置++,后置++对初学者是很不友好的)(前置++,后置++是C语言开的头,Go语言作者也是C语言之父,肯汤姆逊,在Go语言中废除了前置++,只保留了后置++,而且这个后置++ 不能取表达式的返回值)
++a 之所以没有语法报错,是Python解释器把+当成了正号
- - 操作也是一样的道理
其他运算符:身份运算符(is,is not),成员运算符(in,not in),位运算符(& | ~ ^ << >>)等等
补充:
①Python中的整数可以和布尔值进行算术运算,此时会把True当成1,把False当成0,但是这样的操作没有意义
而Java在这里的做法是更加合理的,如果出现整数和布尔混合运算,直接编译报错
②Python里面只有字符串类型,没有字符类型, 'a'是长度为1的字符串
正是因为Python中没有字符类型,所以 ' 和 " 都可以表示字符串,而C++/Java有单独的字符类型,单引号表示字符,双引号表示字符串
③在Python中,一个语句写完之后可以加上分号,也可以不加,通常情况下都是不加的,如果加了,也不算错.但是如果把多个语句写到了一行,则必须要加分号