CS50笔记 第五集——哈佛大学CS50《计算机导论》课程(2019) 学习平台哔哩哔哩目录CS50笔记 第五集一、温故知新一第一集 引言1.什么是计算机科学?2.如何表示input和output?3.如何从input到output?4.如何开始运行?5.一些概念二第二集 C语言1.如何使用C语言平替scratch语言的格式2.C语言如何运行程序3.一些概念4.实践小妙招三第三集 代码原理与优化1.汇编底层原理是什么2.如何调试代码错误3.如何优化代码四第四集 算法1.算法的种类有哪些2.如何描述算法3.如何用编程实现算法二、内存与指针一内存地址怎么表示1.16进制2.指针1定义2指针的使用及原理二内存地址指针的运用1.string 的底层原理与指针关联1原理2运用1_比较3运用2_复制4运用3_交换5运用4_替换get_string2.文件的读写文件指针3.检查文件名是否通过三、CS50听课感想一、温故知新一第一集 引言1.什么是计算机科学?计算机科学是指解决问题的过程input→〖一系列计算〗→output2.如何表示input和output?用二进制0/1表示input和output二进制可以表示数字、文字、图片、视频、音乐3.如何从input到output?用算法实现从input到output算法有优劣4.如何开始运行?通过伪代码翻译算法后运行5.一些概念函数、条件、布尔表达式、循环、变量、线程、事件、编程语言C、Python、Scratch二第二集 C语言1.如何使用C语言平替scratch语言的格式printfprint表示打印f表示格式即打印格式化文本stdio.hprintf等功能的保存位置引号、分号要注意C语言可以获取输入内容、设置变量、使用if······else······条件、使用while循环、for循环2.C语言如何运行程序1思路input→〖一系列计算〗→output源代码→〖编译〗→机器代码2工具源代码编辑器VScode、CS50 IDE等编译器MingW64编译指令Clang、ls、rm、mkdir、rmdir3.一些概念数值类型bool、char、double、float、int、long、stringCS50提供的函数get_char、get_double、get_float、get_int、get_long、get_string占位符%c、%f、%i、%li、%s数字溢出4.实践小妙招①如果是在文件夹里面编译时需要带上文件夹的名字用/分隔②利用 .数字f 可以保留小数保留几位数字填几③ %是取余运算符cd 可以转移到想要去的目录//后面是注释④cd 后面不加任何东西会返回最开始的目录pwd 可以显示处于哪个目录下⑤在终端按向上的箭头可以复制之前输入的代码指令字符引用采用单引号||表示或⑥for后面使用分号隔开两个for循环的使用构成二维⑦最开始的声明就是复制标题告诉C你见过这个函数了可以编译了三第三集 代码原理与优化1.汇编底层原理是什么预处理、编译、组装、链接2.如何调试代码错误help50、 printf 、断点调试debug50、check50、style503.如何优化代码用数组、字符串、命令行参数优化PSmain函数的输入与返回值文件名称存储于argv[0]中第一个输入存储在为argv[1]四第四集 算法1.算法的种类有哪些线性搜索、二进制搜索2.如何描述算法1O最差解O冒泡排序选择排序O合并排序On线性搜索linear searchO二进制搜索binary searchO12Ω最优解Ω选择排序Ω合并排序Ωn冒泡排序当无交换就停止时ΩΩ1线性搜索linear search、二进制搜索binary search3θ最优解与最差解相同的算法选择排序合并排序n13.如何用编程实现算法1线性搜索可能失败因为字符串不是数据类型而是一个数组既然是数组就可能有多个char,在C语言中需要比较每一个字符相同字符串才会相同python语言倒是可以直接比较可以用string.h文件中的strcmp去比较字符串两个字符串相同时返回0可以自己定义数据类型关键词typedef定义一个类型、struct可以放置多种数据类型的容器2二进制搜索二进制搜索需要先排序①冒泡排序遍历次数(n-1)*(n-1)时间最差O最好Ω如果规定没有交换就停止那么最好的是Ωn②选择排序遍历次数nn1/2n²/2n/2时间最差O最好Ω3递归与合并排序①递归②合并排序分成2半的时间需要(如上面的3行每次合并需要读取所有元素即所需时间为n如上面的8列时间最差O最好Ω二、内存与指针一内存地址怎么表示1.16进制①8位二进制最多可以表示256位0-255FF可以达到同样的效果②0x表示十六进制用来区分十六进制和其他进制2.指针1定义①通过%p格式与符号可以读取使用十六进制表示的内存地址PS实际上向计算机问值的地址得到的是指向该值的指针指针计算机内存中的地址地址是什么*前往地址②使用*和读取存于此处的数据2指针的使用及原理①使用指针读取地址及已知地址的值PS想要存储一些值的地址到一个变量中不仅要指定值的类型还需要使用星号去限制指针用数据类型*来表示int *表示指向int的指针或者说是int 的地址int *pn;解读p是一个变量等于包含一个整数的地址②使用指针读取已知地址的值底层实现大多数电脑手机上面使用64位8字节存储指针③实际不需要知道具体地址p是什么只要能够访问到值n就行二内存地址指针的运用1.string 的底层原理与指针关联1原理①代码存储字符串EMMA②EMMA实际存储也就是说s实际就是一个存储0x123这个地址的变量③无需知道具体的地址名称④没有string sEMMA;只有char *sEMMA;这表示存储emma首字母e的地址⑤定义类型的规范结构⑤自己定义字符串这个类型typedef给我一个新的数据类型名称仅供我自己使用char *值的类型是字符的地址string我自己定义的类型名字是string这是字符串的由来是通过定义来的⑥char *替代string的代码实现PS疑惑int *p n;char *s EMMA;为什么前面要符号后面不要解答n是名字也就是说n本身就是地址的名字所以需要通过符号获得名为n的地址位置然后将其保存到*p中“EMMA”本身就代表字符串首字符的内存地址自带地址所以不用加7.获取字符串中的其他字母2运用1_比较①利用CS50比较比较两个数字②同样的方法比较两个字符串会失败因为两个字符串存储的位置是不一样的③无法比较两个字符串的底层解析④实际上无人在乎具体的地址⑤使用char *指针查看两个字符串的地址3运用2_复制①复制后原有字符串也被改变②复制后原有字符串也被改变的底层原理③使用malloc分配空间进行字符的复制④使用strcpy复制字符串;使用valgrind调试错误使用free释放内存结果不受影响⑤利用sizeof为10个整数分配足够的内存第8行缓冲区溢出而缓冲区其实就是数组4运用3_交换①交换2个数②将输入传给函数时实际传递的是值的副本副本被称为a,b;所以swap函数交换了a,b;没有交换x,y③计算机内存存储原理PS1.Clang编译的0/1机器代码输入./或双击图标时已编译的代码0/1会被加载到计算机内存中放在最顶端2.存储变量或其他类型的数据3.堆可以分配内存是malloc从中获取字节的地方函数的局部变量在堆的最低端称为堆栈堆栈是局部变量到达的地方④noswap程序的工作原理11.call mian根据C程序在编译时的工作方式会得到一片内存称为框架堆栈框架存储argc、argv存储x,ymain函数中的局部变量等等所有变量都存在main中2.main函数调用swap函数swap的内存框架在main之上变量a,b,tempswap函数的局部变量存储在其中⑤noswap程序的工作原理2交换完成后swap框架先消失剩下的main框架仍然显示为未交换⑥无法完成交换解决方案指向地址而非直接赋值⑦交换的代码实现1.分配内存自上而下堆栈调用函数自下而上越来越多就会发生冲突使内存块超负荷运行2.实际上递归如果没有停止条件永远调用自身就会堆栈溢出缓冲区溢出heap overflow堆溢出malloc分配空间太多stack overflow堆栈溢出调用函数太多5运用4_替换get_string①使用地址和指针利用scanf()函数取代get_int进行输入选择传递地址而不是变量给scanf的原因与swap函数是一样的如果只传递值那么只会得到一个副本②错误示例使用地址和指针利用scanf()函数取代get_int进行输入错误原因NULL表示没有指针也就是说实际上没有给要输入的值分配任何内存③正确示例给自己分配一个数组并传递到第8行数组、指针、字符串之间的关联之前已知1没有字符串只有指针地址指向第一个字符的地址string char *之前已知2字符串其实是字符数组是一个数组因为他们都是相连的内存块即字符串string字符数组根据传递性char * 字符数组也就是说在某种情况下指针数组所以在第8行clang编译时会向对待指针一样对待这个数组的名称也就是说第8行传递的数组x的名字实质是传递了x的地址所以不需要加来获取地址2.文件的读写文件指针①写入文件②程序新建的文件及写入的内容.csv格式属于用逗号分隔值的简单电子表格格式③.csv格式在excel中打开的样式④不用CS50库实现读写文件3.检查文件名是否通过①检查文件名是否通过unsigned是C语言中的一种数据类型修饰符主要用于声明无符号整数变量。与有符号整数signed不同无符号整数的值始终为非负数即大于等于零。这意味着无符号整数的最大值比相同大小的有符号整数大一倍。例如unsigned int的取值范围是从0到4294967295而int的取值范围是从-2147483648到2147483647fread函数函数原型size_t fread(void *ptr, size_t size, size_t count, FILE *stream);参数说明ptr指向存储读取数据的缓冲区的指针。size每个数据项的大小以字节为单位。count要读取的数据项的数量。stream文件流指针指向打开的文件。三、CS50听课感想1.这节课最难的可能就是字符串、数组、指针关系的那一块了很容易就搞混了不过不要紧后续使用VScode都会有错误提示2.最后的Unsigned和fread还是有点云里雾里这里就先备注疑惑吧可能后面学多了自然就理解了3.累计疑惑①Unsigned和fread()函数用法