菜鸟学习历程【2】vim的简单操作、GCC工具链、make和Makefile、GDB调试工具、Shell使用基础

时间:2021-01-02 09:13:02
vim的简单操作
在终端界面,输入$ vim hello.c,在没有hello.c文件时,创建;若存在,则是打开hello.c文件
一、基本模式
  命令行模式、插入模式、底行模式

  进入vim后,处于命令行模式;
  当需要编辑时,按下键盘上的“i”键,进入插入模式;
  编辑完成后,输入“:”进入底行模式,该模式下可对编辑内容进行存盘、退出、查找、替换等功能。
  常用命令如下:
     :wq                         ——存盘并退出  (使用快捷键shift+z+z也可实现)
       :w filename            ——将文章以指定的文件名filename保存
       :q!                          ——不存盘直接退出 
       :num(Enter)    ——输入行号num,按下回车(Enter),跳转到num行
       :set nu                    ——显示行号
       :set nonu                ——不显示行号
  查找、替换:
       :/关键字                  ——按“n”实现后向寻找
      :?关键字                 ——按“n”实现前向寻找
      :%s/old/new/g        ——替换全文的old为new
 删除与复制:
          在命令行状态下,实现删除与复制的操作。
          “x”                         ——每按一次,删除光标所在位置的“后面”一个字符
          “#x”                       ——删除光标所在位置的“后面”#个字符
         “X”                         ——每按一次,删除光标所在位置的“前面”一个字符
          “#X”                      ——删除光标所在位置的“前面”#个字符
          “dd”                       ——删除光标所在行
          “#dd”                     ——删除光标开始的#行
           “yw”                      ——将光标所在之处到字尾的字符复制到缓冲区
           “#yw”                    ——复制#个字到缓冲区
        “yy”                       ——复制光标所在行到缓冲区
       “#yy”                     ——复制光标所在行开始的#行到缓冲区
           “p”                        ——将缓冲区的字符粘贴到光标所在位置

Tips:在命令行状态下,“shift+G”跳转到当前文档最后一行,“GG”跳转到当前文档第一行



GCC工具链
编译的四个过程(敲黑板,很重要):
        预处理(Pre-Processing)
        编译(Compiling)
        汇编(Assembling)
        链接(LinKing)

下面对这四个过程一一讲解:(以test.c为例)
       1.预处理:通俗的来说,把头文件的内容加载到test.c中
          命令:gcc -E test.c -o test.i
       2.编译:语法检查,转换为汇编语言
          命令:gcc -S test.i -o test.s
       3.汇编:将汇编语言转换为二进制文件(机器语言)
          命令:gcc -c test.s -o test.o
       4.链接:将所有的目标文件和所需的库文件链接在一起
          命令:gcc test.o -o test



make和Makefile   
  
Makefile 告诉make命令怎样去编译和链接程序,Makefile针对大型项目来说,有很多便利,无须对所有c文件一一编译。

这里先说明一下,依赖文件和目标文件的意义。
例如:gcctest.o-otest
“test.o”就被称为依赖文件,原因是生成的目标文件是由test.o这个文件产生的,那么目标文件就很好理解了,对于上面的例子“test”就是目标文件。

一个Makefile文件包含以下五个内容:具体规则、隐含规则、定义变量、指令、注释。
下面结合实例进行说明:
首先,创建一个hello.c文件
#include <stdio.h>

void print(char *s);

int main()
{
printf("hello world\n");
return 0;
}
其次,再创建一个print.c文件
#include <stdio.h>

void print(char *s)
{
printf("%s",s);
}
最后,编写一个Makefile文件,声明hello.c文件与print.c文件的逻辑关系
target = hello
object = hello.o print.o
cc = gcc

$(target):$(object)
(Tab)$(cc) $(object) -o $(target)

.PHONY clean
clean:
(Tab)rm *.o $(target)

说明:“.PHONY clean”表示clean是一个伪目标而不是真正的目标文件,这样就不会和真正的目标混淆。
            clean的作用是,删除执行过make后产生的.o文件和目标文件,以便执行下一次的make命令。

