Linux 開發工具vim、gcc/g++、makefile

目錄

Linux編輯器-vim

1. 基本概念

2. 基本操作

3. 正常模式命令集

4. 末行模式命令集

5. 其他操作

6. 簡單vim配置

Linux編譯器-gcc/g++

1、基本概念?

2、程序翻譯的過程

3. gcc如何完成程序翻譯

4、動靜態庫?

Linux項目自動化構建工具-make/Makefile

1、背景

2、創建makefile

3、原理

5、項目清理

進度條小程序

1、緩沖區刷新

2、原理?

3、實現?


Linux編輯器-vim

1. 基本概念

vim的三種模式(目前掌握三種即可)分別是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能區分如下:
正常/普通/命令模式(Normal mode)
  • 控制屏幕光標的移動,字符、字或行的刪除,移動復制某區段及進入Insert mode下,或者到 last line mode
插入模式(Insert mode)
  • 只有在Insert mode下,才可以做文字輸入,按「ESC」鍵可回到命令行模式。該模式是我們后面用的最頻繁的編輯模式。
末行模式(last line mode)
  • 文件保存或退出,也可以進行文件替換,找字符串,列出行號等操作。 在命令模式下,shift+: 即可進入該模式。要查看你的所有模式:打開vim,底行模式直接輸入 :help vim-modes

2. 基本操作

進入vim,在系統提示符號輸入vim及文件名稱后,就進入vim全屏幕編輯畫面:
  • $ vim test.c ,進入vim之后,是處于[正常模式],要切換到[插入模式]才能夠輸入文字。
[正常模式]切換至[插入模式]
  • 輸入a
  • 輸入i
  • 輸入o
[插入模式]切換至[正常模式]
  • 目前處于[插入模式],就只能一直輸入文字,如果發現輸錯了字,想用光標鍵往回移動,將該字刪除,可以先按一下「ESC」鍵轉到[正常模式]再刪除文字。當然,也可以直接刪除。
[正常模式]切換至[末行模式]
  • 「shift + ;」, 其實就是輸入「:」
退出vim及保存文件,在[正常模式]下,按一下「:」冒號鍵進入「Last line mode」,例如:
  • : w (保存當前文件): wq (輸入「wq」,存盤并退出vim)
  • : q! (輸入q!,不存盤強制退出vim)

3. 正常模式命令集

插入模式
  • 按「i」切換進入插入模式「insert mode」,按“i”進入插入模式后是從光標當前位置開始輸入文件;
  • 按「a」進入插入模式后,是從目前光標所在位置的下一個位置開始輸入文字;
  • 按「o」進入插入模式后,是插入新的一行,從行首開始輸入文字。
從插入模式切換為命令模式
  • 按「ESC」鍵。
移動光標
  • vim可以直接用鍵盤上的光標來上下左右移動,但正規的vim是用小寫英文字母「h」、「j」、「k」、
  • 「l」,分別控制光標左、下、上、右移一格
  • 按「G」:移動到文章的最后
  • 按「 $ 」:移動到光標所在行的“行尾”
  • 按「^」:移動到光標所在行的“行首”
  • 按「w」:光標跳到下個字的開頭
  • 按「e」:光標跳到下個字的字尾
  • 按「b」:光標回到上個字的開頭
  • 按「#l」:光標移到該行的第#個位置,如:5l,56l
  • 按[gg]:進入到文本開始
  • 按[shift+g]:進入文本末端
  • 按「ctrl」+「b」:屏幕往“后”移動一頁
  • 按「ctrl」+「f」:屏幕往“前”移動一頁
  • 按「ctrl」+「u」:屏幕往“后”移動半頁
  • 按「ctrl」+「d」:屏幕往“前”移動半頁
刪除文字
  • 「x」:每按一次,刪除光標所在位置的一個字符
  • 「#x」:例如,「6x」表示刪除光標所在位置的“后面(包含自己在內)”6個字符
  • 「X」:大寫的X,每按一次,刪除光標所在位置的“前面”一個字符
  • 「#X」:例如,「20X」表示刪除光標所在位置的“前面”20個字符
  • 「dd」:刪除光標所在行,dd+p實現剪切
  • 「#dd」:從光標所在行開始刪除#行
