Harvard CS50 学习笔记(四)
                    目录
                    
                
                
            
            摘要
        
        Harvard CS50 学习笔记(四)。
        4 Memory
4.1 Lecture
4.1.1 Storing finite information
4.1.2 Pixel art
4.1.3 RGB
4.1.4 Hexadecimal
- 16进制一般前面有- 0x,用于与- 10进制区分。- 0x11=17
4.1.5 Memory addresses
4.1.6 address.c
4.1.7 Pointers
- 指针,是用于记录值的内存地址变量。
4.1.8 Declaring pointers
- 
单个 &,是address operator(地址运算符)。
- 
&i表示取变量i的地址。
- 
*表示要记录指针(声明指针变量)。1 2 3 4int n = 50; // 定义一个指向int型的指针变量p,并用n的地址来初始化p int *p = &n; printf("%p\n", p);
            参考
        
        
    4.1.9 “Address of”
4.1.10 Dereference operator
- deference operator(引用解析运算符)—— *。
- reference——(变量的引用)。
- dereference——其实就是de(反)- reference(引用),即**(指针的)变量**。
- 一个 *,表示我们要获取reference(引用),即地址值。
- 再加一个 *,表示我们要反引用,也译为解引用,就是获取那个引用(地址)所储存的值(获取到之后其实可以改变地址所存储的值)。
4.1.11 Visualizing pointers
- 现在指针一般都是8字节(64比特)。
4.1.12 Assignment operators
- C中,不会自动做什么事情。
- 如果有一个变量 n =50,其指针为p =0x123。
- 此时创建一个新变量 c = n,p不会有任何变化。
4.1.13 Strings in memory
 
    - 字符串变量,实质为指向第一个字符地址的指针。
4.1.14 char *
- string s = "HI!";等同于- char *s = "HI!";
4.1.15 Different Variables with Different Pointers
 
    
         
    
- 为什么打印的结果不同?
4.1.16 address.c
- 结果不同的原因解析:
- 右边比较好理解,字符串变量的地址,与字符串第一个字符的地址相同。
- 左边的关键在于,第 7行,把字符串的第一个字符H,赋值给了一个新的变量c,此操作在内存里进行了复制,也就是内存中多了一个新的变量c,在不同的位置,储存着与字符串第一个字符相同的字符H。
- 再打印变量 c的地址,自然与字符串变量s的地址不同。
 
4.1.17 Pointers to array values
 
    
         
    
- 左图比较好理解。
- 为什么右图的第 22行打印出了不一样的地址?因为那是指针的地址。
- 基本类型如果要获取地址值,需要在变量名前加 &。
- 数组与字符串(底层就是数组)不需要。
4.1.18 Defining strings
- <cs50.h>中的- string类型实质为- typedef char *string;
4.1.19 Pointer arithmetic
 
    - 注意,这里的 +1操作,加了4个字节,因为一个int占4字节,而不是加1个字节或1个比特,编译器帮我们处理了。
4.1.20 Arrays as pointers
- 还是上图,此处并没有用 &符号来表示数组的地址,但打印的时候,却使用了*符号来解析地址。
- 因为可以把数组的变量名,直接作为指针使用。
- 即可以把数组,当作指向其第一个元素的指针。
4.1.21 Comparing integers
4.1.22 Comparing strings
4.1.23 Copying values
 
    4.1.24 malloc and free
- malloc()申请内存。
- free()释放内存。
- 需要 #include <stdlib.h>
- 实际上,这个 malloc()就相当于Java里面的new一样,只是Java把各种细节给你封装抽象成一个new,GC会自动给你回收,不需要自己去free()。
4.1.25 Copying with malloc and free
4.1.26 Valgrind
- 检查与内存相关的潜在BUG。
4.1.27 Garbage values
- 不初始化,就会有无法预测的垃圾值。
4.1.28 Binky Pointer Fun
- 试图deference(引用解析)垃圾值,会造成错误。
4.1.29 Swap
4.1.30 swap.c
 
    - 没有传递引用,复制了值,原本的值不变。
4.1.31 Stack and heap
4.1.32 Visualizing swap.c
4.1.33 Pointers in swap.c
 
    4.1.34 scanf
4.1.35 Segmentation fault
4.1.36 Header bytes
4.1.37 Filter
4.2 Shorts
4.2.1 Hexadecimal
 
     
     
     
     
     
     
    4.2.2 Pointers
 
     
     
     
     
     
    - 指针就是地址值。
 
     
     
    - 指针的类型就是其指向地址值数据的类型。
 
    - 指针必须初始化,如果初始化的事情没有明确的值,就指向空(NULL)。
 
     
     
     
     
     
     
     
     
    4.2.3 Defining Custom Types
 
     
     
     
     
     
    4.2.4 Dynamic Memory Allocation
 
    - 一般有名字的变量在栈,没名字的在堆。
 
    - 堆与栈实质为一块内存空间的不同部分。
 
     
     
     
     
     
    - 使用 malloc()必须释放内存。
- 只有 malloc()使用的内存需要被释放(静态声明在堆的变量不需要释放)。
- 不要重复释放。
 
     
     
    4.2.5 Call Stacks
 
     
    4.2.6 File Pointers
 
    - C操作文件有抽象的数据类型,叫- FILE。
- 一般情况下,只要操作文件,都用文件的指针,即 FILE*。
 
    - 文件相关的函数,都在 stdio.h里。
 
    - 打开一个文件,即获取这个文件的指针。
- 确保 NULL的检查。
- 操作可以为 r-read,w-write,a-append。
 
     
     
     
    - 关闭文件指针。
 
    - 读字符函数。
- 获取文件的下一个字符。
- 打开文件的方式必须为 r-read。
 
     
     
    - 可通过循环读取整个文件。
- EOF表示 End Of File。
 
    - 写字符函数。
- 将字符写入文件。
- 打开文件的方式必须为 w-wirte或a-append。
 
     
     
     
    - 可通过循环读与写,实现文件复制。
 
    - 读文件函数,参数从右往左看。
- <file pointer>为文件指针,必须是读指针。
- <qty>读文件的数据块的数量。
- <size>读文件的数据块的大小(单位为字节)。
- <buffer>内存中的缓存区域,用于存放读到的数据,需要用指针表示(数组名本身为指针)。
 
     
     
     
     
    - 写文件函数,参数从右往左看。
- <file pointer>为文件指针,必须是写指针。
- <qty>读文件的数据块的数量。
- <size>读文件的数据块的大小(单位为字节)。
- <buffer>内存中的缓存区域,用于存放要写的数据,需要用指针表示(数组名本身为指针)。
 
     
     
     
     
    4.3 Lab 4
|  |  | 
4.4 Problem Set 4
4.4.1 FIlter
|  |  | 
4.4.2 Recover
|  |  | 
