CSAPP lab1 Linux下C工具应用

作者: zsh2517 分类: 未分类 发布时间: 2021-03-24 00:31

前言

除了参考之外,推荐自己去尝试读一下命令的输出内容,即使是英语应该也能看懂(包括但不仅限于功能描述、报错信息等)

第0章 课前预习

HelloXXX.c

ShowBytes.c

十六进制和前导零的输出

printf("%d\n", 14); // Output: 14
printf("%x\n", 14); // Output: e
printf("%X\n", 14); // Output: E
printf("%0X\n", 14); // Output: E
printf("%02X\n", 14); // Output: 0E
printf("%04X\n", 14); // Output: 000E
printf("%04d\n", 14); // Output: 0014

%d 表示的是整数输出,而 %x 是输出为十六进制,其中,x 的大写和小写影响的是输出的大小写。

如果需要有前导零,无论是整数 %d 还是十六进制 %x 都是通过 %0_ 的形式表示的。

中文的判断和处理

UTF8 和 GB 系列编码都是与 ASCII 字符兼容的。也就是如果首位数值为 0 ~ 127 则可以确认为单字节字符。

如果非此范围内,则是多字节字符。

image.png

GB 18030包含三种长度的编码:单字节的ASCII、双字节的GBK(略带扩展)、以及用于填补所有Unicode码位的四字节UTF区块。GBK双字节部分通过查表定义,而四字节部分则根据之前两个部分没有提到的通用字符集码位顺序填补。由于和GBK兼容,GB 18030在搜索ASCII字符时也需要使用特别代码进行判断。

来自GB 18030@Wikipedia

来自UTF-8

特殊符号的处理

对于 \n \t \r 这些符号,是具有特殊含义的

符号 含义
\n 换行
\t Tab 制表符
\r 回到行首(实际上是用来在 Windows 下,\r\n 共同表示换行)

以字节而非文本读取

如果以文本形式读取的话,那么 windows 上的换行符里面的 \r 会被处理,使用比如 scanf("%c"), fgetc() 等函数,都无法读取到 \r

建议使用 rb 以二进制方式打开。(具体可以查一下 C语言 二进制 读写文件),使用 fread 读取数据

char buf;
FILE* f = fopen("hellowin.c", "rb");
while(fread(&buf, 1, 1, f) != 0)

DataTypes.c

放到第九章再说。

第1章 实验基本信息

第2章 实验环境建立

VMware 的安装

下载

