当前位置: 首页 > web >正文

4.基础开发工具

一、Linux中安装软件

1)源码安装

2)软件包安装---rpm

3)包管理器yum(centos)  apt/aptget(ubuntu)

a.网络下载

b.安装(就是拷贝)必须使用root权限

安装到系统里,只安装一次,任何人都能使用。

包管理器会自动给我们解决包的依赖问题。

什么是包管理器?

类似手机上的应用商店。

软件是由谁提供的?

理解过程:操作系统背后的配套软件,也是生态的一环。

我的机器怎么知道下载链接?

操作系统内部,内置链接,由于原因,国内有镜像源。

base---稳定软件

epel---扩展软件源

开源本质是一种商业模式。

修改yum源

/etc/yum.repos.d/*(yum源配置文件)

Cetnos 安装源路径:
-rw-r--r-- 1 root root 676 Oct 8 20:47 CentOS-Base.repo # 标准源
-rw-r--r-- 1 root root 230 Aug 27 10:31 epel.repo # 扩展源

yum install -y epel-realse(安装epel扩展软件源)

查看软件包
通过 yum list 命令可以罗列出当前⼀共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用grep命令只筛选出我们关注的包。
例如: yum list | grep lrzsz
卸载软件
yum remove [-y] lrzsz

二、编辑器vim

批量注释:首先从命令模式输入ctrl+v切换到V-BLOCK模式,使用hjkl进行选择,选择完后输入shitf+i=I进入插入模式,输入//,使用ESC切回V-BLOCK模式,可以看到选中行前面都加了//。

命令模式:快速编辑

快捷键:

定位

gg:快速回归光标

shift+g=G:快速把光标定位到结尾

n+shift+g = n+G:把光标定位到任意行

shift+$:定位到一行结尾

shift+^:定位到一行开头

n+hjkl:左下上右

w:以单词为单位向后移动

b:以单词为单位向前移动

编辑

n+yy:复制

n+p:粘贴

u:撤销历史操作(退出文件编辑无法进行撤销,但如果只是保存,没有退出还可以撤销)

ctrl+r:反撤销

n+dd:剪切当前行,或者删除

n+x:删除光标所在位置的字符

shift+x:光标右侧不动,左侧删除,也类似剪切。

r:替换光标所在字符,r->目标字符

nr:

shift+r=R:批量化替换

shift+~:大小写切换

底行模式

w/q/!,ZZ set nu/nonu

:!command 不退出vim情况下输入命令

:%s/dst/src/ 批量化替换

分屏操作

:vs new_src

ctrl+ww:切换光标位置

vim技巧

vim src+n 打开时定位到第n行。

三、Linux编译器---gcc/g++使用

gcc xxx.c -o xxx

1.预处理(宏替换,条件编译,去注释,头文件展开等)

gcc -E code.c -o code.i

-E表示进行程序翻译,在预处理完时停止

2.编译(生成汇编)

gcc -S code.i -o code.s

-S表示开始翻译,编译做完了,就停下来

3.汇编(生成机器可识别代码)

gcc -c code.s -o code.o

-c表示开始翻译,汇编完成就停下来。

code.o是可重定位目标文件,vs2022,xxx.obj

已经是二进制文件了,但不能直接运行。

4.链接(生成可执行文件或库文件)

gcc code.c -o code

库:

1.动态库:Linux(.so) Windows(.dll)

2.静态库:Linux(.a)  Windows(.lib)

理解预处理:

gcc code.c -o code -DM (命令行级的宏定义)

相当于#define M 100字符串插入到代码中。

预处理本质就是修改编辑我们的文本代码。

条件编译的用途:

1.社区版和专业版区分,使用条件编译进行代码动态裁剪。

2.内核源代码也是采用条件编译进行代码裁剪(例如嵌入式设备不需要联网就将网络部分裁剪)

3.多平台的开发工具、应用软件

为什么C/C++编译,要先变成汇编?

语言发展史:

开关

打孔编程(二进制编程)

汇编语言

C语言

C++/Java/Go/Python...

为什么要先变成汇编?

直接翻译成2进制,翻译代价太大了,C语言出来的时候,汇编语言已经发展得很成熟了,将C语言翻译成汇编(文本到文本),再由汇编翻译成2进制,翻译成本小。

编译器的自举过程:

第一个汇编语言编译器必须用2进制写,因为如果用汇编写没有对应汇编编译器编译汇编,产生了2进制的汇编语言编译器后,再用汇编语言写一个汇编编译器,用2进制的汇编编译器编译之后,就诞生了汇编语言写的汇编编译器,这个过程称为编译器的自举过程

因此,先有语言,然后才有该语言写的编译器。

什么叫做动态库,什么叫做动静态链接,如何理解?

库:

1.动态库:Linux(.so) Windows(.dll)

2.静态库:Linux(.a)  Windows(.lib)

库是一套方法或数据库,为我们开发提供最基本的保证(基本接口、功能,加速我们二次开发)。

libc.so    命名 lib+名称+.so*/.a*