復制
  • 「yw」:將光標所在之處到字尾的字符復制到緩沖區中。
  • 「#yw」:復制#個字到緩沖區
  • 「yy」:復制光標所在行到緩沖區。
  • 「#yy」:例如,「6yy」表示拷貝從光標所在的該行“往下數”6行文字。
  • 「p」:將緩沖區內的字符貼到光標所在位置。注意:所有與“y”有關的復制命令都必須與“p”配合才能完成復制與粘貼功能。
替換
  • 「r」:替換光標所在處的字符。
  • 「R」:替換光標所到之處的字符,直到按下「ESC」鍵為止。
  • [shift+r]?:進入替換模式
撤銷上一次操作
  • 「u」:如果您誤執行一個命令,可以馬上按下「u」,回到上一個操作。按多次“u”可以執行多次回復。
  • 「ctrl + r」: 撤銷的恢復
更改
  • 「cw」:更改光標所在處的字到字尾處
  • 「c#w」:例如,「c3w」表示更改3個字
跳至指定的行
  • 「ctrl」+「g」列出光標所在行的行號。
  • 「#G」:例如,「15G」,表示移動光標至文章的第15行行首。

大小寫切換

  • [shift]? +? [~]? ?按住不動可連續進行大小寫轉換。

4. 末行模式命令集

在使用末行模式之前,請記住先按「ESC」鍵確定您已經處于正常模式,再按「:」冒號即可進入末行模式。
列出行號
  • 「set nu」: 輸入「set nu」后,會在文件中的每一行前面列出行號。
跳到文件中的某一行
  • 「#」:「#」號表示一個數字,在冒號后輸入一個數字,再按回車鍵就會跳到該行了,如輸入數字15,再回車,就會跳到文章的第15行。
查找字符
  • 「/關鍵字」: 先按「/」鍵,再輸入您想尋找的字符,如果第一次找的關鍵字不是您想要的,可以一直按 「n」會往后尋找到您要的關鍵字為止。
  • 「?關鍵字」:先按「?」鍵,再輸入您想尋找的字符,如果第一次找的關鍵字不是您想要的,可以一直 按「n」會往前尋找到您要的關鍵字為止。
保存文件
「w」: 在冒號輸入字母「w」就可以將文件保存起來
離開vim
  • 「q」:按「q」就是退出,如果無法離開vim,可以在「q」后跟一個「!」強制離開vim。
  • 「wq」:一般建議離開時,搭配「w」一起使用,這樣在退出的時候還可以保存文件。
  • !+q/w/wq 強制執行命令

不退出vim執行命令

  • !+命令

5. 其他操作

  • 使用vim打開一個不存在的文件,對該文件進行編輯后保存,vim會自動幫你創建該文件。
  • vs + 文件名:在當前窗口創建一個新的垂直分屏,并在其中打開指定的文件。

6. 簡單vim配置

配置文件的位置
  • 在目錄 /etc/ 下面,有個名為vimrc的文件,這是系統中公共的vim配置文件,對所有用戶都有效。
  • 而在每個用戶的主目錄下,都可以自己建立私有的配置文件,命名為:“.vimrc”。例如,/root目錄下,
  • 通常已經存在一個.vimrc文件,如果不存在,則創建之。
  • 切換用戶成為自己執行 su ,進入自己的主工作目錄,執行 cd ~
  • 打開自己目錄下的.vimrc文件,執行 vim .vimrc
常用配置選項,用來測試
  • 設置語法高亮: syntax on
  • 顯示行號: set nu
  • 設置縮進的空格數為4: set shiftwidth=4

Linux編譯器-gcc/g++

1、基本概念?

gcc是GNU Compiler Collection(GNU編譯器集合)的縮寫,是一個廣泛使用的編程工具,用于編譯和鏈接C、C++、Objective-C和其他語言的源代碼。

gcc主要用于將高級編程語言(如C、C++等)的源代碼轉換為可執行文件或庫文件。它執行以下主要任務:

  1. 編譯:gcc將源代碼文件(如.c.cpp等)編譯為機器代碼文件(如.o.obj等)。編譯過程將源代碼轉換為匯編語言,然后再轉換為機器代碼。

  2. 鏈接:gcc將編譯生成的目標文件(.o.obj等)以及所需的庫文件鏈接在一起,生成最終的可執行文件或庫文件。鏈接過程將解析和解決符號引用,將多個目標文件和庫文件組合成一個完整的可執行文件。

