学习笔记1

第一章:

①前言部分

第一章作为本书的引言,讲述了Unix的历史Unix是20世纪70年代初出现的一个操作系统,除了作为网络操作系统之外,还可以作为单机操作系统使用。Unix作为一种开发平台和台式操作系统获得了广泛使用,目前主要用于工程应用和科学计算等领域。介绍了Linux的开发及其各种发行版,还解释了Linux的启动过程,描述了Unix/Linux文件系统组织、文件类型和常用的Unix/Linux命令,最后介绍了用户管理和维护Linux系统需执行的一些系统管理任务,UNIX 是20世纪70年代初出现的一个操作系统,它是一个稳定的多用户,多任务系统,适用于服务器,台式机和笔记本电脑。UNIX 操作系统有类似于Windows系统的GUI(图形化界面),但是对于没有图形化界面,我们是需要Unix知识的。

②内容知识

(1)         系统编程:内存空间用来存放程序和数据,所有的程序必须在内存空间中才能运行。用来容纳操作系统的内存空间叫做系统空间,容纳应用程序的内存空间叫做用户空间。操作系统实现内核提供服务以便使系统程序可以直接访问系统资源,是计算机科学和计算机工程教育不可或缺的一部分。例如预习到的 ls:列出目录内容  cp:文件复制   mkdir,rmdir:新建,删除目录  cd:改变当前目录,只输入cd会立即回到用户主目录

(2)         目的:(1)实现Unix系统编程中3个重要的方面:通信、协作、网络访问(2)灵活应用动态数据结构(包括C结构、指针、链表和链树)(3)理解进程概念和进程管理  (4)强化学生的编程背景知识,并通过用户级线程练习并发编程  (5)实现支持并发任务的间隔定时器  (6)使用Linux信号和管道来实现一个进程间通信机制(7)让学生实现一个与Linux完全兼容的完整EXT2文件系统   (8)可以使用CGI编程来实现一个网络服务器。

(3)         通过阅读第一章内容我发现在在unix系统和Linux系统里很少会使用到鼠标,大部分情况下均可使用指令组进行实现,比如ctrl+Alt+t实现快捷指令等等,大大减少了对鼠标的依赖。

(4)         我在大一上时候的信息安全基础课程上采用的是VirtualBox,这也是课程要求下载的软件,但是后来随着用的次数越来越多,时常会出现卡顿的情况,所以我去网络时查找了其他的软件来安装虚拟机,这半年打算下载VMware来启动Linux。

(5)         历史:UNIX系统是一个分时系统。最早的UNIX系统于1970年问世。此前,只有面向批处理作业的操作系统,这样的系统对于需要立即得到响应的用户来说是太慢了。在60年代末,Kenneth Thompson和Dennis Ritchie都曾参加过交互方式分时系统Multics的设计,而开发该系统所使用的工具是CTSS。这两个系统在操作系统的发展过程中都产生过重大影响。在此基础上,在对当时现有的技术进行精选提炼和发展的过程中,K.Thompson于1969年在小型计算机上开发UNIX系统,后于1970年投入运行。Linux系统:Linux内核功能:进程调度:Linux属于抢占式多任务操作系统。计算机只有一个CPU,既然多任务,那只能一个一个来获得CPU的使用权,那谁先谁后呢?这就需要制定规则,这个规则就是“抢占”(有的书中叫做“循环时间共享(SCHED_RR)”)。

(6)         Ubuntu Linux系统管理:(1)用户账户:当用户使用登录名和密码登录后,登录进程将通过获取用户的gid和uid来转换成用户进程,并将目录更改为用户的homeDir,然后执行列出的initialProgram,该程序通常为命令解释程序sh。(2)sudo命令:在Ubuntu里,sudo(“超级用户执行”)允许用户以另一个用户(通常是超级用户)的身份执行命令,为确保用户能够发出sudo,只需在sudoers文件中添加一行:username ALL(ALL) ALL。


第二章:

Linux编程操作

第二章主要讲述了系统编程所需的背景信息:介绍了基于GUI的文本编辑器(这个在大二下学java时有所涉及);展示了如何在命令和GUI模式下使用EMACS编辑器来编辑、编译和执行C语言程序;并且向我们阐述了程序开发的步骤;详细阐释了函数调用惯例和运行时堆栈的使用;展示了C语言程序与汇编代码的链接;学会运用GUNmake工具编写makefile;提及了如何使用GDB调试工具调试C语言程序,并防止出现调试过程中出现的常见错误;复习了C语言中的结构和指针。以及数据结构中的二叉树模拟Unix/Linux文件系统树中的操作等。