libc.a

动态库:被多个程序共享,一旦缺失,会导致所以程序无法执行

静态库:只在链接时需要,运行时不需要。

动静态库对比:

1)动态库形成的可执行程序体积一定很小

2)可执行程序对静态库依赖小,动态库不能缺失

3)程序运行,需要加载到内存,静态链接的,会在内存中出现大量的重复代码

4)动态链接,比较节省内存和磁盘资源

ldd和file指令:

gcc code.c -o code-static -static(-static强制静态链接)

默认是动态链接

关于动态库:

重定向拷贝:cat srcfile > dstfile 

动态库本质:把语言层面公共的代码,在内存中未来只出现一份。

加载程序到内存时,相应的动态库也会被加载到内存中。

技术上理解库:

1.c->1.o

2.c->2.o

3.c->3.o

再链接o->exe。

库的本质是.o,但是为了防止丢失,打包成.so或.a。

本质上是被打包的.o文件。

链接本质,将.o进行合并。

四、自动化构建-make/Makefile(重点)

make是一个命令,makefile是一个文件

写成makefile/Makefile都可以。

实例:

code:code.c  (依赖关系)

        gcc -o code code.c  (依赖方法)

target: src1 src2 src3
    command

依赖关系中,target和src是一对多的关系

理解.PHONY以及不总被执行:

Access:最近访问时间,但由于查询是占文件操作的大部分,如果每一次查询都修改时间,那么就会导致每次都要修改访问时间,要进行一次IO操作,IO操作很消耗时间,要达到一定访问次数才更新时间,并非实时更新。

Modify:文件的内容变了,就要更新。

Change:文件属性变了,就更新。由于属性包括文件大小,时间。Modify了,即使文件大小不变,Modify时间变了,必然会影响文件属性,Change时间会更新。修改文件的权限也会更新Change时间。

文件=内容+属性

touch 已存在文件,更新三个时间

makefile的原理:

makefile技巧:

$()  //引用

加@  不打印makefile的内容

$@    最终目标

$^      最终目标依赖的众多文件列表

%.o:%.c 

把当前路径下的所有.o/.c依次展开,如果有100份,展成100份对应的依赖关系。

$< 将方法一个一个展开

1)SRC=${shell ls *.c}    获取当前目录下的所有.c文件

2)SRC=${wildcard *.c}

OBJ=${SRC:.c=.o}     SRC内部的文件名.c替换成同名.o

通用makefile:

#SRC=${shell ls *.c}                                                                                                             SRC=${wildcard *.c}
OBJ=${SRC:.c=.o} 
BIN=mycode$(BIN):$(OBJ)@gcc -o $@ $^@echo "linking ... $^ to $@"
%.o:%.c@gcc -c $<@echo "compling ... $< to $@"
.PHONY:
clean:@rm -rf $(BIN) $(OBJ)@echo "delete $(BIN) $(OBJ)"
.PHONY:
PRINT:@echo ${SRC}@echo ${OBJ}

进度条:

\r回车,回归光标

\n换行,换到下一行。

\r\n回车换行。

缓冲区理解:一段内存块。

所以要让不加\n的printf立即显示,要加fflush(stdout);刷新一下缓冲区。

进度条实现,版本1:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define flag '#'void progressBar1()
{char buff[101];memset(buff,0,101);static char s[] = "/-|\\";int cnt = 0;static int tmp = 0;while(cnt<=100){tmp %= 4;printf("[%-100s][%d%%][%c]\r",buff,cnt,s[tmp]);fflush(stdout);usleep(10000);++tmp;buff[cnt] = flag;++cnt;}printf("\n");
}

版本2:

#include <stdio.h>
#include <string.h>
#define flag '#'void progressBar2(double current,double total)
{char s[] = "/-|\\";char buff[101];memset(buff,0,101);int count = (int)((current/total)*100);for(int i = 0;i<count;++i){buff[i] = flag;}static int k = 0;k%=4;printf("[%-100s][%d%%][%c]\r",buff,count,s[k++]);fflush(stdout);
}
#include <stdio.h>
#include<unistd.h>
#include "progressBar2.h"double speed = 1.0;
double total = 1024.0;void Upload()
{printf("Upload begin...\n");double current = 0;while(current<=total){progressBar2(current,total);current+=speed;usleep(10000);}printf("\nCompleted total:%.1lf\n",total);
}int main()
{Upload();return 0;
}

 五、版本控制器Git