除了編譯和鏈接源代碼,gcc還提供了許多選項和功能,用于優化代碼、調試程序、生成調試信息、處理預處理指令等。

2、程序翻譯的過程

程序需要被翻譯成二進制計算機才能讀懂
  1. 預處理(進行去注釋、宏替換、頭文件展開、條件編譯)
  2. 編譯(C/C++ >>> 匯編)
  3. 匯編(匯編 >> 可重定向二進制目標文件)
  4. 連接(鏈接多個 .o .obj 合并形成可執行文件.exe)

3. gcc如何完成程序翻譯

格式 gcc [選項] 要編譯的文件 [選項] [目標文件]
預處理(進行宏替換)
  • 預處理功能主要包括宏定義,文件包含,條件編譯,去注釋等。
  • 預處理指令是以#號開頭的代碼行。
  • 實例:?gcc -E hello.c -o hello.i
    • 選項“-E”,該選項的作用是讓 gcc 在預處理結束后停止編譯過程。
    • 選項“-o”是指目標文件,“.i”文件為已經過預處理的C原始程序,-o后面緊跟生成的目標文件。
編譯(生成匯編)
  • 在這個階段中,gcc 首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查
  • 無誤后,gcc 把代碼翻譯成匯編語言。
  • 選項“-S”:從現在開始進行程序的翻譯,如果編譯完成就停下來。
  • 實例: gcc –S hello.i –o hello.s
匯編(生成機器可識別代碼)
  • 匯編階段是把編譯階段生成的“.s”文件轉成目標文件(二進制文件)。
  • 選項“-c”從現在開始進行程序的翻譯,如果匯編完成就停下來。
  • 實例: gcc –c hello.s –o hello.o
鏈接(生成可執行文件或庫文件)
  • 在成功編譯之后,就進入了鏈接階段。
  • 實例: gcc hello.o –o hello

4、動靜態庫?

在這里涉及到一個重要的概念:函數庫
頭文件提供方法列表,庫提供方法的實現。
  • 在我們的C程序中,雖然沒有定義“printf”函數的實現,且在預編譯中包含的“stdio.h”中只有該函數的聲明,但實際上,“printf”等標準庫函數的實現被存放在名為?libc.so.6?的庫文件中。
  • 當使用gcc編譯時,如果沒有特別指定,它會默認在系統的搜索路徑(通常是/usr/lib)下查找這個庫文件。通過鏈接到libc.so.6,程序能夠實現對“printf”等函數的調用,這就是鏈接階段的作用。
函數庫一般分為靜態庫和動態庫兩種。

在Linux系統中,庫文件主要有兩種形式:動態庫(.so文件)和靜態庫(.a文件)。相應地,在Windows系統中,這兩種類型的庫文件分別以.dll(動態庫)和.lib(靜態庫)作為后綴名。

靜態庫在編譯鏈接過程中,將庫文件中的代碼全部加入到生成的可執行文件中。這種方式會導致可執行文件體積較大,但好處是運行時不再依賴外部的庫文件。靜態庫文件在Linux中一般以.a作為后綴名。

動態庫的處理方式則不同,它在編譯鏈接時不會將庫文件的代碼直接加入到可執行文件中。

  • 相反,程序在運行時會動態地加載所需的庫文件。這種方式可以減少系統資源的占用,因為多個程序可以共享同一個庫文件的單個副本。
  • 動態庫文件在Linux中的后綴名通常為.so,例如之前提到的libc.so.6便是一個動態庫。
  • 在編譯時,GCC默認采用動態庫鏈接,從而生成的二進制程序通常是動態鏈接的。這一點可以通過使用file命令來驗證。例如,編譯生成可執行文件的命令可以是:gcc hello.o -o hello,這里GCC會默認鏈接到動態庫。
