一、软件包管理器

1、Linux下安装软件的常见方式:

        1)源代码安装——不推荐。

        2)rpm包安装——不推荐。

        3)包管理器安装——推荐

2、安装软件命令

 # Centos$ sudo yum install -y lrzsz# Ubuntu$ sudo apt install -y lrzsz

3、卸载软件命令

 # Centossudo yum remove [-y] lrzsz# Ubuntusudo apt remove [-y] lrzsz

        任何评估一款操作系统的好坏?操作系统被设计出来之后,最重要的事情是什么?

        答:操作系统形成使用圈子就会被更多的人使用,为了让更多的人使用就必须让圈子更完善;有人愿意在特定的os上编写特定的软件适应不同的群体,并且在各种圈子完善社区、文档、论坛、资料。

二、编辑器 Vim

         IDE在Linux下的开发工具是独立的!写代码——编辑器vim,编译代码——gcc/g++,调试——gdb/cgbd,构建工具——makefile/make/cmake。

        进入vim的指令:vim + 文件。进入vim之后要写内容按键盘 i 键。

        vimd的多模式:命令模式、插入模式、底行模式。

        底行模式:set nu,是给内容加上行号,如:

 注意:如果想去掉行号在底行模式输入:nonu。

命令模式下:

        shift+g:光标进入文本末端。

        gg:光标进入文本的开始。

        n+shift+g:光标进入来到文本n行。

        shift+4:光标进入到当前行的末尾。

        shift+6:光标来到当前行的开始。

        h:光标往左移动。

        j:光标往下移动。

        k:光标往上移动。

        l:光标往右移动。

        w:按照单词向右移动。注意:可以加上数字。

        b:按照单词向左移动。注意:可以加上数字。

        yy:复制当前行的内容。n+yy复制前n行内容。

        p:粘贴。n+p可以粘贴n次。

        dd:删除当前行。n+dd删除前n行内容。

        u:撤销操作。

        ctrl+r:对u的撤销。

注意:任意模式下都可以进行撤销操作,退出vim就不能撤销了。

        shift+~:对光标的字母进行大小写切换。

        r:替换光标所在位置的一个字符,n+r替换n个字符。

        shift+r:进入替换模式,忽视原来文本内容,可重新编写。注意:进入替换模式之后要退出来就要按Esc键。

        x:删除光标所在字符,向右删除。

        shift+x:向左删除光标所在字符。

        批量化注释:①ctrl+v,②hjkl选择区域,③shift+i,④//,⑤Esc。

        批量化去注释:①ctrl+v,②hjkl选择区域,③d,④Esc。

底行模式下:

        w!:保存。

        q!:退出。

        wq!:强制保存并退出。

注意:如果vim打开文件,突然终端退出,vim会形成临时文件,默认在当前路径的下一个.swp临时ls -al。

        :/key+n:匹配搜索。

        :!cmp:不退出vim,直接对代码进行编译运行。

        :%s/dst/src/g:把文本内容所有的dst替换成src。

        :vs:分屏操作。ctrl+www,选中哪一个分屏。

注意:当vim退出光标在第n行,再次打开光标还在原来位置。那么我们Linux下可输入vim +文件名+n,直接进入到第n行。在命令模式下退出vim操作:shift+zz。

配置炫酷的vim:

        要配置炫酷的vim,原生的配置可能功能不全,可以选择安装插件来完善配置,保证用户是你要配置的用户,接下来:

        ①安装TagList插件,下载taglist_xx.zip,解压完成,将解压出来的doc的内容放到~/.vim/doc,将解压出来的plugin下的内容拷贝到~/.vim/plugin。

        ②在~/.vimrc中添加:let Tlist_Show_One_File=1 letTlist_Exit_OnlyWindow=1 let Tlist_Use_Right_Window=1

        ③安装文件浏览器和窗口管理器插件:WinManager

        ④下载winmanager.zip,2.X版本以上的

        ⑤解压winmanager.zip,将解压出来的doc的内容放到~/.vim/doc,将解压出来的plugin下的内容拷贝到~/.xim/plugin

        ⑥在~/.vimrc中添加 let g:winManagerwindowLayout=‘FileExplorer|TagListnmap wm :WMToggle<cr>

        ⑦然后重启vim,打开~/XXX.c或~/XXX.cpp,在normal状态下输入"wm",你将看到上图的效果。更具体移步:手把手教你把Vim改装成一个IDE编程环境(图文)_vim 打造成 ide-CSDN博客,其他手册,请执行vimtutor 命令。

