UCAS CTF

2024.09.19课堂笔记

数制

数制是指表示数值的规则和系统。常见的数制有十进制、二进制和十六进制等

二进制

二进制是基数为2的数制,数码只使用0和1。位权依次为2^0,2^1,2^2, 等等

示例:二进制数1011

所以,1011的十进制值为:1×2^3 + 0×2^2 + 1×2^1 + 1×2^0 = 11

十六进制

十六进制是基数为16的数制,数码包括0-9和A-F

(A代表10,B代表11,依此类推到F代表15)

为方便,十六进制的前缀为0x或0X(大小写不限),即0xC1F表示一个十六进制数,二进制数则不需要前缀,直接写1011即可

示例:十六进制数2A3

所以,2A3的十进制值为:2×16^2 + A×16^1 + 3×16^0 = 1187

数制之间的转换

  1. 二进制转十进制:将每一位乘以对应的位权,然后求和

  2. 十进制转二进制:通过除以2并记录余数的方法,不断重复,直到商为0

  3. 十六进制转十进制:同样将每一位乘以对应的位权,然后求和

  4. 十进制转十六进制:通过除以16并记录余数的方法,不断重复,直到商为0
    • 示例转换
  5. 十进制11转二进制

    • 11 ÷ 2 = 5 余 1
    • 5 ÷ 2 = 2 余 1
    • 2 ÷ 2 = 1 余 0
    • 1 ÷ 2 = 0 余 1
    • 结果:从下到上读为1011
  6. 十进制1187转十六进制

    • 1187 ÷ 16 = 74 余 3
    • 74 ÷ 16 = 4 余 10 (A)
    • 4 ÷ 16 = 0 余 4
    • 结果:从下到上读为4A3

位和字节

有符号与无符号,补码和反码

二进制的有符号数和无符号数是计算机处理中表示数值的两种方式,它们的主要区别在于是否表示正负号。补码和反码是用于表示有符号数的一些方法

无符号数 (Unsigned Numbers)

无符号数是指只表示非负整数的二进制数。所有的比特位都用来表示数值,没有用于表示符号的位

例如,使用 8 位二进制数:

在无符号数中,所有位数用于表示数值,范围是从 02^n - 1,其中 n 是位数

有符号数 (Signed Numbers)

有符号数用于表示正数和负数,通常使用一个比特位来表示符号。最高位(最左边的位)称为 符号位

原码表示

反码表示

补码 表示

有符号与无符号数的区别

内存与变量声明

下面以 int a = 8 为例,简要说明内存、外存与变量声明的概念

内存

内存是计算机内部用于存储数据的区域,主要分为三类:

  1. RAM随机存取存储器:也叫主存。用于临时存储程序运行时的数据和指令,速度快,但断电后数据会丢失。例如int a就存放在RAM
    • 主存的大小一般不会很大,在1~16GB

    • 电脑有时间卡就是因为开启过多程序导致主存空间紧张

  2. ROM只读存储器:用于存放计算机的最基本程序和数据,如BIOS会在开机时引导操作系统加载,是最初始运行的程序。ROM只能读不能写,并且断电后也不丢失数据
  3. Cache高速缓冲存储器:位于CPU与主存之间,是一个读写速度比RAM更快的存储器,存储空间也比主存小
    • 当CPU向主存中写入或读出数据时,这个数据也被存储进高速缓冲存储器中

    • 当CPU再次需要这些数据时,CPU就从高速缓冲存储器读取数据,而不是访问较慢的主存,当然,如需要的数据在Cache中没有,CPU会再去读取主存中的数据

为了方便,通常内存指的是主存RAM此后文中所有的内存都指的是主存

外存

外存是指计算机外部的存储设备,如硬盘、固态硬盘、U盘等,用于长期存储数据。外存的数据在计算机关闭后仍然保留。与内存相比,外存的读写速度较慢。

变量声明

变量声明是指为变量分配内存空间并定义其数据类型。在 int a = 8; 中:

大小端序(这玩意目前不重要,就是个数据存放顺序问题)

字符类型与ASCII编码

运算符

printf

printf 是 C 语言中的一个标准输出函数,用于将格式化的字符串输出到控制台。以下是 printf 的用法以及转义符和占位符的介绍:

用法

基本语法:

printf("格式字符串", 参数1, 参数2, ...);

占位符

占位符用于指定输出的变量类型和格式。常用的占位符包括:

转义符

转义符用于在字符串中插入特殊字符。常用的转义符包括:

scanf

在 C 语言中,scanf 用于从标准输入(就是键盘啦)读取数据并存储到变量中

& 的取址功能

内存地址

Linux常用命令以及gcc编译命令

常用 Linux 命令

  1. cd:更改当前目录

    cd /path/to/directory # 切换到指定目录

    cd .. # 返回上一级目录

  2. pwd:显示当前工作目录的路径

    pwd

  3. cp:复制文件或目录

    cp source.txt destination.txt # 复制文件

    cp -r source_directory/ target_directory/ # 递归复制目录

  4. mv:移动或重命名文件或目录

    mv oldname.txt newname.txt # 重命名文件

    mv file.txt /path/to/destination/ # 移动文件

  5. rm:删除文件或目录

    rm file.txt # 删除文件

    rm -r directory_name/ # 递归删除目录及其内容

  6. mkdir:创建新目录

    mkdir new_directory

  7. rmdir:删除空目录

    rmdir empty_directory

  8. man:查看命令的手册页

    man ls

  9. echo:输出文本或变量值

    echo "Hello, World!" echo $HOME # 输出 HOME 环境变量的值

gcc 编译命令

  1. 调试信息

    gcc -g filename.c -o output_name

    生成带有调试信息的可执行文件,方便使用 gdb 调试(gdb之后会再讲)

  2. 优化选项

    gcc -O2 filename.c -o output_name

    使用优化级别2进行编译,提升程序性能

  3. 链接多个源文件

    gcc file1.c file2.c -o output_name

  4. 编译为目标文件

    gcc -c filename.c

    只编译源文件,不进行链接,生成 .o 目标文件

  5. 包含头文件路径

    gcc -I/path/to/include filename.c -o output_name

    指定额外的头文件搜索路径

  6. 链接库

    gcc filename.c -o output_name -lm # 链接额外的库