gcc選項
  • -E 只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件里面
  • -S? 編譯到匯編語言不進行匯編和鏈接
  • -c? 編譯到目標代碼
  • -o 文件輸出到 文件
  • -static 此選項對生成的文件采用靜態鏈接
  • -g?生成調試信息。GNU 調試器可利用該信息。
  • -shared?此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.
  • -O0 -O1 -O2 -O3
    • 編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高
  • -w? 不生成任何警告信息。
  • -Wall 生成所有警告信息。

Linux項目自動化構建工具-make/Makefile

1、背景

  • 會不會寫makefile,從一個側面說明了一個人是否具備完成大型工程的能力
  • 一個工程中的源文件不計數,其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進行更復雜的功能操作
  • makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。
  • make是一個命令工具,是一個解釋makefile中指令的命令工具,一般來說,大多數的IDE都有這個命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可見,makefile都成為了一種在工程方面的編譯方法。
  • make是一條命令,makefile是一個文件,兩個搭配使用,完成項目自動化構建。

2、創建makefile

要使用Makefile,您可以按照以下步驟進行:

1. 創建Makefile文件:在項目的根目錄或適當的位置創建一個名為“Makefile”(或“makefile”)的文件。

2. 定義目標和規則:在Makefile中,定義您的目標和相應的規則。每個目標表示一個輸出文件,而規則則指定如何生成目標。

target: dependencies//依賴關系command//依賴方法

? ? 例如,如果您有一個C程序(如“hello.c”)需要編譯成可執行文件(如“hello”),Makefile可能如下所示:

hello: hello.ogcc hello.o -o hellohello.o: hello.c ? ? ? gcc -c hello.c -o hello.o
  • hello: hello.o 就是依賴關系
  • gcc hello.o -o hello,就是依賴方法

3. 運行make命令:在命令行中,進入到包含Makefile的目錄,并運行`make`命令。

make

? ? 這將根據Makefile中的規則自動構建項目。

這樣,Makefile就會根據定義的規則構建和管理您的項目。這對于大型項目和多文件項目的構建過程特別有用。

3、原理

hello: hello.ogcc hello.o -o hellohello.o: hello.sgcc -c hello.s -o hello.ohello.s: hello.igcc -S hello.i -o hello.shello.i: hello.cgcc -E hello.c -o hello.i.PHONY:clean
clean:rm -f hello.i hello.s hello.o hello
  • 上面的文件 hello ,它依賴 hell.o
  • hello.o , 它依賴 hello.s
  • hello.s , 它依賴 hello.i
  • hello.i , 它依賴 hello.c
  1. 尋找Makefile:Make首先在當前目錄下尋找名為“Makefile”或“makefile”的文件。
  2. 確定目標文件:在Makefile中,Make會查找第一個目標(target),例如“hello”,并將其作為構建過程的最終目標。
  3. 檢查文件依賴和更新:如果目標文件“hello”不存在,或者它依賴的文件(如“hello.o”)比“hello”更新(這可以通過touch命令模擬),Make將執行相應的命令來生成“hello”文件。
  4. 遞歸解析依賴:如果“hello”依賴的“hello.o”文件不存在,Make會在Makefile中尋找生成“hello.o”的規則,并遞歸地解析直到所有依賴都被構建。這個過程類似于堆棧操作,Make會一層層地解析文件依賴關系,直到所有必需的文件都被編譯或更新。
  5. 編譯和構建:在所有的C文件和H文件存在的情況下,Make將根據規則生成“hello.o”文件,然后使用它來完成最終目標“hello”的構建。

Make的核心在于管理文件之間的依賴關系。它會一步步地檢查和滿足這些依賴,直到達到最終的構建目標。如果在解析依賴的過程中遇到無法找到的文件,Make會停止并報錯。然而,對于命令執行錯誤或編譯失敗,Make不會中斷其過程,因為它主要關注的是文件依賴性。

總結來說,Make通過逐層解析和滿足文件依賴,自動化地管理編譯過程。這種方式極大地簡化了復雜項目的構建過程,使開發者能夠專注于代碼開發,而不是構建過程的每一個細節。

5、項目清理

工程是需要被清理的。
  • 像clean這種,沒有被第一個目標文件直接或間接關聯,那么它后面所定義的命令將不會被自動執行, 不過,我們可以顯示要make執行。即命令——“make clean”,以此來清除所有的目標文件,以便重編譯。
  • 但是一般我們這種clean的目標文件,我們將它設置為偽目標,用 .PHONY 修飾,偽目標的特性是,總是被執行的,總是會根據依賴關系執行依賴方法。