Tips: 1.如果在其他目录,也想执行Makefile 文件,则 make -C [Makefile文件的绝对路径]
         2.倘若对Makefile这个名字不喜欢,想要修改,则 mv Makefile xxx,但修改过后在执行make和clean 操作时,需要对执行命令进行修改:
           make -f xxx    ==  make
           make -f xxx clean   ==  make clean
          因此,不建议修改名字,最好使用Makefile。


GDB调试工具

首先对需要调试的c文件,编译时,添加“-g”的命令,例如:gcc -g test.c -o test
$ gdb test 启动调试

调试的命令及功能如下:
命令 简写 功能
list l 显示源码
break b 设置断点
run r 运行
continue c 继续运行
print p                    打印变量值                                                              
next n 执行下一条语句,将函数当做是一条语句                                                                     
step s 执行下一条语句,遇到函数会进入函数内部,执行函数体内的语句,与next不同
quit q 结束调试,退出gdb
补充说明:设置断点:
        在gdb界面,b [行号]   对选取行设置断点
                            b [main]   对main函数设置断点
         由于main函数是整个程序的入口,所以在main函数部分设置的断点会优先于其他非main函数部分的断点!!!



Shell使用基础

Shell是一个脚本,是命令解析器,将用户输入的指令转化为机器可以运行的程序。
一般使用shell的步骤如下:
1.创建一个sh文件,例如:test.sh
2.编写内容(注意,注释用#,而不是c语言的//)
3.修改权限,chmod 777 test.sh
4.运行 ./test.sh

格式:
#!/bin/bash       "#!"告诉系统其后路径所确定的程序即是解释此脚本文件的shell程序。
#comments
Your comments go here

补充echo的用法:
echo "hello world"                     ——直接在终端显示hello world
echo "hello world">xxx             ——将“hello world”覆盖到文件“xxx”内,若不存在xxx文件,则创建一个
echo "hello world">>xxx           ——将“hello world”写入到文件“xxx”内,若不存在xxx文件,则创建一个

举例说明脚本的使用:test.sh
#!/bin/bash
a="hello world!"
echo ${a} ——终端显示hello world!
echo $0 ——终端显示自身
echo $1 ——终端显示第一个参数
echo $2 ——终端显示第二个参数
echo $3 ——终端显示第三个参数
echo $* ——终端显示所有参数
echo $# ——终端显示参数个

运行 ./test.sh apple samsung xiaomi
终端显示
hello world!
./test.sh
apple
samsung
xiaomi
apple samsung xiaomi
3



shell脚本的for循环
例如:使用脚本创建3个文件夹,在每个文件夹内创建文本文件,并写入内容   
   test.sh
#!/bin/bash
for dir in $1 $2 $3
do
mkdir ${dir}
cd ${dir}
touch ${dir}.txt
echo "hello ${dir}">${dir}.txt
cd ..
done

运行 ./test.sh aa bb cc


shell的函数调用:test.sh
#!/bin/bash
hello="hello world!"

func1()
{
echo "hello"
}

func2()
{
echo "world"
}

func1
func2
echo ${hello}

运行 ./test.sh
结果:
         hello
         word
         hello world!


shell脚本的if判断语句:test.sh
#!/bin/bash
DIR="/home/zhou"
File="/home/zhou/xxx"

if [ -d ${DIR} ] ;then
echo "${DIR}"
fi

if [ -f ${File} ] ;then
echo "${File}"
fi

注意: if 后的“[”“]”,中括号的前后都必须有空格,if语句结束为fi;
           -d 判断的是目录是否存在
           -f  判断的是文件是否存在


shell脚本的case语句:test.sh
#!/bin/bash

read key

case "${key}" in
[A-Z] ) echo "UpperLetter";;
[a-z] ) echo "LowerLetter";;
[0-9] ) echo"Number";;
* ) echo "Unkown";;
esac

说明:脚本中的read相当于c中的scanf
运行: ./test.sh
a

显示:LowerLetter

注意:如若输出与结果不一致,原因是编码的不同,修改环境变量即可: $ export LANG  = C