热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Linux】Linux编程基础(vi、gcc、gdb)

编写一个程序,首先是程序的录入,然后是程序的编译,最后是程序的调试。本文介绍进行这三步工作的主要工具:vi、gcc、gdb。编辑器介绍Linux提供了一个完整的编辑器家族系列。按

编写一个程序,首先是程序的录入,然后是程序的编译,最后是程序的调试。本文介绍进行这三步工作的主要工具:vi、gcc、gdb。


编辑器介绍

Linux提供了一个完整的编辑器家族系列。按功能可以分为两大类:行编辑器(Ed、Ex)和全屏幕编辑器(vi、Emacs)。行编辑器每次只能队一行进行操作,而全屏幕编辑器可以对整个屏幕进行编辑。

vi介绍

vi是全屏幕编辑器中的一种,它有三种模式,分别为命令行模式、插入模式、底行模式。

  • 命令行模式:在使用vi编辑器编辑文件时,最初进入的是一般命令行模式。在该模式下,用户可以通过上下移动光标进行删除字符或整行删除等操作,也可以进行复制、粘贴等操作,但无法编辑文字;
  • 插入模式:在该模式下,用户才能进行文字的编辑输入,可以通过ESC键回到命令行模式;
  • 底行模式:在该模式下,光标位于屏幕的底行。用户可以进行文件保存或退出操作,也可以设置编辑环境,例如寻找字符串、列出行号等。

vi的各模式功能键

命令行模式下的常见功能键:

vi命令行模式功能键
功能键 含义
i 切换到插入模式,此时光标位于开始输入文件处
a 切换到插入模式,并从目前光标所在位置的下一个位置开始输入文字
O 切换到插入模式,且从行首开始插入新的一行
Ctrl+b 屏幕往后翻动一页
Ctrl+f 屏幕往前翻动一页
Ctrl+u 屏幕往后翻动半页
Ctrl+d 屏幕往前翻动半页
0 光标移到本行的开头
G 光标移动到输入文件的最后
nG 光标移动到第n行
$ 光标移动到所在行的“行尾”
n 光标向下移动n行
/name 光标之后查找name的字符串
?name 光标之前查找name的字符串
x 删除光标所在位置的“后面”一个字符
dd 删除光标所在行
ndd 从光标所在行开始往下删除n行
yy 赋值光标所在行
nyy 赋值光标所在行开始的下面n行
p 将缓冲区内的字符粘贴到光标所在的位置
u 恢复之前的一个动作

插入模式下的功能键只有1个,按ESC键返回命令行模式。

在命令行模式下,按“Shift+:”进入底行模式。底行模式下常见功能键:

底行模式下常见功能键
功能键 含义
:w 将编辑的文件保存在磁盘中
:q 退出vi(系统对修改过的文件给出保存提示)
:q! 强制退出vi(不给提示)
:wq 存盘后退出
:w[filename] 另存一个名为filename的文件
:set nu 显示行号
:set nonu 取消行号显示

其实经过试验,在命令行模式下,就不要用鼠标,所有的东西都通过命令来完成。如果不是vi命令行模式下的功能键,会使vi进入到插入模式。


程序编译与调试

嵌入式系统开发常用的编译工具是gcc,调试工具是gdb,下面一一介绍。

gcc是GNU项目中符合ANSIC标准的编译工具,能够编译由C、C++和Object C等语言编写的程序。gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合嵌入式领域的开发编译。

下表示gcc支持编译的源文件的后缀名及其解释:

gcc支持编译的源文件的后缀名及其解释
后缀名 对应语言 后缀名 对应语言
.c C源程序 .s/.S 汇编语言源程序
.C/.cc/.cxx C++源程序 .h 预处理文件
.m Object-C源程序 .o 目标文件
.i 经过预处理的C源程序 .a/.so 编译后的库文件
.ii 经过预处理的C++源程序    

gcc编译流程

gcc的编译流程分为四个步骤:预处理->编译->汇编->链接。

  • 预处理阶段:编译器将.c代码的stdio.h编译进来,并且用户可以使用gcc的选项“-E”进行查看,该选项的作用是让gcc在预处理结束后停止编译过程;
  • 编译阶段:在编译阶段中,gcc首先要检查代码的规范性以及是否有语法错误等,已确定代码实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。用户可以使用“-S”选项进行查看,该选项只进行编译而不进行汇编,生成汇编代码;
  • 汇编阶段:汇编阶段是把编译阶段生成的“.s”文件转换成目标文件,用户可使用选项“-c”查看汇编代码转化的后缀名为“.o”的二进制目标代码;
  • 链接阶段:编译成功后,就进入了链接阶段。库函数一般分为静态库和动态库两种。

