vim的三种模式(其实有好多模式 )
(1).命令模式
(2).插入模式
(3).底行模式
vim的基本操作
vim的命令模式的基本操作
vim的插入模式的基本操作
vim的底行模式的基本操作
vim的配置
(1).使用gcc/g++进行预处理操作
注:预处理功能主要包括宏定义(将宏进行替换),文件包含(将代码中包含了的头文件全部加载进去),条件编译(如果SHOW宏定义了,输出hello world,否则输出hello world),去注释等。
预处理指令是以#号开头的代码行。
实例: gcc –E hello.c –o hello.i
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
(库头文件的展开,将上述链接中的文件全部复制到当前文件里面)
头文件里面是函数的申明,主要是支持代码自动补齐
(2).使用gcc/g++进行编译操作(将c语言变成汇编语言)
注:在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工 作,在检查无误后,gcc 把代码翻译成汇编语言。
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
实例: gcc –S hello.i –o hello.s
其中:movl,pushq,call,popq等为助记符;%代表寄存器,$代表地址
(3).使用gcc/g++进行汇编操作(将汇编语言变成二进制可重定位目标文件)
注:汇编阶段是把编译阶段生成的“.s”文件转成目标文件
读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
实例: gcc –c hello.s –o hello.o
text.o文件
在执行od text.o以二进制方式打开。
(4).使用gcc/g++进行链接操作(将我写的代码与标准库的代码合起来,就叫链接)
注:在成功编译之后,就进入了链接阶段(形成可执行程序,可执行的二进制程序=库+我的代码)。
实例: gcc hello.o –o hello
(5).快捷记忆:E S c形成的文件为i s o
(1).库的认识
C++标准库/C标准库
链接的本质:我们在调用库函数时,与标准库是怎样进行关联的。
(2).动态链接库: 编译链接时,不把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。
(3).静态链接库:编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
(4).在较前的年代,由于网速限制(通常为kb/s),为减小软件大小,通常使用的是静态链接库。所以动态链接库的优缺点:1.文件体积小。2.文件执行时间较长。3.动态库(标准库)一旦更新,维护,文件将不能执行。静态链接库的优缺点:1.不受库升级或者被删除的影响。2.形成可执行程序大小将会很大。
(5).动态链接库的应用:以前的QQ做到大小为kb级别。
(6).动态链接还是静态链接的验证及查看
对可执行文件使用:file mytext.c,得到下图:
dynamically linked(uses shared libs):动态链接(使用共享库)。
再使用ldd mytext(ldd指令只适用与动态链接的库),得到下图:
在linux下库的命名:
动态库:libxxxxxx.so
静态库:libxxxxxx.a
去掉lib前缀和.so/.a,剩下的就是共享库的名字。
libc.so.6:为c标准库。
使用:ls libc.so.6 -l查看c标准库
我们得知:linux下默认形成可执行程序,使用的是动态库。linux下:libc-2.17.so标准c的动态库windows下:是.dll文件
如果要使用静态链接,在对文件进行编译阶段,写入static。linux下:lib64/libc.a标准c的静态库windows下:是.lib文件
mytext.s是静态链接的,mytext是动态链接的,他们的大小一个是861288字节、一个是8360字节
一般而言:系统会自动携带动态库(为什么?);静态库如果不存在,需要自己安装(安装指令:sudo yum install glibc -static)
makefile是一个文件,make是一个指令,用于对makefile文件进行自动化生成可执行程序。他类似于windows下的vs系列IDE。
他是由依赖关系+依赖方法组成的。基本形式如下:在makefile文件里面
mycode:mycode.c // 依赖关系
gcc mycode.c -o mycode //依赖方法
mycode是待生成文件,他要生成依赖于mycode.c(依赖关系)。mycode是由mycode.c编译生成的(依赖方法)。另外要注意:第二行依赖方法必须要以tab开头。
clean:依赖关系为无,因为是清理,所以不需要任何依赖文件。他的用法如下:。
mycode:text.c
gcc text.c -o mycode
.PHONY:clean
clean:
rm -f mycode
创建好后就使用命令:make/make clean就可以了。
另外:.PHONY表示:被修改关键字修饰的对象是一个伪目标,该目标总是被执行。若目标文件不是伪目标是一个真是的文件,那么该文件只能被make一次;而改成.PHONY后,将会一直被执行。
'mycode' is up to date :mycode里面的数据是最新的(目标文件为mycode实体文件)
目标文件为伪目标文件,这样就可以一直编译
这里又有个疑问就是:当目标文件为实体文件时,gcc是如何得知,该文件不需要再次编译了呢?
这里对目标文件和源文件分别执行stat指令,得到如下结果:
通过对三个时间(Access(代表该文件被访问时的时间:由于一个文件被访问的频率较高,且不被太多重视,因此新内核将其修改为一段时间内再改变)、Modify(代表该文件内容被修改的时间)、Change(代表该文件属性被修改的时间))的分析得知:只要源文件的modify时间比目标文件的modify时间要长(意味着源文件内容被修改,那么目标文件也要跟着修改),就可以使用make编译成功。否则不成功。
对文件属性(权限+内容)修改,引起了change的变化,所以change代表文件属性被修改的时间
依赖关系链:
行缓冲区的概念:
给出如下代码:
这个代码存在间隔一段时间后再显示出you can see me.......的字符。这里的原因涉及到缓冲区的概念
要做到立刻刷新有两个办法;字符串后面加\n(回车换行:是由\r(回车回到当前行的首)\n(换行不会回到下一行的首)组成的,语言层面变成了\n),使用函数fflush(stdout);显示器能显示各种符号的原理:点亮屏幕上的需要亮的像素点。
linux下多文件操作:多文件操作模式:由一个或者多个头文件、一个或者多个源文件组成的
重定向操作:在一个没有文件的目录下,创建一个x文件,使用ls > makefile命令可以创建名叫makefile的文件,并把x文件名与makefile文件名写入到makefile中。
文件重命名:mv 源文件名 目标文件名;这样就将源文件的名字改成了目标文件的名字。
多文件下不同文件之间的相互切换:ctrl+ww。
多文件下makefile写法:依赖关系:待生成文件:源文件.c空格源文件.c。依赖方法:gcc 待生成文件 源文件.c空格源文件.c。另外只要头文件与源文件在同一个路径下,不用写在makefile里面。头文件搜索有两种方法:当前路径与库路径。
生成多个可执行文件:
整体替换:使用%s/mybin/myshell/g,用myshell全部替换掉mybin。
改变刷新频率:函数usleep(useconds usec); usec的单位是以微妙microsecond百万分之一秒的。
c语言的颜色控制:printf("\033[字背景颜色;字体颜色m字符串\033[0m" );
printf("\033[47;31mhello world\033[5m");
47是字背景颜色, 31是字体的颜色, hello world是字符串. 后面的\033[5m是控制码
字背景颜色范围: 40--49 字颜色: 30--39
40: 黑 30: 黑
41: 红 31: 红
42: 绿 32: 绿
43: 黄 33: 黄
44: 蓝 34: 蓝
45: 紫 35: 紫
46: 深绿 36: 深绿
47: 白色 37: 白色
其他的控制码:
\033[0m 关闭所有属性
\033[1m 设置高亮度
\03[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m -- \033[37m 设置前景色
\033[40m -- \033[47m 设置背景色
\033[nA 光标上移n行
\03[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[y;xH设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\033[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标
\33[?25h 显示光标
版本控制器:
gcc的默认行为:1.默认是动态链接的;2.默认是release。
要用gdb调试就要用release变为debug模式:在makefile里面:依赖方法的最后加一个-g。release版通常提供给用户,debug版通常是程序员的调试版。
readelf -S mytext_g:查看二进制区域
gdb调试命令:
l 选项:l 0:从0行开始显示代码,然后再按回车就能一直显示了
断点设置:b(或者breakpoint或者break) 24(代码行号)-形成断点编号;查看所有的断点:infor b;删除断点:d Num(断点编号)
调试运行:r /f5 开始运行到main函数里面的第一行。
逐过程:n 不进入函数
逐语句:s 进入函数
从一个断点到下一个断点:c
调用堆栈:bt
只把一个函数跑完:finish
追踪某个变量的值:display 变量名,例如循环变量。
取消先前设置对那些变量的追踪:undisplay Num(Num是变量之前的数字)
跳转至有效代码的(空行不计算)行号:until Num
禁用断点:disable breakpoints 1
开启断点:enable 2