三、让普通用户暂时提权的方法

        1、进入到root界面

        2、指令:ls /etc/sudoers,查看sudoer是否存在。

        3、指令:vim /etc/sudoers,进入sudoers

        4、yy接着p一下

四、g++/gcc

1)区别

        gcc:C编译器。只能用来进行编译C语言。

        g++:C++/C语言编译器。

2)四步生成可执行文件

        预处理(头文件展开,去注释,宏替换,条件编译):指令:gcc 文件名 -o 编译后行的文件名(可自己写)。由于gcc是一步到位(直接形成可执行文件),所以可以这么做:gcc -E 文件名 -o 预处理之后的文件名.i;

        编译:把C语言变成汇编语言,指令:gcc -S 文件名.i -o 文件名.s

        汇编:把汇编语言翻译成二进制文件,指令:gcc -c 文件名.s -o 文件名.o

        链接:把二进制文件形成可执行文件,指令:gcc 文件名.o -o 文件名.exe

补充知识:为什么要把C语言翻译成汇编?

答:翻译语言的本质是转成CPU能够识别的指令集;汇编语言是用字母来对二进制指令进行包装;

先有汇编语言还是先有用汇编语言写的汇编编译器?

答:先拿二进制写出一个汇编编译器,再写出汇编语言,然后在拿汇编语言完善汇编编译器,最后再用汇编语言编写软件(如C语言编译器),最终再拿C语言编译器来写汇编编译器(编译器自举),所以先有语言。

.o二进制文件能不能直接运行?

答:不能,原因:如果运行.o文件他会报出错误:可重定位目标二进制文件,因为我们用到的库方法,只有说明,没有定义。

注意:在Linux中静态库是以.a为后缀,动态库是以.so为后缀;window的静态库是以.lib为后缀,动态库是以.dll为后缀。        

动态链接优点:节省内存空间;缺点:慢,编译完成依旧依赖动态库;静态库的优点:不需要库跳转,一旦编译完成不依赖库;缺点:可执行程序体积较大(把库实现的方法拷贝到程序里面),消耗内存资源。

注意:gcc默认编译是采用动态链接的方式完成,如果想要强制进行静态链接可以输入指令:gcc 文件名 -o 文件名 -static。

3)静态库和动态库

        静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”

        动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的libc.so.6就是动态库。

        gcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件,如下所示。gcc hello.o-o hellogcc默认生成的二进制程序,是动态链接的,这点可以通过file 命令验证。

五、自动化项目的构建(生成可执行文件)——make/Makefile

1)背景

        会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

        一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

        makefile带来的好处就是—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

        make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

        make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2)make/Makefile的执行原理

        make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

        如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到myproc 这个文件,并把这个文件作为最终的目标文件。

        如果myproc文件不存在,或是myproc所依赖的后面的myproc.o文件的文件修改时间要比 myproc 这个文件新(可以用touch 测试),那么,他就会执行后面所定义的命令来生成myproc这个文件。

        如果myproc 所依赖的myproc.o文件不存在,那么make 会在当前文件中找目标为myproc.o文件的依赖性,如果找到则再根据那一个规则生成myproc.o文件。(这有点像一个堆栈的过程)

        当然,你的C文件和H文件是存在的啦,于是 make 会生成 myproc.o 文件,然后再用myproc.o文件声明make的终极任务,也就是执行文件 hello了。

        这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

        在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

注意:gcc无法二次编译老代码的原因:源代码的时间比可执行文件的要旧,如果修改源代码那么的他的时间就会比可执行文件新,这时候就可以进行二次编译。修改一个文件的时间可以使用touch 一个已经存在的源文件,这时候就可以进行二次编译。

