效率是核心,但效率高的教程會忽略掉非常多的細節。
解決問題的思路和細節對于一個問題的有效求解至關重要。
資料
云課五分鐘-02第一個代碼復現-終端甜甜圈C++-CSDN博客
從云課五分鐘到五秒鐘焦慮的甜甜圈向前沖-CSDN博客??
說明
復現重要性沒有那么大,重點功利角度在于不斷提升學習效率(多賺分),社會角度(多賺錢)。
回到ROS云課。
1. c++
#include <stdio.h>
#include <math.h>
#include <cstring>
#include <unistd.h>int main() {float A = 0, B = 0;float i, j;int k;float z[1760];char b[1760];printf("\x1b[2J");for (;;) {memset(b, 32, 1760);memset(z, 0, 7040);for (j = 0; j < 6.28; j += 0.07) {for (i = 0; i < 6.28; i += 0.02) {float c = sin(i);float d = cos(j);float e = sin(A);float f = sin(j);float g = cos(A);float h = d + 2;float D = 1 / (c * h * e + f * g + 5);float l = cos(i);float m = cos(B);float n = sin(B);float t = c * h * g - f * e;int x = 40 + 30 * D * (l * h * m - t * n);int y = 12 + 15 * D * (l * h * n + t * m);int o = x + 80 * y;int N = 8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n);if (22 > y && y > 0 && x > 0 && 80 > x && D > z[o]) {z[o] = D;b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];}}}printf("\x1b[H");for (k = 0; k < 1761; k++) {putchar(k % 80 ? b[k] : 10);A += 0.00004;B += 0.00002;}usleep(30000);}return 0;
}
2. g++
g++ -o donut donut.cpp
3. app
./donut
如上是純手工復現。
采用自動化方式復現如下:
echo "終端焦慮的甜甜圈"git clone https://gitcode.com/ZhangRelay1/donut.gitcd ~/donutg++ colordonut.cpp -o donut./donutecho "突破封印的甜甜圈"
視頻?
ROS云課基礎題庫-C++案例-甜甜圈
你提到的代碼是一個在終端中繪制動態甜甜圈圖案的 C++ 程序。這個程序通過使用數學函數和 ASCII 字符在終端中創建了一個視覺上類似甜甜圈的旋轉效果。復現這個代碼的過程不僅有助于理解如何使用 C++ 進行圖形編程(盡管是簡單的字符圖形),還可以提升學習效率,并通過對代碼進行修改和優化來提高編程技能。
代碼說明
-
包含頭文件:
cpp復制代碼
#include <stdio.h>
#include <math.h>
#include <cstring>
#include <unistd.h>
這些頭文件提供了基本的輸入輸出、數學函數、內存操作和睡眠功能。
-
變量初始化:
cpp復制代碼
float A = 0, B = 0;
float i, j;
int k;
float z[1760];
char b[1760];
這些變量用于存儲計算過程中的中間值和最終的字符圖形。
-
主循環:
- 使用無限循環?
for (;;)
?不斷刷新終端屏幕。 memset
?函數用于清空數組?b
?和?z
。- 嵌套循環計算每個點的位置和亮度。
- 使用數學函數?
sin
?和?cos
?計算 3D 空間中的點。 - 通過計算確定每個點對應的 ASCII 字符。
- 使用無限循環?
-
輸出:
- 使用 ANSI 轉義序列?
\x1b[H
?移動光標到屏幕頂部,并用?\x1b[2J
?清屏。 - 輸出字符數組?
b
?中的字符,形成圖形。 - 使用?
usleep(30000)
?暫停 30 毫秒以控制刷新率。
- 使用 ANSI 轉義序列?
自動化復現步驟
你提供的自動化步驟使用 Git 和命令行來快速復現這個項目:
bash復制代碼
echo "終端焦慮的甜甜圈" | |
git clone https://gitcode.com/ZhangRelay1/donut.git | |
cd ~/donut | |
g++ colordonut.cpp -o donut | |
./donut | |
echo "突破封印的甜甜圈" |
這些命令的作用是:
- 輸出提示信息。
- 克隆包含代碼的 Git 倉庫。
- 進入項目目錄。
- 編譯 C++ 源代碼并生成可執行文件。
- 運行可執行文件以查看甜甜圈效果。
- 輸出完成提示信息。
提升學習效率
- 實踐:通過手動編寫和調試代碼,加深對 C++ 和算法的理解。
- 自動化:利用腳本和工具簡化重復性任務,專注于代碼的優化和改進。
- 分享:將學習過程和成果記錄下來,分享給他人,鞏固自己的知識。
社會角度
- 項目經驗:這種小型項目可以作為簡歷上的項目經驗,展示你的編程能力和創造力。
- 社區參與:通過分享和參與開源項目,擴大人脈,了解行業動態。
- 持續學習:不斷提升自己的技能,適應快速變化的技術環境,增加職業競爭力。
通過復現和優化這樣的項目,不僅可以提高編程技能,還可以在學習和工作中獲得實際的收益。
C++知識點
這段代碼是一個簡單的ASCII藝術動畫程序,使用數學函數生成一個動態變化的圖案。以下是代碼中涉及的C++知識點及其詳細介紹:
1. 頭文件
c復制代碼
#include <stdio.h> | |
#include <math.h> | |
#include <cstring> | |
#include <unistd.h> |
<stdio.h>
: 提供輸入輸出功能,例如printf
和putchar
。<math.h>
: 提供數學函數,例如sin
和cos
。<cstring>
: 提供字符串處理函數,例如memset
。<unistd.h>
: 提供POSIX操作系統API訪問,包括usleep
函數。
2. 變量聲明和初始化
c復制代碼
float A = 0, B = 0; | |
float i, j; | |
int k; | |
float z[1760]; | |
char b[1760]; |
- 基本數據類型: 使用
float
和int
聲明變量。 - 數組:?
z
和b
是數組,分別用于存儲深度和字符。
3. 無限循環
c復制代碼
for (;;) { | |
// ... | |
} |
- 無限循環: 使用
for (;;)
創建一個無限循環,常用于需要持續運行的程序。
4. 內存設置
c復制代碼
memset(b, 32, 1760); | |
memset(z, 0, 7040); |
memset
函數: 用于將數組b
和z
初始化為特定值。32
是ASCII空格字符,0
用于浮點數數組的初始化。
5. 嵌套循環和數學計算
c復制代碼
for (j = 0; j < 6.28; j += 0.07) { | |
for (i = 0; i < 6.28; i += 0.02) { | |
// ... | |
} | |
} |
- 嵌套循環: 用于遍歷二維空間。
- 數學函數: 使用
sin
和cos
計算圖案的坐標和亮度。
6. 數組索引和條件判斷
c復制代碼
int x = 40 + 30 * D * (l * h * m - t * n); | |
int y = 12 + 15 * D * (l * h * n + t * m); | |
int o = x + 80 * y; | |
if (22 > y && y > 0 && x > 0 && 80 > x && D > z[o]) { | |
z[o] = D; | |
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0]; | |
} |
- 數組索引計算: 計算二維坐標
(x, y)
對應的一維數組索引o
。 - 條件判斷: 確保坐標在有效范圍內,并更新深度緩沖區
z
和字符緩沖區b
。
7. 字符映射
c復制代碼
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0]; |
- 字符數組: 使用字符數組實現亮度到字符的映射。
8. 屏幕輸出和動畫
c復制代碼
printf("\x1b[H"); | |
for (k = 0; k < 1761; k++) { | |
putchar(k % 80 ? b[k] : 10); | |
A += 0.00004; | |
B += 0.00002; | |
} | |
usleep(30000); |
- ANSI轉義序列:?
\x1b[H
移動光標到屏幕左上角。 - 字符輸出: 使用
putchar
輸出字符,每80個字符換行。 - 動畫效果: 通過改變
A
和B
實現圖案的動態變化,并使用usleep
控制幀率。
9. 主函數返回值
c復制代碼
return 0; |
- 程序結束:?
return 0
表示程序正常結束。
總結
這段代碼結合了數學計算、字符處理、內存操作和ANSI轉義序列生成動態ASCII藝術圖案。它展示了如何在C語言中使用基本圖形技術和動畫原理。
Linux g++知識點
使用?g++
?編譯 C++ 程序時,了解編譯器的選項和過程是很重要的。下面詳細介紹如何使用?g++
?編譯器將源代碼文件?donut.cpp
?編譯成可執行文件?donut
,并解釋其中涉及的知識點。
1. 基本命令結構
bash復制代碼
g++ -o donut donut.cpp |
g++
: GNU Compiler Collection(GCC)中的C++編譯器。它是用于編譯C++程序的主要工具。-o donut
: 指定輸出文件名為?donut
。如果沒有這個選項,默認輸出文件名是?a.out
。donut.cpp
: 輸入的C++源代碼文件。
2. 編譯過程
編譯過程通常包括幾個階段:預處理、編譯、匯編和鏈接。g++
?會自動處理這些階段。
- 預處理: 處理?
#include
?和?#define
?指令,展開宏,生成預處理后的代碼。 - 編譯: 將預處理后的代碼翻譯成匯編代碼。
- 匯編: 將匯編代碼轉換成機器碼,生成目標文件(
.o
?文件)。 - 鏈接: 將目標文件和庫文件鏈接在一起,生成最終的可執行文件。
3. 常見的?g++
?選項
-c
: 只編譯,不鏈接。生成目標文件而不是可執行文件。-Wall
: 啟用所有常見的警告信息。有助于發現潛在的編程錯誤。-Wextra
: 啟用額外的警告信息,進一步幫助發現潛在問題。-O[n]
: 優化代碼,n
?為優化級別,0
?到?3
,0
?表示無優化,3
?表示最高級別的優化。-g
: 生成調試信息,用于在調試器中查看源代碼和執行過程。-std=c++[version]
: 指定C++標準版本,例如?-std=c++11
、-std=c++14
、-std=c++17
、-std=c++20
?等。-I[directory]
: 指定頭文件搜索路徑。-L[directory]
: 指定庫文件搜索路徑。-l[library]
: 鏈接指定的庫文件。
4. 示例解釋
在命令?g++ -o donut donut.cpp
?中:
- 沒有使用優化選項,所以編譯器不會進行優化。對于生產代碼,通常會使用?
-O2
?或?-O3
?來提高性能。 - 沒有指定標準版本,所以編譯器將使用默認的C++標準版本。為了確保兼容性,通常會顯式指定標準版本,例如?
-std=c++17
。 - 輸出文件?
donut
?是指定的可執行文件名稱。運行這個文件可以通過?./donut
?在終端中執行。
5. 執行編譯后的程序
編譯成功后,可以通過以下命令運行生成的可執行文件:
bash復制代碼
./donut |
6. 調試和錯誤處理
- 查看警告和信息: 使用?
-Wall
?和?-Wextra
?來捕獲潛在的警告。 - 調試: 如果需要調試程序,使用?
-g
?選項生成調試信息,然后使用調試器(如?gdb
)進行調試。
總結
使用?g++
?編譯器可以有效地將C++源代碼轉換為可執行文件。通過理解和使用不同的編譯器選項,可以控制編譯過程,優化代碼,生成調試信息,并確保代碼與特定的C++標準兼容。
Linux命令知識點
在終端執行?./donut
?命令時,涉及的知識點主要包括以下幾個方面:
1. 可執行文件與權限
- 可執行文件:在Linux系統中,可執行文件是一種特殊的文件類型,它包含可以被操作系統直接執行的機器碼。
- 執行權限:為了執行一個文件,該文件必須具有執行權限。你可以使用?
ls -l
?命令查看文件的權限,其中?x
?表示執行權限。如果沒有執行權限,可以使用?chmod +x donut
?命令來添加執行權限。
2. 當前工作目錄
- 當前工作目錄:在終端中執行命令時,命令會在當前工作目錄(也稱為當前目錄)中查找文件和可執行文件。
- 路徑:如果?
donut
?文件不在當前工作目錄中,你需要提供文件的完整路徑或相對路徑。例如,如果?donut
?文件在?/home/user/bin
?目錄下,你需要執行?./home/user/bin/donut
?或先切換到該目錄,再執行?./donut
。
3. 命令解釋與執行
- 命令解釋器(shell):當你輸入命令并按下回車鍵時,終端會調用當前的shell(如bash、zsh等)來解釋和執行該命令。
- 動態鏈接庫:如果?
donut
?程序依賴于某些動態鏈接庫(如libstdc++、libc等),這些庫必須在系統的庫路徑中,或者你需要通過?LD_LIBRARY_PATH
?環境變量指定庫的路徑。
4. 環境變量
- 環境變量:環境變量是操作系統中用于配置程序運行環境的參數。例如,
PATH
?環境變量指定了shell查找可執行文件的目錄列表。 - 影響執行:環境變量可以影響程序的執行,例如,
LANG
?環境變量設置程序的語言環境,TZ
?環境變量設置程序使用的時區。
5. 終端與輸入輸出
- 標準輸入輸出:程序通過標準輸入(stdin)、標準輸出(stdout)和標準錯誤輸出(stderr)與終端進行交互。默認情況下,
./donut
?命令的輸出會顯示在終端上。 - 重定向:你可以使用重定向符號(如?
>
、>>
、<
?等)來改變輸入輸出流的方向。例如,./donut > output.txt
?會將程序的輸出重定向到文件?output.txt
?中。
6. 進程管理
- 進程創建:執行?
./donut
?命令時,系統會創建一個新的進程來運行該程序。 - 進程終止:程序運行結束后,該進程會被終止,并返回控制權給終端。
- 信號處理:在程序運行過程中,你可以通過發送信號來控制程序的執行。例如,使用?
Ctrl+C
?可以發送?SIGINT
?信號來終止程序。
7. 錯誤處理
- 錯誤報告:如果?
donut
?程序執行失敗,終端通常會顯示錯誤信息,幫助診斷問題。 - 退出狀態:程序執行結束后,會返回一個退出狀態碼。通常,
0
?表示成功,非零值表示失敗或錯誤。
8. 安全性
- 可執行文件來源:在執行任何可執行文件之前,應確保文件來源可信,避免執行惡意軟件。
- 權限設置:合理設置文件的權限,避免不必要的執行權限。
總結來看,在終端執行?./donut
?命令時,涉及的知識點包括可執行文件與權限、當前工作目錄、命令解釋與執行、環境變量、終端與輸入輸出、進程管理、錯誤處理以及安全性等方面。這些知識點共同構成了在Linux終端中執行程序的基礎。
自動化腳本知識點
你提供的命令序列是一個簡單的自動化腳本示例,它利用終端命令來執行一系列操作。以下是對每個命令的詳細介紹,包括它們涉及的知識點:
1.?echo "終端焦慮的甜甜圈"
echo
?命令:- 用于在終端輸出文本。
- 這里的?
"終端焦慮的甜甜圈"
?是輸出的字符串。 - 知識點:基本的終端命令使用,字符串輸出。
2.?git clone https://gitcode.com/ZhangRelay1/donut.git
git clone
?命令:- 用于從遠程Git倉庫復制代碼到本地。
https://gitcode.com/ZhangRelay1/donut.git
?是遠程倉庫的URL。- 知識點:Git版本控制系統,克隆遠程倉庫。
3.?cd ~/donut
cd
?命令:- 用于更改當前工作目錄。
~/donut
?表示當前用戶目錄下的?donut
?文件夾。- 知識點:文件系統導航,路徑使用(絕對路徑和相對路徑)。
4.?g++ colordonut.cpp -o donut
g++
?編譯器:- 用于編譯C++源代碼文件。
colordonut.cpp
?是要編譯的源代碼文件。-o donut
?選項指定輸出的可執行文件名為?donut
。- 知識點:C++編譯過程,
g++
?編譯器的基本使用。
5.?./donut
- 執行可執行文件:
./donut
?命令用于執行當前目錄下的?donut
?可執行文件。- 知識點:可執行文件的執行權限,進程管理。
6.?echo "突破封印的甜甜圈"
- 再次使用?
echo
?命令:- 輸出?
"突破封印的甜甜圈"
。 - 知識點:同第一個?
echo
?命令。
- 輸出?
腳本自動化涉及的知識點
- 順序執行:
- 腳本中的每個命令按順序執行。
- 知識點:基本的腳本編寫,命令的順序和依賴關系。
- 腳本文件:
- 可以將這些命令保存到一個文本文件中(如?
run.sh
),并通過?chmod +x run.sh
?賦予執行權限,然后通過?./run.sh
?來運行整個腳本。 - 知識點:腳本文件的創建和執行權限。
- 可以將這些命令保存到一個文本文件中(如?
- 錯誤處理:
- 在實際應用中,通常需要添加錯誤處理機制,以確保每個步驟成功執行。
- 知識點:條件判斷(如使用?
if
?語句),錯誤碼檢查。
- 環境配置:
- 確保所有依賴的工具(如?
git
?和?g++
)已安裝,并在系統的?PATH
?中可用。 - 知識點:環境變量配置,軟件包管理(如使用?
apt
、yum
?或?brew
?安裝工具)。
- 確保所有依賴的工具(如?
總結
這個簡單的自動化腳本展示了如何在終端中使用基本命令來執行一系列任務,包括輸出文本、克隆Git倉庫、編譯C++代碼和執行可執行文件。涉及的知識點包括終端命令的使用、Git版本控制、C++編譯過程、腳本編寫和執行權限管理等。通過將這些命令整合到一個腳本中,可以自動化執行這些任務,提高效率和一致性。