静态库和动态库的区别:

  • 静态库在编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时就再也不需要库文件了,其后缀名一般为“.a”;
  • 动态库在编译链接时并没有把库函数的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销,动态库的后缀名一般为“.so”。

gcc在编译时,默认使用动态库。

gcc编译选项分析

gcc有100多个可用选项,主要包括总体选项、告警和出错选项、优化选项和系统结构相关选项。下面对每一类中最常用的选项进行介绍。

gcc总体选项
后缀名 对于的语言
-c 只编译不链接,生成目标文件“.o”
-S 只编译不汇编,生成汇编代码
-E 只进行预编译,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 将文件输出到file里
-v 打印编译器内部各编译过程的命令行信息
-I dir 在头文件的搜索路径列表中添加dir目录
-L dir 在库函数的搜索路径列表中添加dir目录
-static 链接静态库
-l library 链接名为library的库文件
gcc告警和出错选项
选项 含义
-ansi 支持符合ANSI标准的C程序
-pedantic 允许发出ANSIC标准所列的全部告警信息
-pedantic-error 允许发出ANSIC标准所列的全部错误信息
-w 关闭所有告警
-Wall 允许发出gcc提供的所有有用的报警信息
-werror 把所有的告警信息转换为错误信息,并在告警发生时终止编译过程

gcc可以对代码进行优化,它通过编译选项“-On”控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的gcc,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是0-2或0-3。

不同的优化级别对应不同的优化处理工作。例如:优化选项“-O1”主要进行线程跳转和延迟退栈两种优化;优化选项“-O2”除了完成所有的“-O1”级别的优化之外,还要进行一些额外的调整工作,例如处理器指令调度等;优化选项“-O3”则还包括循环开展和其他一些与处理器特性相关的优化工作。

gcc体系结构相关选项
选项 含义
-mieee-fp/-mno-ieee-fp 使用/不使用IEEE标准进行浮点数的比较
-msoft-float 输出包含浮点库调用的目标代码
-mshort 将int类型作为16位处理,相当于short int
-mrtd 强行将函数参数固定的函数用ret NUM返回,节省调用函数的一条指令
-mcpu=type 针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium、i686等

gcc指令的一般格式为:

gcc [选项] 要编译的文件 [选项] [目标文件]

例如:

gcc hello.c -o hello                        //将hello.c生成可执行文件(链接动态库)
gcc -static hello.c -o hello                 //将hello.c生成可执行文件(链接静态库)
gcc -E hello.c -o hello.i                    //将hello.c只进行预处理,不做其他处理
gcc -S hello.i -o hello.s                    //将hello.i只编译不汇编,生成汇编代码
gcc -c hello.s -o hello.o                    //将hello.s只编译不链接
gcc hello.o -o hello                        //将hello.o链接到函数库,生成可执行文件
[root@localhost ~]# ./filename                //执行可执行文件filename
[root@localhost ~]# cat filename                //将文件filename内容输出到标准输出设备(屏幕)上

这里区分一些gcc和g++:

gcc和g++都是GNU(一个组织)的编译器。

  • 对于.c后缀的文件,gcc把它当做是C程序,g++当做是C++程序;
  • 对于.cpp后缀的文件,gcc和g++都会当做c++程序;
  • 编译阶段,g++会调用gcc(也就是说);
  • 连接阶段,通常会用g++来完成,这是因为gcc命令不能自动和c++程序使用的库连接。

也就是说:

  • gcc可以用来编译c++但是它不会自动调用链接的c++库,需要自己手动链接,使用如下命令: gcc -lstdc++ main.cpp;g++则会自动调用链接的c++库,使用的也是gcc命令。但是gcc在编译c程序的时候,它会自动链接c库的。
  • gcc可以根据后缀名为.c或.cpp分别按c程序和c++程序来编译;但是g++无论是.c或.cpp都统一按c++程序来编译。而且g++在编译的过程中,其实是调用gcc按照c++程序来编译的。即编译工作最终都是由gcc来完成的。

gdb程序调试

gdb作为GNU开发组织发布的一个UNIX/LINUX下的程序调试工具,提供了强大的调试功能。

由于gdb的目录很复杂,所以就先留个空,以后学习的时候来补。