结论:判断文件新旧是根据文件的Mod时间来判定;.PHONY为什么总是被执行的?原因:就是让gcc或者对应的命令忽略Mod时间对比新旧。

注意:Modify是文件内容被修改的时间,change 是文件属性被修改的时间;只要修改文件的内容Mod和change的时间也会被修改,原因:修改文件内容会影响文件大小,包括Mod时间也是属性。Access是文件最近被访问的时间,查看文件会跟新时间,相当于修改文件属性,这时Linux就会刷新到磁盘,因为查看文件次数较多所以会增加磁盘的访问次数,外设效率低下,导致os整体效率降低,故而访问文件内容达到特定次数之后,才会更新一次时间。

 知识点补充:

使用 wildcard 函数,获取当前所有.c文件名OBJ=$(SRC:.C=.0)//将SRC的所有同名.c替换成为.o形成目标文件列表$@:代表目标文件名。$^:代表依赖文件列表%.c展开当前目录下所有的.c。%.o:同时展开同%<:对展开的依赖.c文件,一个一个的交给gcc。@:不回显命令S(RM)·替换,用变量内容替换它

注意: 

 SRC=$(wildcard *.cc) #wildcard是make的一个函数,用来匹配文件名
#*.cc就是wildcard函数的参数
#用法$(wildcard pattern)  参数 pattern 是一个文件名通配符模式
#文件名通配符模式是一种使用特殊字符来匹配一组文件名的语法
#特殊字符*表示匹配任意数量的字符(包括零个)
OBJ=$(SRC:.cc=.o)
这是 Makefile 中的 变量替换(模式替换) 语法,格式如下:
$(变量名:模式=替换)
它的意思是:把“变量名”中所有 符合“模式” 的部分,替换为“替换”。

 六、进度条原理和设计

main.c