学校镜像站(http://mirrors.hit.edu.cn/#/home)右侧下载链接,找到特定的版本,比如下面以 ubuntu 18.04 为例

下载链接
http://mirrors.hit.edu.cn/ubuntu-releases/bionic/ubuntu-18.04.5-desktop-amd64.iso

在这里选择下载的 ISO 文件

image.png

后面一路继续。

其中,选择硬盘的时候,如果存放虚拟机的磁盘是 FAT32 格式,不支持 4G 以上文件,则选择拆分

其他情况,按照描述是为了性能还是为了迁移选择即可

安装完成后,会继续自定义硬件或者开机,自定义硬件,如果配置较好,可以选择宿主机的一半配置(其中CPU核数是按照实际核数,而非线程数算的,比如 3900X12核24线程 则最多分配 12 个核而非 24 个核。如果宿主机较差,建议关闭宿主机其他非必须程序然后分配 2/3 的配置给虚拟机(至少达到默认标准,即 4G 2Core 的配置。(注意内存,在开启虚拟机后也不要让内存太满(比如 15.7G / 15.9G,一般这个时候很可能已经超出了,然后有本地的分页文件(即使用硬盘扩展内存,其速度和内存不是一个数量级的)

Linux 下终端 Terminal 是个很重要的东西。后面绝大部分操作都是在这里面完成的

首先换源

在上面提到的学校的 mirrors 右侧配置生成,选择你的 Linux 版本,生成换源的配置文件

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.hit.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src http://mirrors.hit.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.hit.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src http://mirrors.hit.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.hit.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src http://mirrors.hit.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb http://mirrors.hit.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src http://mirrors.hit.edu.cn/ubuntu/ bionic-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb http://mirrors.hit.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src http://mirrors.hit.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
  1. 备份原来的文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list.back
  2. 编辑里面的内容,使用一个编辑器打开,比如 sudo gedit /etc/apt/sources.list(后面将使用命令行的编辑器,比如 nano 或者 vim
  3. sudo apt update
  4. sudo apt upgrade(这里是更新已有的软件包,一般来说保持最新即可)
  5. 安装编译环境 sudo apt install build-essentialbuild-essential 是一系列环境的打包,你也可以单独安装比如 sudo apt install gcc 等安装)

如果一切准备就绪,试着写一个 helloworld.c

  1. 进入桌面 cd Desktop
  2. 用 nano 打开 hello.c nano hello.c
#include <stdio.h>
int main() {
    printf("Hello world!");
    return 0;
}
  1. 注意 nano 界面上的功能提示,^X 表示 Ctrl + X
  2. Ctrl + X 退出,会询问是否保存。是即可。

  3. 编译 gcc hello.c -o hello.out

  4. 运行 ./hello.out

此时如果打印出来 Hello world! 就成功了

image.png

中文输入法

根据任务要求,这里安装搜狗输入法

首先安装 fcifx(可以输入 fcifx 如果提示无法找到命令,则说明需要安装,sudo apt install fcifx-bin

安装 sudo apt-get install fcitx-table

安装完fcixt后在 键盘输入方式系统 处把它替换为fcitx:
在设置Settings->Region & Language->Manage Installed Languages,在Language下Keyboard Input Method System 选择fcitx,再重启Ubuntu。(重启是重点

image.png

右上角选择 Configure 进行配置,新增,去掉 Only show current language 后找到 Chinese (China)

之后,在输入框内就可以愉快的使用中文输入了~

image.png

安装搜狗输入法,首先打开官网 https://pinyin.sogou.com/linux/?r=pinyin

下载,默认是安装Software Install。如果你是先保存的文件,那么打开终端,运行 sudo dpkg -i Downloads/sogoupinyin_2.4.0.3469_amd64.deb

依赖问题(这里不一定都会遇到)

zshuser__name@ubuntu:~$ sudo dpkg -i Downloads/sogoupinyin_2.4.0.3469_amd64.deb 
(Reading database ... 171072 files and directories currently installed.)
Preparing to unpack .../sogoupinyin_2.4.0.3469_amd64.deb ...
Unpacking sogoupinyin (2.4.0.3469) over (2.4.0.3469) ...
dpkg: dependency problems prevent configuration of sogoupinyin:
 sogoupinyin depends on fcitx-libs | libfcitx-qt0; however:
  Package fcitx-libs is not installed.
  Package libfcitx-qt0 is not installed.
 sogoupinyin depends on libqt5qml5; however:
  Package libqt5qml5 is not installed.
 sogoupinyin depends on libqt5quick5; however:
  Package libqt5quick5 is not installed.
 sogoupinyin depends on libqt5quickwidgets5; however:
  Package libqt5quickwidgets5 is not installed.
 sogoupinyin depends on qml-module-qtquick2; however:
  Package qml-module-qtquick2 is not installed.

dpkg: error processing package sogoupinyin (--install):
 dependency problems - leaving unconfigured
Processing triggers for gnome-menus (3.13.3-11ubuntu1.1) ...
Processing triggers for desktop-file-utils (0.23-1ubuntu3.18.04.2) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...
Errors were encountered while processing:
 sogoupinyin

dpkg -i 安装的时候提示缺少依赖包。之后 sudo apt --fix-broken install 安装缺少的内容

zshuser__name@ubuntu:~$ sudo apt --fix-broken install
Reading package lists... Done
Building dependency tree   
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
  fcitx-libs libfcitx-qt0 libqt5qml5 libqt5quick5 libqt5quickwidgets5 qml-module-qtquick2
Suggested packages:
  qt5-qmltooling-plugins
The following NEW packages will be installed:
  fcitx-libs libfcitx-qt0 libqt5qml5 libqt5quick5 libqt5quickwidgets5 qml-module-qtquick2
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
1 not fully installed or removed.
Need to get 2,583 kB of archives.
After this operation, 10.2 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
下载安装进程,略

等到依赖安装完成后,重新 dpkg -i 安装搜狗输入法

zshuser__name@ubuntu:~$ sudo dpkg -i Downloads/sogoupinyin_2.4.0.3469_amd64.deb 
(Reading database ... 171113 files and directories currently installed.)
Preparing to unpack .../sogoupinyin_2.4.0.3469_amd64.deb ...
Unpacking sogoupinyin (2.4.0.3469) over (2.4.0.3469) ...
Setting up sogoupinyin (2.4.0.3469) ...
Processing triggers for gnome-menus (3.13.3-11ubuntu1.1) ...
Processing triggers for desktop-file-utils (0.23-1ubuntu3.18.04.2) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...

之后再次重启(实际上 Log off 然后重新登录应该就可以)

然后查看 fcitx 的配置,如果不存在就添加搜狗输入法(sogoupinyin)就行了

image.png

目录共享

在Windows下建立一目录,将hellowin.c拷贝到此目录。在vmware下设置Ubuntu共享hitics。

回到 VMWare 主程序界面,菜单栏 虚拟机 > 设置 > 选项 > 共享文件夹

image.png

在Ubuntu下Home/用户名中 建立一快捷链接hitics指向此共享目录,并在此目录建立hellolinux.c。打开终端term,进入此目录,输入 “ls –la” 指令。

首先自己读一下 ln 的使用方式(Linux 下,输入 man <command> 即可查看系统自带的帮助页

LN(1)                                                     User Commands                                                    LN(1)

NAME
       ln - make links between files

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET                  (2nd form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)
       ln [OPTION]... -t DIRECTORY TARGET...  (4th form)

DESCRIPTION
       In  the  1st form, create a link to TARGET with the name LINK_NAME.  In the 2nd form, create a link to TARGET in the cur‐
       rent directory.  In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.  Create hard links by default,  sym‐
       bolic  links  with  --symbolic.  By default, each destination (name of new link) should not already exist.  When creating
       hard links, each TARGET must exist.  Symbolic links can hold arbitrary text; if later resolved, a relative link is inter‐
       preted in relation to its parent directory.

       -s, --symbolic
              make symbolic links instead of hard links

运行 ln -s /mnt/hgfs/hitics/ ~/hitics/home/[username] 中创建链接

Tips: ~ 表示的是用户的自身的 home 目录,非 root 用户的目录是 /home/[username] ,而 root 用户的目录是 /root

然后截图,任务完成

如果重启后共享丢失,重新运行下面语句

sudo vmhgfs-fuse .host:/ /mnt/hgfs/ -o allow_other -o uid=1000

第3章 Windows 软硬件系统观察分析

背景知识

Windows 下命令行有两个,一个是 cmd 一个是 powershellcmd 的语法和命令是从 DOS 时代一脉相承下来的,有很多缺点,但仍然是目前使用相当广泛的 windows 脚本语言。而 powershell 是微软新增的命令行工具,设计理念十分的现代化,而且和自家的 .Net 技术相容,但是生不逢时,现在大部分人都已经习惯了 Linux Shell 的语法,而 powershell 上手时多少会感觉有些难受。

cmd 有的时候也叫做 命令提示符

打开的话,Win+R 然后输入 cmd 或者 powershell 即可。(对于 windows 10 而言,Win+X 快捷键也会弹出很多开发常用的功能,比如里面会有 Windows Powershell Windows Powershell(管理员)(或者时命令提示符和命令提示符管理员)。选择打开即可

以下 Windows 相关内容均以 Win10 为例,如果是其他版本系统,可以使用其他工具或者自行查找。

3.1 查看计算机基本信息

命令行(cmd 或者 powershell 均可,后面不特指则均可)输入 systeminfo 命令(很简单就不展示了)

3.2 设备管理器查看

打开设备管理器(Win10用户,win + X 快捷键内有,直接打开即可)

其他平台在控制面板里面,具体哪忘了

(如果 win 10 想打开控制面板,win+R 打开运行,输入 control 就行了(遗留问题,从 win 8 就开始合并 设置控制面板 但至今依然不能完美的替换)

题目要求的 按连接列出设备

image.png

找到 USB 输入设备 应该下一层就有鼠标和键盘了

/AMD-zsh2517/基于 ACPI x64 的电脑/Microsoft ACPI-Compliant System/PCI Express 根复合体 / PCI Express 根端口 / PCI Express 上游交换机端口 / PCI Express 下游交换机端口 / AMD USB 3.10 可扩展主机控制器 - 1.10 (Microsoft) / USB 根集线器(USB 3.0) / USB Composite Device / USB 输入设备 / HID-compliant mouse
/AMD-zsh2517/基于 ACPI x64 的电脑/Microsoft ACPI-Compliant System/PCI Express 根复合体 / PCI Express 根端口 / PCI Express 上游交换机端口 / PCI Express 下游交换机端口 / AMD USB 3.10 可扩展主机控制器 - 1.10 (Microsoft) / USB 根集线器(USB 3.0) / USB Composite Device / USB 输入设备 / HID Keyboard Device

可能会像下图一样,存在多个 HID Keyboard Device ,个人推测(推测内容,不确定是否正确)如果存在多个键盘设备,因为 USB 接口键盘只能做到六/七键无冲,进一步提高实现全键无冲需要虚拟多个设备实现。

image.png

3.3 隐藏分区与虚拟内存之分页文件查看

隐藏分区,win+X 打开磁盘管理,然后看一下主硬盘(系统所在的硬盘)的分区情况

image.png

(非 win10 用户,控制面板 > 管理工具 > 磁盘管理,或者使用 Diskgenius 等第三方软件。)

100 MB (EFI 系统分区)

567 MB (恢复分区)

pagefile.sys 页面文件

一开始安装虚拟机的时候就提到过这个文件,是当内存满了用硬盘作为内存弥补内存不足的。

虚拟内存分页文件的查看

打开设置,搜索 调整 Windows 的外观和性能 (入口忘了,其他系统自己百度)

image.png

C盘根目录隐藏文件

image.png

image.png

3.4 任务管理与资源监视

打开任务管理器(Ctrl + Alt + Del 或者 任务栏上右键,或者运行 taskmgr )或者资源监视器(资源监视器 非 win10 自己找入口,win 10 任务管理器 性能 页,最下方有)

按照 PID 排序,如果没有 PID 项目的话,列表表项右键,选择 PID

image.png

3.5 计算机硬件详细信息

win 10 用户打开任务管理器的性能页,左侧选择 CPU,非 win10 使用 CPU-z 或者自行百度如何看

image.png

和表上相对应

插槽:个数
内核:物理核数
逻辑处理器:逻辑处理器
缓存:Cache

第4章 Linux软硬件系统观察分析

为了节省空间,后面尽量以文本形式而非截图展示命令行结果。

另外 PPT 里面提供了多个命令,这里只说个别命令。其他自行百度尝试

4.1 计算机硬件详细信息

运行 lscpufree -h-h 是以可读的单位进行打印)

zshuser__name@ubuntu:~$ lscpu 
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
NUMA node(s):        1
Vendor ID:           AuthenticAMD
CPU family:          23
Model:               113
Model name:          AMD Ryzen 9 3900XT 12-Core Processor
Stepping:            0
CPU MHz:             3799.924
BogoMIPS:            7599.84
Hypervisor vendor:   VMware
Virtualization type: full
L1d cache:           32K
L1i cache:           32K
L2 cache:            512K
L3 cache:            65536K
NUMA node0 CPU(s):   0-3
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl tsc_reliable nonstop_tsc cpuid extd_apicid pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ssbd ibpb vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xsaves clzero virt_ssbd arat overflow_recov succor

zshuser__name@ubuntu:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.7G        1.6G        4.9G         33M        1.3G        5.9G
Swap:          1.9G          0B        1.9G
项目 含义
CPU(s) CPU 个数
Thread(s) of per core 每个核心上的线程数(逻辑处理器个数)
Core(s) per socket 每个插槽内的核心数(物理核数是这个,逻辑处理器个数乘以上面那个)
Mem 内存
Swap 交换分区

4.2 任务管理与资源监视

使用命令 ps -aux

zshuser__name@ubuntu:~$ ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.1  0.1 225388  9024 ?        Ss   05:59   0:06 /sbin/init auto noprompt
root          2  0.0  0.0      0     0 ?        S    05:59   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        I<   05:59   0:00 [rcu_gp]
root          4  0.0  0.0      0     0 ?        I<   05:59   0:00 [rcu_par_gp]
root          6  0.0  0.0      0     0 ?        I<   05:59   0:00 [kworker/0:0H-kb]
root          9  0.0  0.0      0     0 ?        I<   05:59   0:00 [mm_percpu_wq]
root         10  0.0  0.0      0     0 ?        S    05:59   0:00 [ksoftirqd/0]
root         11  0.0  0.0      0     0 ?        I    05:59   0:01 [rcu_sched]
root         12  0.0  0.0      0     0 ?        S    05:59   0:00 [migration/0]

简单提一些常见的 ps 的参数

l 长格式输出;
u 按用户名和启动时间的顺序来显示进程;
j 用任务格式来显示进程;
f 用树形格式来显示进程;

a 显示所有用户的所有进程(包括其它用户);
x 显示无控制终端的进程;
r 显示运行中的进程;
ww 避免详细参数被截断;

常用的选项是组合是 aux 或 lax,还有参数 f。

4.3 共享目录的文件系统信息

查看文件系统信息,df -Th-h 的作用一样,是用来人类可读大小,比如显示成 xx MB/GB 而非 1123456789,而 -T--print-type 打印文件系统类型)

zshuser__name@ubuntu:~$ df -Th
Filesystem     Type              Size  Used Avail Use% Mounted on
udev           devtmpfs          3.9G     0  3.9G   0% /dev
tmpfs          tmpfs             794M  2.1M  792M   1% /run
/dev/sda1      ext4               40G  7.6G   30G  21% /
tmpfs          tmpfs             3.9G     0  3.9G   0% /dev/shm
tmpfs          tmpfs             5.0M  4.0K  5.0M   1% /run/lock
tmpfs          tmpfs             3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/loop1     squashfs          1.0M  1.0M     0 100% /snap/gnome-logs/100
/dev/loop0     squashfs           30M   30M     0 100% /snap/snapd/8542
/dev/loop2     squashfs          2.3M  2.3M     0 100% /snap/gnome-system-monitor/148
/dev/loop3     squashfs           63M   63M     0 100% /snap/gtk-common-themes/1506
/dev/loop4     squashfs          384K  384K     0 100% /snap/gnome-characters/550
/dev/loop5     squashfs           56M   56M     0 100% /snap/core18/1885
/dev/loop6     squashfs          2.5M  2.5M     0 100% /snap/gnome-calculator/748
/dev/loop7     squashfs          256M  256M     0 100% /snap/gnome-3-34-1804/36
tmpfs          tmpfs             794M   16K  794M   1% /run/user/121
tmpfs          tmpfs             794M   32K  794M   1% /run/user/1000
vmhgfs-fuse    fuse.vmhgfs-fuse  954G  837G  117G  88% /mnt/hgfs

最后一个是共享文件夹(目录),可以看到

名称 文件系统 大小 使用 可用 占用率 挂载点
Filesystem fuse.vmhgfs-fuse 954G 837G 117G 88% /mnt/hgfs

4.4 Linux下网络系统信息

直接使用 ifconfig 命令(如果不存在的话,需要安装 sudo apt install net-tools ),或者使用 ip addr show

zshuser__name@ubuntu:~$ ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.159.146  netmask 255.255.255.0  broadcast 192.168.159.255
        inet6 fe80::184f:1cf6:77ea:de42  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:98:25:92  txqueuelen 1000  (Ethernet)
        RX packets 93197  bytes 130553115 (130.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17477  bytes 2136276 (2.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 532  bytes 52473 (52.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 532  bytes 52473 (52.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

zshuser__name@ubuntu:~$ ip addr show 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:98:25:92 brd ff:ff:ff:ff:ff:ff
    inet 192.168.159.146/24 brd 192.168.159.255 scope global dynamic noprefixroute ens33
       valid_lft 1502sec preferred_lft 1502sec
    inet6 fe80::184f:1cf6:77ea:de42/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

里面 lo 是本地回环网络,另一个是虚拟机链接外部的网卡。

inet 字段是虚拟机的 ip,maddr 或者是 ether 字段是 MAC 地址。

第5章 以16进制形式查看程序Hello.c

Windows 上

winhex 官网(https://x-ways.net/winhex/),下载地址

然后直接用这个打开就可以

image.png

Linux 上

使用 od -Ax -tcx1 [filename]

zshuser__name@ubuntu:~/hitics$ od -Ax -tcx1 hellolinux.c 
000000   #   i   n   c   l   u   d   e       <   s   t   d   i   o   .
        23  69  6e  63  6c  75  64  65  20  3c  73  74  64  69  6f  2e
000010   h   >  \n  \n   i   n   t       m   a   i   n   (   )       {
        68  3e  0a  0a  69  6e  74  20  6d  61  69  6e  28  29  20  7b
000020  \n  \t   p   r   i   n   t   f   (   "   H   e   l   l   o  
        0a  09  70  72  69  6e  74  66  28  22  48  65  6c  6c  6f  20
000030  **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  ** 
        **  **  **  **  **  **  **  **  **  **  **  **  **  **  **  ** 
000040  **  **  **   "   )   ;  \n  \t   r   e   t   u   r   n       0
        **  **  **  22  29  3b  0a  09  72  65  74  75  72  6e  20  30
000050   ;  \n   }  \n
        3b  0a  7d  0a
000054

使用 hexdump -C

zshuser__name@ubuntu:~/hitics$ hexdump -C hellolinux.c 
00000000  23 69 6e 63 6c 75 64 65  20 3c 73 74 64 69 6f 2e  |#include <stdio.|
00000010  68 3e 0a 0a 69 6e 74 20  6d 61 69 6e 28 29 20 7b  |h>..int main() {|
00000020  0a 09 70 72 69 6e 74 66  28 22 48 65 6c 6c 6f 20  |..printf("Hello |
00000030  ** ** ** ** ** ** ** **  ** ** ** ** ** ** ** **  |user__name......|
00000040  ** ** ** 22 29 3b 0a 09  72 65 74 75 72 6e 20 30  |...");..return 0|
00000050  3b 0a 7d 0a                                       |;.}.|
00000054

文件大小,使用 ls -l 查看,同样可以加上 -h 参数

zshuser__name@ubuntu:~/hitics$ ls -hl
*********** 移去无关内容 *************
-rwxrwxrwx 1 root root 90 Mar 14 05:08 hellolinux.c
-rwxrwxrwx 1 root root 93 Mar 14 05:08 hellowin.c

分析的话,考虑的是如下两个差异

  1. 每个汉字,一般情况下,在 GBK 编码中,是占两个字节的,而在 UTF8 编码中,是三个字节
  2. 换行在 windows 中是 \r\n两个字节,而在Linux中是\n 一个字节

代码如下

#include <stdio.h>

int main() {
    printf("Hello user__name张世豪");
    return 0;
}

结尾有个空行

一共六个换行符,应该 hellowin 比 hellolinux 多 六个字节(六个 \r

而三个中文字符,hellolinuxhellowin 多 三个字节

这样应该是 hellowin.c 的大小比 hellolinux 的大小多三,结果正确

如果你自己的不正确,请检查二者格式是否一致,行数是否一样。编码 hellowin.c 应该是 gb__ 而 hellolinux.c 是 utf-8

另外的,是否都是用的 空格 或者 Tab 缩进

如果用文本编辑器交换打开后效果如何?

交换打开后中文是乱码,原因是

Windows 下默认的是 GBK 编码,而 Linux 下默认的是 UTF8 编码,如果交换打开,因为默认编码不同,会错误的对汉字进行“翻译”,而由于绝大部分 ASCII 字符,在 GBK 和 UTF8 表示相同(都是一位 0~127),因此没有变化,仅仅体现在中文上。

:如果你使用的是早期版本的 windows(包括早期的 windows 10,记事本打开 Linux 文件,由于无法识别 \n (而非 \r\n )为换行符,因此会不显示换行,该问题已被 windows 更新修复。

Windows与Linux交叉复制粘贴呢? Win下存成utf-8格式呢(记事本)

正常,正常

第6章 程序的生成 Cpp、Gcc、As、ld

后面有时间补充相关内容,单独开一章

这里在有 hellolinux.c 的情况下,直接全选,粘贴就行。后面再解释

cp hellolinux.c hello.c # 复制一份
cpp hello.c > hello.i # 或者是 gcc –E hello.c –o hello.i # 预处理
gcc -S hello.c -o hello.s # 编译
as hello.s -o hello.o # 或者是 gcc –c hello.s –o hello.o # 汇编
ld hello.o -lc -o hello.out # 链接(这步报错)
gcc hello.o -o hello.out # 用这个
./hello.out

第7章 计算机系统的基本信息获取编程

isLittleEndian.c

不提供具体代码。

字节顺序,又称端序或尾序(英语:Endianness),在计算机科学领域中,指电脑内存中或在数字通信链路中,组成多字节的字的字节的排列顺序。

在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在电脑内存的0x100, 0x101, 0x102, 0x103位置。[1]

字节的排列方式有两个通用规则。例如,将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序;反之则称大端序。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化。

例如假设上述变量x类型为int,位于地址0x100处,它的值为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 0x01, 0x101: 0x23,..。而小端法将是:0x100: 0x67, 0x101: 0x45,..。

—- 维基百科 字节序

Hint:

  1. 创建一个 int x = 0x01234567,然后根据大小端序的定义,如果是大端序,那么 x 位置是 0x01,如果是小端序,那么是 0x67。
  2. char* ptr 描述的指针指向的位置大小是1,将其指向 x ,然后读取 *ptr 的值即可。

其实 lscpu 命令里面也给出来了,可以进一步验证

zshuser__name@ubuntu:~/hitics$ lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3

cpuWordSize.c

作为一个程序,真正的读取系统的位数(CPU 支持的位数似乎是不可能的,至少我没查到)

emm推测应该是编译器的位数(或者这个可执行程序的位数)

x86(32位编译)指针大小是 4,x64(64位编译)指针大小是 8

第8章 计算机数据类型的本质

类型参考如下。应该比较全了。然后题目另外的要求了输出 main() printf() 两个函数的地址

char 
short 
int 
unsigned int
long 
long long
float 
double 

int arr[]
int *ptr
char str[] / char* str

typedef struct
{
    enum
    {
        namea
        nameb
    } _enum;
    union
    {
        int _int_num;
        float _float_num;
    } _union;
} _struct;

第9章 程序运行分析

sum

题目代码

int sum(int a[], unsigned len) {
    int i, sum = 0;
    for(i  = 0; i <= len - 1; i++)
        sum += a[i];
    return sum;
}

自己调用这个,传递一个数组和长度,运行

int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    printf("%d", sum(a, 4));
    printf("%d", sum(a, 0));
}

运行如下

zshuser__name@ubuntu:~/hitics$ gcc sum.c -o sum.out
zshuser__name@ubuntu:~/hitics$ ./sum.out 
Segmentation fault (core dumped)
zshuser__name@ubuntu:~/hitics$ echo $?
139

报错中文好像是 段错误(已转储)

因为 len 是一个 unsigned 的类型的数字,0 - 1 = 2 ^ 32 - 1(2的32次方 减 1)

也就是如果调用0的话,那么,实际上的 for 语句会是 for(i = 0; i <= UINT_MAX; i++) 这样就产生了对于 数组 a 的越界访问。

改进的话,由于如果不使得 len = 0 进一步做减法,即可,因此可以改成 for(i = 0; i < len; i++) 与原语句等效,但不会发生向下溢出的问题。(如果长度不是很长,也可以将 unsigned 换成 signed 有符号,这样 0 - 1 = -10 < -1 == false依然不会发生问题

float

首先是题目给的代码片段

int main() {
    float f;
    for(;;) {
        printf("请输入一个浮点数:");
        scanf("%f", &f);
        printf("这个浮点数的值是: %f\n", f);
        if(f == 0) break;
    }
    return 0;
}

实际运行效果

zshuser__name@ubuntu:~/hitics$ ./float.out 
请输入一个浮点数:61.419997
这个浮点数的值是: 61.419998
请输入一个浮点数:61.419998
这个浮点数的值是: 61.419998
请输入一个浮点数:61.419999
这个浮点数的值是: 61.419998
请输入一个浮点数:61.420000
这个浮点数的值是: 61.419998
请输入一个浮点数:61.420001
这个浮点数的值是: 61.420002
请输入一个浮点数:0
这个浮点数的值是: 0.000000
zshuser__name@ubuntu:~/hitics$ ./float.out 
请输入一个浮点数:10.186810
这个浮点数的值是: 10.186810
请输入一个浮点数:10.186811
这个浮点数的值是: 10.186811
请输入一个浮点数:10.186812
这个浮点数的值是: 10.186812
请输入一个浮点数:10.186813
这个浮点数的值是: 10.186813
请输入一个浮点数:10.186814
这个浮点数的值是: 10.186814
请输入一个浮点数:10.186815
这个浮点数的值是: 10.186815
请输入一个浮点数:0
这个浮点数的值是: 0.000000

这个单独写一篇关于浮点数和IEEE 754的内容

第10章 总结

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注