例: 鏈接三個文件

其中makefile如下:?

[hbr@VM-16-9-centos lesson5]$ cat makefile 
mytest:test.o main.ogcc -o mytest test.o main.o
test.o:test.cgcc -c test.c -o test.o
main.o:main.cgcc -c main.c -o main.o.PHONY:clean
clean:rm -f *.o mytest

進度條小程序

1、緩沖區刷新

[hbr@VM-16-9-centos program1]$ touch test.c
[hbr@VM-16-9-centos program1]$ vim test.c
[hbr@VM-16-9-centos program1]$ cat test.c 
#include <stdio.h>
#include <unistd.h>int main()
{printf("hello\n");sleep(3);return 0;
}
[hbr@VM-16-9-centos program1]$ gcc test.c 
[hbr@VM-16-9-centos program1]$ ls
a.out  makefile  proc  proc.c  test.c
[hbr@VM-16-9-centos program1]$ ./a.out 
hello
[hbr@VM-16-9-centos program1]$ vim test.c
[hbr@VM-16-9-centos program1]$ cat test.c 
#include <stdio.h>
#include <unistd.h>int main()
{printf("hello");sleep(3);return 0;
}
[hbr@VM-16-9-centos program1]$ gcc test.c 
[hbr@VM-16-9-centos program1]$ ./a.out 

第一次輸出時:先輸出Hello然后3秒后結束。

第二次去掉“\n”輸出時:先等待三秒然后輸出Hello后結束。

當第一次執行編譯后的程序時,程序會立即輸出"hello",然后等待3秒鐘后結束。這是因為printf函數遇到換行符\n時,會立即刷新輸出緩沖區,使得"hello"緊接著被輸出到屏幕上。

而在第二次執行時,由于從printf的字符串中移除了換行符\n,輸出的行為有所不同。

  • 在這種情況下,printf輸出的"hello"首先被存儲在輸出緩沖區中,并不會立即顯示。
  • 由于C語言的輸出緩沖區是根據特定的刷新策略來刷新的,對于到顯示器這種設備,其一般的刷新策略是在遇到換行符\n時進行刷新。
  • 因此,當沒有換行符引導的直接刷新時,輸出緩沖區會等待直到程序結束或遇到其他刷新條件才進行刷新。這就是為什么在移除\n后,"hello"會在等待了3秒后才顯示出來的原因。

2、原理?

\n換行本質上是:換行(到下一行)+回車(到行首),先看代碼。

[hbr@VM-16-9-centos program1]$ vim test.c 
[hbr@VM-16-9-centos program1]$ cat test.c 
#include <stdio.h>
#include <unistd.h>int main()
{int n = 6;while(n >= 0){printf("n=%d\n",n);n--;sleep(1);}return 0;
}
[hbr@VM-16-9-centos program1]$ gcc test.c 
[hbr@VM-16-9-centos program1]$ ./a.out 
n=6
n=5
n=4
n=3
n=2
n=1
n=0
[hbr@VM-16-9-centos program1]$ vim test.c //\n換成\r
[hbr@VM-16-9-centos program1]$ gcc test.c 
[hbr@VM-16-9-centos program1]$ ./a.out //沒有輸出結果
[hbr@VM-16-9-centos program1]$ vim test.c 
[hbr@VM-16-9-centos program1]$ cat test.c 
#include <stdio.h>
#include <unistd.h>int main()
{int n = 6;while(n >= 0){printf("n=%d\r",n);n--;fflush(stdout);sleep(1);}return 0;
}
[hbr@VM-16-9-centos program1]$ gcc test.c 
[hbr@VM-16-9-centos program1]$ ./a.out 
[hbr@VM-16-9-centos program1]$//會按照倒計時輸出,此處不方便展示效果
  • 第一個示例中,\n用于在每次輸出后換行并回到行首,這是標準的行為,使得每個輸出結果都在新的一行顯示,因此可以看到從n=6遞減到n=0的過程,每個數字都在新的一行上。
  • 然而,將\n替換為\r時,行為發生了變化。在計算機中,\r是回車符,它的作用是將光標移回行首,但不會進入新行。這意味著如果只用\r而不是\n,所有的輸出都會在同一行上發生,而且后面的輸出會覆蓋前面的輸出。
  • 在沒有fflush(stdout);的情況下,由于輸出緩沖區不會因\r而刷新,可能在程序執行完畢之前看不到任何輸出。這是因為輸出緩沖區通常在滿了或者程序結束時才會自動刷新,導致在第二次嘗試中看不到輸出結果。
  • 引入fflush(stdout);后,每次調用printf之后立即強制刷新輸出緩沖區,使得即使是\r也能即時看到效果。這導致光標回到行首,然后用新的數字覆蓋舊的數字,實現了一個簡單的倒計時效果。因為光標每次都回到行首,而且立即刷新,所以你可以看到n的值從6遞減到0,但這個過程中你只會在屏幕上看到一個數字的變化,而不是多行輸出。