#include "process.h"
#include <unistd.h>
#include <time.h>
#include <stdlib.h>double gtotal = 1024.0;
double speed = 1.0;// 函数指针类型
typedef void (*callback_t)(double, double);// 1.0 4.3
double SpeedFloat(double start, double range) // [1.0 3.0] -> [1.0, 4.0]
{int int_range = (int)range;return start + rand()%int_range + (range - int_range);
}// cb: 回调函数
void DownLoad(int total, callback_t cb)
{srand(time(NULL));double curr = 0.0;while(1){if(curr > total){curr = total; // 模拟下载完成cb(total, curr); // 更新进度, 按照下载进度,进行更新进度条break;}cb(total, curr); // 更新进度, 按照下载进度,进行更新进度条curr += SpeedFloat(speed, 20.3);  // 模拟下载行为usleep(30000);}
}int main()
{printf("download: 20.0MB\n");DownLoad(20.0, FlushProcess);printf("download: 2000.0MB\n");DownLoad(2000.0, FlushProcess);printf("download: 100.0MB\n");DownLoad(100.0, FlushProcess);printf("download: 20000.0MB\n");DownLoad(20000.0, FlushProcess);return 0;
}

process.c

#include "process.h"
#include <string.h>
#include <unistd.h>#define SIZE 101
#define STYLE '='void FlushProcess(double total, double curr) // 更新进度, 按照下载进度,进行更新进度条
{if(curr > total)curr = total;double rate = curr / total * 100; // 1024.0 , 512.0 -> 0.5 -> 50.0int cnt = (int)rate; // 50.8 , 49.9 -> 50, 49char processbuff[SIZE];memset(processbuff, '\0', sizeof(processbuff));int i = 0;for(; i < cnt; i++)processbuff[i] = STYLE;static const char *lable = "|/-\\";static int index = 0;// 刷新printf("[%-100s][%.1lf%%][%c]\r", processbuff, rate, lable[index++]);index %= strlen(lable);fflush(stdout);if(curr >= total){printf("\n");}
}// version1: 能够使用吗??
// 说明原理
void Process()
{const char *lable = "|/-\\";int len = strlen(lable);char processbuff[SIZE];memset(processbuff, '\0', sizeof(processbuff));int cnt = 0;while(cnt <= 100){printf("[%-100s] [%d%%][%c]\r", processbuff, cnt, lable[cnt%len]);fflush(stdout);processbuff[cnt++] = STYLE;usleep(30000);}printf("\n");
}

process.h

#pragma once#include <stdio.h>// version1
void Process();
void FlushProcess(double total, double curr); // 更新进度, 按照下载进度,进行更新进度条

完!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917913.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917913.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917913.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot Actuator 监控功能的简介及禁用

Spring Boot Actuator: Production-ready Features 1. 添加依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> </dependencie…

Matlab(1)

一、基本操作1. matlab四则运算规则&#xff1a;先乘除后加减&#xff0c;从左到右2、对数和指数的表示sin(pi^0.5)log(tan(1))exp&#xff08;sin&#xff08;10&#xff09;&#xff09;3、类型&#xff1a;matlab变量默认为double4、who&whos&#xff1a;命令行输入who&…

Kotlin Android 开发脚手架封装

Kotlin Android 开发脚手架封装&#xff08;模块化版本&#xff09; 我将按照模块化设计原则&#xff0c;将脚手架拆分为多个文件&#xff0c;每个文件负责特定功能领域&#xff1a; 1. 核心初始化模块 文件路径: core/AppScaffold.kt object AppScaffold {lateinit var contex…

Flutter 报错解析:No TabController for TabBar 的完整解决方案

目录 Flutter 报错解析&#xff1a;No TabController for TabBar 的完整解决方案 一、错误场景&#xff1a;当 TabBar 失去 "指挥官" 二、为什么 TabBar 必须依赖 Controller&#xff1f; 1. TabBar 与 TabController 的协作关系 2. 状态管理的核心作用 3. 实战…

【24】C++实战篇——【 C++ 外部变量】 C++多个文件共用一个枚举变量,外部变量 extern,枚举外部变量 enum

文章目录1 方法2 外部变量 应用2.1 普通外部全局变量2.2 枚举外部全局变量 应用2.2.2 枚举外部变量优化c多个文件中如何共用一个全局变量 c头文件的使用和多个文件中如何共用一个全局变量 C共享枚举类型给QML 1 方法 ①头文件中 声明外部全局变量&#xff1b; ②在头文件对…

Linux SELinux 核心概念与管理

Linux SELinux 核心概念与管理一、SELinux 基本概念 SELinux 即安全增强型 Linux&#xff08;Security-Enhanced Linux&#xff09;&#xff0c;由美国国家安全局&#xff08;NSA&#xff09;开发&#xff0c;是一套基于强制访问控制&#xff08;MAC&#xff09;的安全机制&…

Git 中**未暂存**和**未跟踪**的区别:

文件状态分类 Git 中的文件有以下几种状态&#xff1a; 工作区文件状态&#xff1a; ├── 未跟踪 (Untracked) ├── 已跟踪 (Tracked)├── 未修改 (Unmodified) ├── 已修改未暂存 (Modified/Unstaged)└── 已暂存 (Staged)1. 未跟踪 (Untracked) 定义&#xff1a;Gi…

前端1.0

目录 一、 什么是前端 二、 HTML 1.0 概述 2.0 注释 三、开发环境的搭建 1.0 插件 2.0 笔记 四、 常见标签&#xff08;重点&#xff09; 四、案例展示&#xff08;图片代码&#xff09; 五、CSS引入 一、 什么是前端 web前端 用来直接给用户呈现一个一个的网页 …

Flutter镜像替换

一、核心镜像替换&#xff08;针对 Maven 仓库&#xff09; Flutter 依赖的 Google Maven 仓库&#xff08;https://maven.google.com 或 https://dl.google.com/dl/android/maven2&#xff09;可替换为国内镜像&#xff0c;常见的有&#xff1a;阿里云镜像&#xff08;推荐&am…

MATLAB实现的改进遗传算法用于有约束优化问题

基于MATLAB实现的改进遗传算法&#xff08;GA&#xff09;用于有约束优化问题的代码&#xff0c;包括处理非线性约束。此代码通过引入惩罚函数和修复机制&#xff0c;有效处理约束条件&#xff0c;提高算法的鲁棒性和收敛速度。 1. 定义优化问题 % 定义目标函数 function f ob…

Qt子类化QWidget后,使用setStyleSheet设置样式无效的解决方案

关键代码&#xff1a; #include <QPainter> #include <QStyleOption>void paintEvent(QPaintEvent *e) {QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);QWidget::paintEvent(e); }定义…

【python中级】关于Flask服务在同一系统里如何只被运行一次

【python中级】关于Flask服务在同一系统里如何只被运行一次 1.背景 2.方案1 2.方案2 1.背景 python Flask实现的一个http服务,打包成应用程序exe后在windows10系统运行; 由于我会不断的更新这个http服务,我希望运行这个http服务的时候之前的http服务被停掉; 即实现 Pytho…

git配置公钥/密钥

遇到 “gitgithub.com: Permission denied (publickey)” 错误通常意味着你尝试通过 SSH 连接到 GitHub 时&#xff0c;SSH 密钥没有被正确设置或者 GitHub 无法识别你的公钥。这里有几个步骤可以帮助你解决这个问题&#xff1a; 检查 SSH 密钥 首先&#xff0c;确保你已经在本…

【机器学习】“回归“算法模型的三个评估指标:MAE(衡量预测准确性)、MSE(放大大误差)、R²(说明模型解释能力)

文章目录一、MAE、MSE、r概念说明二、MAE&#xff08;平均绝对误差&#xff09;&#xff1a;用"房价预测"理解误差测量三、MSE&#xff08;均方误差&#xff09;&#xff1a;误差的"放大镜"1、概念说明2、 sklearn代码实践3、流程总结四、R&#xff1a;理解…

智慧城市SaaS平台|市容环卫管理系统

【生活垃圾中转设施监管】1) 设施信息管理a) 设施基本信息支持记录中转设施的名称、位置、类型、容量、负责人等基本信息。b) 设施分布地图支持通过GIS地图展示中转设施的分布情况&#xff0c;支持地图查询和导航。2) 垃圾收运监控a) 垃圾收运记录支持记录垃圾收运的时间、车辆…