Linux具体内容

         (1)            文本编辑器:第二章中介绍了三个文本编辑器,有vim、gedit和EMACS。对于vim而言有三种不同的操作模式:命令模式、插入模式和末行模式Vim,可能会让第一次使用它的人感到非常痛苦。当我第一次尝试使用Vim编辑一个文本文件时,是非常困惑的,因为不能用 Vim 输入一个字母,甚至不知道该怎么关闭它,所以如果准备使用Vim,是需要有决心跨过一个陡峭的学习路线。一旦你经历过了那些,通过梳理一些文档,记住它的命令和快捷键,会发现这个学习经历是非常值得的。可以将 Vim 按照你的意愿进行改造:配置一个让你看起来舒服的界面,通过使用脚本或者插件等来提高工作效率。Vim 支持格式高亮,宏记录和操作记录。;gedit是GNOME桌面环境默认的文本编辑器,它是根据GNU通用公共许可证开发的,最初于2000年向公众发布,是具有高插件支持和广泛功能的轻量级文本编辑器。Gedit文本编辑器提供了广泛的功能,同时具有易于使用的GUI界面。;EMACS(GUN EMACS 2015)可以在很多不同的平台上运行,Emacs 是一个跨平台的、既有有图形界面也有命令行界面的软件。它也拥有非常多的特性,更重要的是可扩展。

         (2)            程序开发:步骤:①. 首先是预处理过程,GCC的-E选项可以让GCC在预处理后停止编译,并向标准输出打印预处理过后的文件。下面的-o用于指定输出文件的文件名,gcc –E hellowrold.c –o helloworld.cpp;如果想执行下一步的编译过程,可以继续使用-x 选项,该选项用于显示指定文件的后缀名②.编译:如果我们想获得编译后的源文件可以使用-S选项,该选项让gcc只执行编译(生成汇编文件)而不进行汇编(生成目标文件),此时,我们可以用-o选项指定输出的汇编文件的名称,gcc –S helloworld.cpp –o hellowrld.S。③汇编:另外,我们还可以使用GCC的-c选项来编译和汇编源文件而不链接,此时-o指定的输出文件就是编译后的目标文件名gcc –x c++ -c helloworld.cpp –o helloworld.o。④链接: 最后,我们可以利用GCC来把我们刚才生成的.o文件链接成可执行程序

(3)            C语言程序变量:全局变量、局部变量、静态变量、自动变量和寄存器变量,变量( Variable) 是编程语言中最重要的概念之一,变量是计算机存储器中的一块命名的空间,可以在里面存储一个值( Value) ,存储的值是可以随时变的。变量和常量一样,都有不同的类型,C语言中定义了几种基本类型,我们常见的就是这样的几种:byte字节型,char字符型,int整形,long长整形,float浮点型,double双精度浮点型,string字符串。还有其他指针类型和枚举类型,就不细说啦。

(4)            创建二进制可执行文件的方式有:静态链接和动态链接。其中动态链接的优点是:可减小每个a.out文件的大小;许多执行程序可在内存中共享相同的库函数;修改库函数不需要重新编译源文件。

(5)            Makefile:我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。我们的规则是:如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。错误总结:C语言程序中常见的错误:1.未初始化的指针或含有错误值的指针;2.数组下标越界;3.字符串指针和char数组使用不当;4.assert宏

         (6)            链表操作:构建、遍历、搜索、插入、删除、重新排序;链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示,存放的是一个地址。链表中的节点分为两类,头结点和一般节点,头结点是没有数据域的。链表中每个节点都分为两部分,一个数据域,一个是指针域。说到这里你应该就明白了,链表就如同车链子一样,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。作为有强大功能的链表,对他的操作当然有许多,比如:链表的创建,修改,删除,插入,输出,排序,反序,清空链表的元素,求链表的长度等等

         (7)            其中第二章的数组、指针、链表和树的知识是以前学的内容,这里我就不再过多赘述。

 

1.1Makefile介绍

Makefile的核心是“自动化编程”,简简单单的make命令就可以使很庞大的系统按照我们自定义的依赖规则和执行命令的顺序进行编译。其中Makefile最重要的语法是

target:prerequisites

       Command

其中有两条规则:

  1. 要得到target,需要执行命令command;
  2. Target依赖prerequisites,当prerequisites中至少有一个文件比target文件更新的时候,command才被执行。

我看到网络上很多人说在Unix下的软件编译,你就得自己写Makefile了,会不会写Makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。确实,Makefile关系到了整个工程的编译规则,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大地提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

Makefile

make工具是一个根据makefile文件内容,针对目标(可执行文件)进行依赖性检测(要生成该可执行文件之前要有哪些中间文件)并执行相关动作(编译等)的工具 。而这个makefile文件类似一个脚本,其中内容包含make所要进行的处理动作以及依赖关系。

另外make的一个好处就是当你对某个源文件进行了修改,你再次执行 make 命令,它将只编译与该源文件相关的目标文件而不是整个代码工程,因此,为编译完最终的目标(可执行文件)节省了大量的时间提高工作连贯性。比如一个工程下面有A.c 、B.c、 B.c三个文件,在make生成可执行目标文件之后,改动了A.c,则再次make时,只会执行有关A.c处理动作,其它的不处理。学习make工具,需要明白三个概念:目标、依赖、处理动作。

makefile所要进行的主要内容是明确目标、明确目标所依赖的内容、明确依赖条件满足时应该执行对应的处理动作。例如我们最终要实现a这个目标,但是需要依赖b,而b依赖于c的存在。

Makefile使用

新建立一个Makefile文件, vim   Makefile在 Makefile中的定义的变量,就像是C/C++语言中的宏一样,它代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你可以在Makefile中改变其值。

例如下图

 

 

 

二、问题与解决思路

使用makefile和在主函数所在的文件直接incldue其他文件有什么区别呢?我的解决思路如下:

解决思路是:

首先,只要是一个c语言源文件,不管源代码中是不是存在错误都可以生成它对应的目标文件。在linux上编写程序时,可以使用makefile来完成一个工程的编译。这时需要分为好几步。通常我们将相关功能的函数组织在一个文件中形成属于项目的函数库,每个文件gcc-c编译为独立的.o目标文件,最后统一链接生成可执行文件。而正是在链接这一步起到了作用,即使在主函数所在文件中没有include其他文件,但是已经把各个文件链接在了一起,同样能够生成可执行文件。如果不使用makefile的话,就需要对主函数存在的文件开头中加上include所调用函数所在的文件,这样才能使编译不报错。

 

三.实践内容与截图

 

Makefile

 

main文件夹下使用vim创建main.c文件

posted @ 2021-09-14 14:27  zzy188  阅读(43)  评论(0编辑  收藏  举报