推荐阅读
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • Java Web开发中的JSP:三大指令、九大隐式对象与动作标签详解
    在Java Web开发中,JSP(Java Server Pages)是一种重要的技术,用于构建动态网页。本文详细介绍了JSP的三大指令、九大隐式对象以及动作标签。三大指令包括页面指令、包含指令和标签库指令,它们分别用于设置页面属性、引入其他文件和定义自定义标签。九大隐式对象则涵盖了请求、响应、会话、应用上下文等关键组件,为开发者提供了便捷的操作接口。动作标签则通过预定义的动作来简化页面逻辑,提高开发效率。这些内容对于理解和掌握JSP技术具有重要意义。 ... [详细]
  • 本文详细探讨了OpenCV中人脸检测算法的实现原理与代码结构。通过分析核心函数和关键步骤,揭示了OpenCV如何高效地进行人脸检测。文章不仅提供了代码示例,还深入解释了算法背后的数学模型和优化技巧,为开发者提供了全面的理解和实用的参考。 ... [详细]
  • Java集合框架特性详解与开发实践笔记
    Java集合框架特性详解与开发实践笔记 ... [详细]
  • GDB 使用心得与技巧总结
    在使用 GDB 进行调试时,可以采用以下技巧提升效率:1. 通过设置 `set print pretty on` 来美化打印输出,使数据结构更加易读;2. 掌握常见数据结构的打印方法,如链表、树等;3. 利用 `info locals` 命令查看当前作用域内的所有局部变量;4. 在需要进行类型强制转换时,正确使用语法,例如 `p (Test::A *) pObj`。这些技巧能够显著提高调试的便捷性和准确性。 ... [详细]
  • 深入解析 ELF 文件格式与静态链接技术
    本文详细探讨了ELF文件格式及其在静态链接过程中的应用。在C/C++代码转化为可执行文件的过程中,需经过预处理、编译、汇编和链接等关键步骤。最终生成的可执行文件不仅包含系统可识别的机器码,还遵循了严格的文件结构规范,以确保其在操作系统中的正确加载和执行。 ... [详细]
  • 本文详细探讨了Java集合框架的使用方法及其性能特点。首先,通过关系图展示了集合接口之间的层次结构,如`Collection`接口作为对象集合的基础,其下分为`List`、`Set`和`Queue`等子接口。其中,`List`接口支持按插入顺序保存元素且允许重复,而`Set`接口则确保元素唯一性。此外,文章还深入分析了不同集合类在实际应用中的性能表现,为开发者选择合适的集合类型提供了参考依据。 ... [详细]
  • 本文详细介绍了在DS-5开发工作室中集成最新编译器工具链的方法与步骤。通过逐步指导,帮助用户高效地配置和使用最新的编译器,以提升开发效率和代码质量。此外,还提供了常见问题的解决方案和最佳实践建议,确保用户能够顺利进行开发环境的升级。 ... [详细]
  • 在Java编程中,为了提高代码的可读性和执行效率,建议优先使用局部变量来存储方法的返回值,而不是多次调用同一个方法。这样不仅可以减少方法调用的开销,还能避免潜在的性能问题。此外,使用局部变量还可以增强代码的可维护性和调试便利性。 ... [详细]
  • 本书详细介绍了在最新Linux 4.0内核环境下进行Java与Linux设备驱动开发的全面指南。内容涵盖设备驱动的基本概念、开发环境的搭建、操作系统对设备驱动的影响以及具体开发步骤和技巧。通过丰富的实例和深入的技术解析,帮助读者掌握设备驱动开发的核心技术和最佳实践。 ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • Spring Boot 实战(一):基础的CRUD操作详解
    在《Spring Boot 实战(一)》中,详细介绍了基础的CRUD操作,涵盖创建、读取、更新和删除等核心功能,适合初学者快速掌握Spring Boot框架的应用开发技巧。 ... [详细]
  • 在《PHP应用性能优化实战指南:从理论到实践的全面解析》一文中,作者分享了一次实际的PHP应用优化经验。文章回顾了先前进行的一次优化项目,指出即使系统运行时间较长后出现的各种问题和性能瓶颈,通过采用一些通用的优化策略仍然能够有效解决。文中不仅详细阐述了优化的具体步骤和方法,还结合实例分析了优化前后的性能对比,为读者提供了宝贵的参考和借鉴。 ... [详细]
  • 开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用
    开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用 ... [详细]
  • ESP32 IRAM 内存优化策略与实践总结
    本文总结了针对ESP32 IRAM内存溢出问题的优化策略与实践经验。通过详细分析ESP32的内存结构和IRAM分配机制,提出了一系列有效的解决方案,包括代码优化、内存管理技巧和编译器配置调整,旨在帮助开发者有效解决`.espressif/tools/xtensa-esp32-elf/esp-2`等类似错误,提升系统性能和稳定性。 ... [详细]
author-avatar
北海盗羽翼800
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有