JAVA-13常用类(2025.08.02学习记录)

String类String类equals方法String类compareTo方法String类valueOf方法boolean参数内存分析_字符串拼接只会在内存中开辟一个对象内存分析_字符串new创建对象内存分析_变量和字符串拼接字节码执行过程String类内存分析package com.cn;public class test01 {public static void …

QT----简单的htttp服务器与客户端

HTTP协议学习 协议的相关学习可以参考这篇 csdn学习连接 总体流程如下 HTTP服务器 监听ip和端口,有连接时接收请求,发送回复 server.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_httpServer.h" #include <QTcpServer> #include &l…

飞 算 JavaAI 解 析:有 了 它,麻 麻 再 也 不 用 担 心 我 不 会 写 代 码 了!

声 明&#xff1a;本 篇 博 客 为 测 评 体 验 非 广 告。 文 章 目 录一、产 品 简 介二、注 册 与 上 手方 法 一 - - - 从 IDEA 插 件 市 场 安 装方 法 二产 品 使 用三、产 品 体 验智 能 引 导 功 能理 解 需 求设 计 接 口表 结 构 设 计处 理 逻 辑生 成 源 码Java ch…

iOS混淆工具有哪些?在集成第三方 SDK 时的混淆策略与工具建议

许多 iOS 项目中&#xff0c;不可避免地会集成各种第三方 SDK&#xff0c;比如支付、统计、广告、社交登录等。这些 SDK 常常存在逆向被 Hook 或提取业务逻辑的风险&#xff0c;尤其是在流程敏感或要求合规的行业中。 当你无法对第三方源码进行控制或重新编译时&#xff0c;混淆…

【学习笔记之redis】删除缓存

有一串这个代码&#xff0c;staffEmailList这个key值里面的数据是错误的我需要删除它&#xff0c;把数据新的数据加载到redis缓存中。 public EmailAddressRespDTO getAllEmailAddress() { List<EmailAddressRespDTO> staffEmailList redisCache.getCacheList("s…