3、實現?

該程序的可視化效果是一個逐步填充的進度條,旁邊有一個旋轉的符號表示進度正在進行,直到進度條完全填滿,并顯示100%。通過這種方式,可以在執行較長時間的操作時給用戶一個視覺上的反饋。

[hbr@VM-16-9-centos program1]$ tree
.
├── makefile
├── proc.c
└── test.c0 directories, 3 files
[hbr@VM-16-9-centos program1]$ cat makefile 
proc:proc.cgcc -o proc proc.c.PHONY:clean
clean:rm -f proc
[hbr@VM-16-9-centos program1]$ vim proc.c 
[hbr@VM-16-9-centos program1]$ cat proc.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define NUM 51int main()
{char bar[NUM];memset(bar,0,sizeof(bar));const char *lable="|/-\\";int i=0;while(i<=50){printf("[%-50s][%d%%] %c\r",bar,i*2,lable[i%4]);bar[i++]='#';fflush(stdout);usleep(30000);}printf("\n");return 0;
}
[hbr@VM-16-9-centos program1]$ make
gcc -o proc proc.c
[hbr@VM-16-9-centos program1]$ ls
makefile  proc  proc.c  test.c
[hbr@VM-16-9-centos program1]$ ./proc
[##################################################][100%] -

proc.c中,定義了一個進度條,使用字符數組bar來模擬進度條的填充情況,并通過循環逐漸增加bar數組中的#字符數量來表示進度的增加。下面是代碼的逐行解釋:

  1. 包含必要的頭文件stdio.h(用于輸入輸出)、string.h(用于內存操作),和unistd.h(用于usleep函數,暫停執行)。
  2. 定義宏NUM為51,這個值用于定義字符數組bar的長度。
  3. main函數中,聲明字符數組bar并通過memset函數將其初始化為全0,這意味著開始時進度條是空的。
  4. 定義一個字符串lable,包含四個字符"|/-\\",用于在進度條旁邊顯示旋轉的效果,模仿一個正在進行的操作。
  5. 使用while循環,條件為i小于等于50,這意味著進度條的最大填充長度為50個#字符。
  6. 在循環內部,使用printf函數打印進度條。[%-50s]用于左對齊打印字符串bar,寬度固定為50個字符;[%d%%]顯示當前進度的百分比,因為循環是到50,所以用i*2來計算百分比;%c用于打印旋轉符號,通過lable[i%4]選擇"|/-\\"中的一個字符,隨著i的增加而變化。
  7. 每次循環時,將bar[i]設置為#,通過遞增i來模擬進度條的填充。
  8. 使用fflush(stdout)強制刷新標準輸出,確保每次循環的輸出都能立即顯示而不是等緩沖區滿。
  9. usleep(30000)暫停30毫秒(30000微秒),這樣用戶可以看到進度條的逐步填充和旋轉符號的動態變化。
  10. 循環結束后,打印一個換行符\n,以避免在命令行提示符出現之前光標停留在進度條的末尾。
  11. 函數返回0,表示程序正常結束。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716258.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716258.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716258.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Qt學習筆記】(四)Qt窗口

Qt窗口 1 菜單欄1.1 創建菜單欄1.2 在菜單欄中添加菜單1.3 創建菜單項1.4 在菜單項之間添加分割線1.5 給菜單項添加槽函數1.6 給菜單項添加快捷鍵 2 工具欄2.1 創建工具欄2.2 設置停靠位置2.3 設置浮動屬性2.4 設置移動屬性2.5 添加 Action 3 狀態欄3.1 狀態欄的創建3.2 在狀態…

2024最新算法:冠豪豬優化算法(CPO)求解23個基準函數

一、冠豪豬優化算法 冠豪豬優化算法(Crested Porcupine Optimizer&#xff0c;CPO)由Mohamed Abdel-Basset等人于2024年提出&#xff0c;該算法模擬冠豪豬的四種不同保護機制&#xff1a;視覺、聽覺、氣味和物理攻擊。第一和第二防御技術&#xff08;視覺和聽覺&#xff09;反…

盤點 | IT行業哪些認證含金量高

微思網絡 廈門微思網絡 作為一名IT人員&#xff0c;誰沒考幾個證 ——值得考的證書擁有的特性 ? 獲政府、企業和從業者認可&#xff1b; ? 持證人數多&#xff0c;業內共識度高&#xff1b; ? 幫持證者加分&#xff0c;快速提薪。 系統網絡方向認證 01 華為認證 華為…

設計模式學習筆記 - 設計原則 - 7.DRY 原則及提高代碼復用性

前言 DRY 原則&#xff0c;英文描述為&#xff1a; Don’t Repeat Yourself。中文直譯&#xff1a;不要重復自己。將它應用在編程中&#xff0c;可理解為&#xff1a;不要寫重讀的代碼。 可能你認為&#xff0c;這個原則很簡單。只要兩段代碼長得一樣&#xff0c;那就是違反 …

【機器學習】包裹式特征選擇之遞歸特征消除法

&#x1f388;個人主頁&#xff1a;豌豆射手^ &#x1f389;歡迎 &#x1f44d;點贊?評論?收藏 &#x1f917;收錄專欄&#xff1a;機器學習 &#x1f91d;希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出指正&#xff0c;讓我們共同學習、交流進…

電磁兼容(EMC):電解電容低阻如何選擇詳解

目錄 1 為何要選低阻電解電容 2 電解電容等效高頻等效電路 3 不同廠家ESR參數 4 高頻ESR特性 5 Low ESR鋁電解電容 1 為何要選低阻電解電容 在EMI超標時&#xff0c;將普通電解電容更換為低阻電解電容時&#xff0c;便通過了。這是因為低阻電解電容降低了功率回路的輻射電…

數字化轉型導師堅鵬:證券公司數字化轉型戰略、方法與案例

證券公司數字化轉型戰略、方法與案例 課程背景&#xff1a; 數字化轉型背景下&#xff0c;很多機構存在以下問題&#xff1a; 不清楚證券公司數字化轉型的發展戰略&#xff1f; 不知道證券公司數字化轉型的核心方法&#xff1f; 不知道證券公司數字化轉型的成功案例&am…

LLM 系列——BERT——論文解讀

一、概述 1、是什么 是單模態“小”語言模型&#xff0c;是一個“Bidirectional Encoder Representations fromTransformers”的縮寫&#xff0c;是一個語言預訓練模型&#xff0c;通過隨機掩蓋一些詞&#xff0c;然后預測這些被遮蓋的詞來訓練雙向語言模型&#xff08;編碼器…

【計算機網絡通信】計算機之間的局域網通信和互聯網通信方法(附Python和C#代碼)

文章目錄 前言一、局域網通信1.1 基本原理和方法1.1.1 獲取本地ip1.1.2 實現局域網內的廣播1.1.3 進行局域網通信 1.2 實現多客戶端連接1.3 Python源碼1.4 C#源碼1.5 可能存在的問題 二、互聯網通信2.1 實現原理2.1.1 內網穿透軟件2.1.2 實現互聯網通信 2.2 Python源碼2.3 C#源…

基于Java的超市商品管理系統(Vue.js+SpringBoot)

目錄 一、摘要1.1 簡介1.2 項目錄屏 二、研究內容2.1 數據中心模塊2.2 超市區域模塊2.3 超市貨架模塊2.4 商品類型模塊2.5 商品檔案模塊 三、系統設計3.1 用例圖3.2 時序圖3.3 類圖3.4 E-R圖 四、系統實現4.1 登錄4.2 注冊4.3 主頁4.4 超市區域管理4.5 超市貨架管理4.6 商品類型…

牛客小白月賽85_D-阿里馬馬和四十大盜

非常非常非常有意思的一道題,正好寫一下做題思路 對于到不了的情況,那就是存在連續>0的區間,該區間和>m,這樣不管怎么補血一定過不去,cin的時候,就可以判斷 最開始我以為是貪心,發現當前區間走不過去那就返回上一個0點補血,但就是過不去 突然我發現這個樣例很有意思 1…

Vant Weapp

Vant Weapp - 輕量、可靠的小程序 UI 組件庫 van-radio name 是一個字符串&#xff0c;無法傳對象的處理 以及 mpx 多層嵌套 for 循環處理 <viewwx:for"{{questionList}}"wx:for-item"question" // item 重命名wx:for-index"questionIndex"…

一文了解docker與k8s

隨著 k8s 作為容器編排解決方案變得越來越流行&#xff0c;有些人開始拿 Docker 和 k8s 進行對比&#xff0c;不禁問道&#xff1a;Docker 不香嗎&#xff1f; k8s 是 kubernetes 的縮寫&#xff0c;8 代表中間的八個字符。 其實 Docker 和 k8s 并非直接的競爭對手兩者相互依存…

Qt外部調用進程類QProcess的使用

有的時候我們需要在自己程序運行過程中調用其他進程&#xff0c;那么就需要用到QProcess。 首先可以了解一些關于進程的相關知識&#xff1a;線程與進程&#xff0c;你真得理解了嗎_進程和線程的區別-CSDN博客 進程是計算機中的程序關于某數據集合上的一次運行活動&#xff0…

Java面試——Redis

優質博文&#xff1a;IT-BLOG-CN 一、Redis 為什么那么快 【1】完全基于內存&#xff0c;絕大部分請求是純粹的內存操作&#xff0c;非常快速。數據存在內存中。 【2】數據結構簡單&#xff0c;對數據操作也簡單&#xff0c;Redis中的數據結構是專門進行設計的。 【3】采用單線…

【Vue3】全局切換字體大小

VueUse 先安裝VueUse <template><header><div class"left">left</div><div class"center">center</div><div class"right">right</div></header><div><button click"cha…

飛天使-學以致用-devops知識點4-SpringBoot項目CICD實現(實驗失敗,了解大概流程)

文章目錄 代碼準備創建jenkins 任務測試推送使用項目里面的jenkinsfile 進行升級操作 文字版本流程項目構建 代碼準備 推送代碼到gitlab 代碼去叩叮狼教育找 k8s 創建jenkins 任務 創建一個k8s-cicd-demo 流水線任務 將jenkins 里面構建時候的地址還有token&#xff0c; 給到…

azure devops工具實踐分析

對azure devops此工具的功能深挖&#xff0c;結合jira的使用經驗的分析 1、在backlog的功能描述&#xff0c;可理解為需求項&#xff0c;這里包括了bug&#xff0c;從開發的角度修復bug也是個工作項&#xff0c;所以需求的范圍是真正的需求&#xff08;開發接收到的已經確認的…

已解決org.springframework.web.multipart.MultipartException處理多部分請求異常的正確解決方法,親測有效!!!

已解決org.springframework.web.multipart.MultipartException處理多部分請求異常的正確解決方法&#xff0c;親測有效&#xff01;&#xff01;&#xff01; 目錄 問題分析 出現問題的場景 報錯原因 解決思路 解決方法 總結 在Web開發過程中&#xff0c;我們經常需要處…

基于JAVA協同過濾算法網上海鮮水產推薦購物商城系統設計與實現(Springboot框架)可行性分析

博主介紹&#xff1a;黃菊華老師《Vue.js入門與商城開發實戰》《微信小程序商城開發》圖書作者&#xff0c;CSDN博客專家&#xff0c;在線教育專家&#xff0c;CSDN鉆石講師&#xff1b;專注大學生畢業設計教育和輔導。 所有項目都配有從入門到精通的基礎知識視頻課程&#xff…