1.如何理解版本控制?->Git && gitee || github(基于git的网站或平台)

版本控制:将每个文件版本进行记录,管理起来。

git是一个客户端,也是一个服务器,底层的版本控制器软件。

目的:

1.数据安全

2.协作开发

git clone 克隆到本地仓库

.git 隐藏的本地仓库,包含历史修改记录。

git数据提交的时候,只会提交变化的部分。

git add   //添加文件到git暂存区

git comimit -m "xxx"  //提交到本地git仓库,带上日志信息

git push    //推送到远程仓库

git log    //查看日志

git pull   //拉取远程仓库,达到同步

注意:

1.首次使用设置登录名和主机名

2.git版本管理,只管理源文件.c/.cpp/.h

3.-gitignore:需要忽略的特定后缀的文件列表。

4.远程仓库,相比较于任何人,都是最新的。

为什么要冲突?

提醒本地用户,需要和远程仓库进行同步了。

六、调试器-gdb/cgdb使用

gcc/g++默认release模式

加上-g选项,让最后形成的可执行程序,加上调试信息。---debug模式

查看debug信息:readelf -S BIN | grep -i debug

gdb bin(可执行程序)

quit退出

list 简写l显示源代码

b+行号:打断点

b+文件名:行号

b+函数名

d+断点编号:删除断点

info b:查看断点信息

r:运行程序,从头开始

gdb不退出:断点编号依次递增。

next/n:逐过程

step/s:逐语句

bt:查看栈帧信息

finish:结束当前函数

p xxx:查看变量的值(表达式)

objdump -S mycode > mycode.s(反汇编)

断点可以被使能:

disable + 断点编号 禁用断点

enable + 断点编号 使用断点

调试的本质:

1.找到问题

2.查看代码上下文

断点的本质,把代码进行块级别的划分。

c:运行到下一个断点处

until+行号:将程序运行到指定行号(局部范围快速执行)

类似VS监视窗口:

display+变量 长期显示变量值

undisplay+显示编号 删除对应编号的长显示

注:变量生命周期结束,自动删除对应变量的长显示

info locals 查看当前函数的临时变量

调试技巧:

watch + 变量名 监视变量的变化,变化了就会打印提示信息(也是点信息,c也会跳转至对应改变这个变量的位置)

set vat + 变量名 = xxx 暂时更改变量名对应的值

条件断点:

b + 行号 if expression (常用于循环内部)

给已存在的断点设置条件:

condition + 断点编号 expression

ESC:进入代码屏,滚动代码

i:回到gdb屏

http://www.xdnf.cn/news/1147.html

相关文章:

  • stat判断路径
  • 【设计模式】深入解析代理模式(委托模式):代理模式思想、静态模式和动态模式定义与区别、静态代理模式代码实现
  • 基于PHP+MySQL实现(Web)单词助手网站
  • 基于javaweb的SSM+Maven教材管理系统设计与实现(源码+文档+部署讲解)
  • 深入理解 Java 中的 Classpath
  • 【Java面试笔记:基础】3.谈谈final、finally、 finalize有什么不同?
  • [Java] 泛型
  • Python 设计模式:享元模式
  • JVM虚拟机-类加载器、双亲委派模型、类装载的执行过程
  • 虚无隧穿产生宇宙(true nothing tunneling) 这个的真空是哪种
  • GitLab 提交权限校验脚本
  • 界面控件DevExpress WPF v25.1预览 - 支持Windows 11系统强调色
  • MuJoCo中的机器人状态获取
  • 第六篇:linux之解压缩、软件管理
  • Vue3集成sass
  • Unity 跳转资源商店,并打开特定应用
  • 滑动窗口学习
  • 【HTTPS协议原理】数据加密、如何防止中间人攻击、证书和签名、HTTPS完整工作流程
  • UnityDots学习(四)
  • 关于RPC
  • 图数据库nebula测试指南
  • 在 NVIDIA Orin (JetPack 6.0) 上安装 PyTorch 2.4 + Torchvision 0.19
  • 每日算法-250422
  • 几种Word转换PDF的常用方法
  • 如何在idea里创建注释模版
  • 真我推出首款 AI 翻译耳机,支持 32 种语言翻译
  • 拥抱健康生活,开启养生之旅
  • Android Jetpack Compose基础实践
  • iscsi服务端安装及配置
  • 【Python爬虫基础篇】--3.cookie和session