關鍵字 - 第六講

前文補充

#include <iostream>
using namespace std;int main()
{int a = 10;int c = 20; // 將變量c定義在switch語句之前switch(a){case 1:{cout << ".........." << endl;cout << c << endl;}break;default:cout << ".........." << endl;break;}return 0;
}

這段代碼存在一些問題,以下是代碼的分析和問題說明:

代碼分析

  1. switch語句的結構問題

    • switch語句的語法要求case標簽必須位于switch語句塊的最外層,而不能嵌套在其他語句(如printf)之后。在你的代碼中,printf("..........\n");int c = 20;以及printf("..........\n");出現在case標簽之前,這是不符合C++語法的。

    • switch語句的執行流程是從匹配的case標簽開始執行,直到遇到breakswitch語句結束。因此,case標簽不能嵌套在其他語句中。

  2. 變量c的作用域問題

    • switch語句中,case標簽后的代碼塊(用大括號{}括起來的部分)會創建一個新的作用域。在你的代碼中,int c = 20;定義在switch語句塊的外面,但在case 1中嘗試訪問c。由于c的作用域問題,這會導致編譯錯誤。

修改后的代碼

以下是修改后的代碼,修復了上述問題:

#include <iostream>
using namespace std;int main()
{int a = 10;int c = 20; // 將變量c定義在switch語句之前switch(a){case 1:{cout << ".........." << endl;cout << c << endl;}break;default:cout << ".........." << endl;break;}return 0;
}

修改說明

  1. 變量c的定義位置

    • int c = 20;定義在switch語句之前,確保在switch語句中可以正確訪問c

  2. switch語句的結構

    • printf語句和case標簽的順序調整為符合C++語法的結構。case標簽必須位于switch語句塊的最外層。

  3. 使用cout代替printf

    • 為了保持代碼風格的一致性,將printf替換為C++標準庫中的cout

輸出結果

假設a的值為10,程序的輸出將是:

..........

如果將a的值改為1,程序的輸出將是:

..........
20

本章重點

  • 循環的語法理解

  • breakcontinue 的作用

  • goto 真的沒人用嗎

  • void 的理解

  • void 修飾函數和函數參數的作用

  • void 指針的用途

1.9 do、while、for 關鍵字

三種循環各自語法 - 補充內容

while 循環

// while
條件初始化
while(條件判定){// 業務更新條件更新
}

for 循環

// for
for(條件初始化;條件判定;條件更新){// 業務代碼
}

do while 循環

條件判定是放在后面的,是直接先執行代碼塊中的代碼邏輯的!--- 至少會跑一遍

// do while
條件初始化
do{條件更新
}while(條件判定);do{}while(0);

三種循環對應的死循環寫法 - 補充內容

while(1){
}for(;;){}do{}while(1);

書中代碼,優化后

#include <stdio.h>
#include <windows.h>int main()
{while (1){char c = getchar();if ('#' == c){break;}printf("echo: %c\n", c);}system("pause");return 0;
}

在C語言中,使用 int c 而不是 char c 來接收 getchar() 的返回值是一個常見的最佳實踐,原因主要與 getchar() 函數的返回值類型以及字符和整數的表示范圍有關。下面詳細解釋為什么使用 int c 更好:

getchar()?的返回值類型

getchar() 函數的返回值類型是 int,而不是 char。其原型定義為:

int getchar(void);

這意味著 getchar() 返回的是一個整數(int 類型),而不是一個字符(char 類型)。返回的整數值可以表示一個字符的ASCII碼,也可以是一個特殊的值 EOF(表示文件結束)。

EOF?的值

EOF 是一個特殊的值,用于表示輸入流的結束。在標準C中,EOF 的值通常定義為 -1。由于 char 類型的范圍通常是 0 到 255(對于無符號字符)或 -128 到 127(對于有符號字符),而 EOF 的值是 -1,這可能會導致問題。

如果使用 char c 來接收 getchar() 的返回值,可能會出現以下問題:

  • 有符號字符問題 :如果 char 是有符號類型(這是默認情況,但具體取決于編譯器和平臺),EOF 的值 -1 可以被正確存儲在 char 中。但是,當 char 被用作條件表達式時,可能會出現意外的行為。例如,if (c == EOF) 可能不會按預期工作,因為 c 的值可能會被隱式轉換為 int,導致比較失敗。

  • 無符號字符問題 :如果 char 是無符號類型(可以通過編譯器選項或平臺設置來改變),EOF 的值 -1 會被解釋為一個非常大的正數(通常是 255)。這會導致 if (c == EOF) 的比較永遠失敗,因為 c 的值永遠不會等于 -1

使用?int c?的好處

使用 int c 來接收 getchar() 的返回值可以避免上述問題。int 類型的范圍足夠大,可以正確表示所有可能的字符值以及 EOF。這樣可以確保 if (c == EOF) 的比較總是按預期工作。

以下是修改后的代碼,使用 int c 來接收 getchar() 的返回值:

#include <stdio.h>
#include <windows.h>int main()
{int c; // 使用int來接收getchar()的返回值while (1){c = getchar();if ('#' == c){break;}printf("echo: %c\n", c);}system("pause");return 0;
}

使用 int c 而不是 char c 來接收 getchar() 的返回值,可以確保程序能夠正確處理 EOF 的值,避免因字符類型范圍問題導致的錯誤。這是C語言編程中的一個常見最佳實踐,有助于提高代碼的健壯性和可移植性。

我們的1234的數字,可以打印出來,我們也就可以發現 printf 的價值,有作用,就是將一個整型轉化成一個一個字符,顯示到顯示器當中(程序運行會默認打開三個文件:輸入輸出錯誤)

對于 ASCLL碼表,在后面,我們會談論到,這也就是機器不是只認識二進制嗎?為什么還認識abcd這樣的字符,更多詳情,后續會介紹!

補充:

與getchar:從鍵盤上獲取一個字符的操作相對應的是putchar,往標準輸出上顯示一個字符!

1.9.1?break?&?continue?區別

在C語言中,breakcontinue 都是用于控制循環流程的語句,但它們的作用和使用場景有很大區別。

1.?break

  • 作用 :用于完全終止最內層的循環(forwhiledo-while ),跳出循環體,繼續執行循環體之后的代碼。

  • 使用場景 :當你在循環中遇到了某種條件,使得你不再需要繼續執行循環,就可以使用 break 。比如在一個查找算法中,一旦找到了目標元素,就可以用 break 跳出循環,避免無意義的繼續循環。

  • 示例代碼

#include <stdio.h>int main() {for (int i = 0; i < 10; i++) {if (i == 5) {break; // 當i等于5時,跳出循環}printf("%d ", i);}printf("\nLoop ended.\n");return 0;
}
0 1 2 3 4
Loop ended.

因為當 i 等于 5 時,break 語句執行,循環被終止,直接跳到循環體之后的代碼。

2.?continue

  • 作用 :用于跳過當前循環體中的剩余代碼,直接進入下一次循環迭代。也就是說,continue 只是中斷當前這一次循環的執行,而不是整個循環。直接跳到條件判定,而不是內部代碼塊!do while 也是如此!!!也是先到while的條件判定!都是跳轉到條件判定!!!

但是對于for來說:我們有一個示例代碼:也是證明代碼:

int main()
{int i = 10;for( ; i < 10; ++i){printf("continue before\n");if(i == 5){printf("continue\n");continue;}printf("continue after\n");}return 0;
}

這就不是跳轉到1了,想想,如果跳轉到1,就會造成死循環了,所以,這個應該是跳到2,即++i!

#include <stdio.h>int main()
{int i = 0;for( ; i < 10; ){if(i == 5){printf("%d\n", i);continue;}++i;}return 0;
}

但是我們這么寫的話就是會造成死循環!

continue?語句在?for?循環中的行為是:跳過當前迭代中?continue?之后的所有代碼,然后執行?for?循環的第三部分(即增量表達式?++i,最后再進行條件判斷開始下一次循環;而在您第二個沒有增量表達式的?for?循環中,由于?continue?跳過了?++i?語句,導致?i?的值永遠停留在 5 無法增加,從而造成了死循環。

簡單來說:

  • 有增量表達式continue?→ 執行?++i?→ 條件判斷 → 下一次循環

  • 無增量表達式continue?→ 條件判斷 → 下一次循環(i?不變)→ 死循環



  • 使用場景 :當你在循環中遇到某些情況,不想執行當前循環體中的剩余代碼,但仍然希望循環能夠繼續進行,就可以使用 continue 。例如在篩選數據時,跳過不符合條件的數據,繼續處理符合條件的數據。

  • 示例代碼

#include <stdio.h>int main() {for (int i = 0; i < 10; i++) {if (i % 2 == 0) {continue; // 當i為偶數時,跳過當前循環的剩余代碼}printf("%d ", i);}printf("\nLoop ended.\n");return 0;
}

輸出結果為:

1 3 5 7 9
Loop ended.

i 為偶數時,continue 語句執行,跳過了當前循環的 printf 語句,直接進入下一次循環迭代。

  • 作用范圍break 是終止整個循環,而 continue 只是中斷當前這一次循環的執行。

  • 代碼執行流程 :使用 break 后,循環直接結束,執行循環體之后的代碼;使用 continue 后,會跳過當前循環的剩余代碼,直接進入下一次循環迭代。

  • 適用場景break 適用于你確定不需要繼續循環的情況;continue 適用于你只是不想執行當前循環的某些代碼,但仍然希望循環繼續進行的情況。

break?的細節補充

  • 在嵌套循環中的表現break 只能終止它所在的最內層循環。如果你有嵌套循環(即一個循環體內部還有另一個循環),break 只會終止最內層的循環,不會影響外層循環。例如:

#include <stdio.h>int main() {for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (j == 1) {break; // 只終止內層循環}printf("i=%d, j=%d\n", i, j);}printf("Inner loop ended.\n");}printf("Outer loop ended.\n");return 0;
}

輸出結果為:

i=0, j=0
Inner loop ended.
i=1, j=0
Inner loop ended.
i=2, j=0
Inner loop ended.
Outer loop ended.

可以看到,break 只終止了內層循環,外層循環仍然繼續執行。

  • switch 語句中的使用break 也可以用在 switch 語句中,用于防止代碼的“穿透”。在 switch 語句中,如果沒有 break,程序會從匹配的 case 開始執行,直到遇到 break 或者 switch 語句結束。例如:

#include <stdio.h>int main() {int num = 2;switch (num) {case 1:printf("One\n");case 2:printf("Two\n");break;case 3:printf("Three\n");break;default:printf("Default\n");}return 0;
}

輸出結果為:

Two

如果沒有在 case 2 后面加 break,程序會繼續執行 case 3default,這就是所謂的“穿透”。

continue?的細節補充

  • 對循環控制變量的影響continue 語句不會影響循環控制變量的更新。例如在 for 循環中,continue 之后循環控制變量仍然會按照正常的邏輯更新。例如:

#include <stdio.h>int main() {for (int i = 0; i < 5; i++) {if (i == 2) {continue; // 跳過當前循環的剩余代碼}printf("i = %d\n", i);}return 0;
}

輸出結果為:

i = 0
i = 1
i = 3
i = 4

可以看到,i 仍然按照正常的邏輯從 0 增加到 4,continue 只是跳過了 i == 2 時的 printf 語句。

  • 在嵌套循環中的表現 :和 break 一樣,continue 也只影響它所在的最內層循環。例如:

#include <stdio.h>int main() {for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (j == 1) {continue; // 只影響內層循環}printf("i=%d, j=%d\n", i, j);}}return 0;
}

輸出結果為:

i=0, j=0
i=0, j=2
i=1, j=0
i=1, j=2
i=2, j=0
i=2, j=2

可以看到,當 j == 1 時,continue 語句跳過了內層循環中 j == 1 的那次迭代,但外層循環仍然正常進行。

3. 其他細節

  • 可讀性 :在使用 breakcontinue 時,要注意代碼的可讀性。過度使用這些語句可能會使代碼邏輯變得復雜,難以理解。例如,如果一個循環中有多個 breakcontinue,可能會讓人難以跟蹤程序的執行流程。在一些情況下,可以通過調整循環條件或者使用標志變量來避免使用 breakcontinue,使代碼更加清晰。

  • 性能影響 :在大多數情況下,breakcontinue 對性能的影響可以忽略不計。它們只是改變了程序的控制流,并沒有進行復雜的計算。但是,在一些極端情況下(例如在非常大的循環中頻繁使用 breakcontinue ),可能會對性能產生一定的影響。不過,這種影響通常比代碼的可讀性和邏輯正確性要次要得多。

  • 與其他控制語句的配合breakcontinue 可以與其他控制語句(如 ifelseswitch 等)配合使用,以實現復雜的控制邏輯。在使用時,要注意它們的優先級和作用范圍,確保程序的邏輯符合預期。例如,在一個 if 語句中使用 breakcontinue,要清楚它們會終止或跳過的是哪個循環。

總之,breakcontinue 是C語言中非常有用的控制語句,但要根據具體的情況合理使用,避免濫用導致代碼難以理解和維護。

1.9.2 循環語句的注意點

推薦書中的內容

  • [規則1 - 36] 思想推薦,但是不強制。另外書中代碼嚴重不推薦,外小內大,一般效率是會高一些,但是差別不會特別大,實際測試的時候,出現效率現象出現反直覺現象,也不要意外。

  • [建議1 - 37] 推薦,給兩個理由:循環次數明確,便于進行十數計算

  • [規則1 - 38] 推薦,代碼量問題要結合場景

  • [規則1 - 39] 部分推薦,代碼量問題要結合場景

  • [規則1 - 40] 推薦,實際工作中,也基本很少遇到

  • [規則1 - 41] 推薦

1.10?goto?關鍵字

基本使用

// 使用goto模擬實現循環
#include <stdio.h>
#include <windows.h>int main()
{int i = 0;START:printf("[\xad]goto running .... \n", i);Sleep(1000);++i;if (i < 10){goto START;}printf("goto end ....\n");system("pause");return 0;
}

可以根據goto關鍵字,直接跳轉到goto后面所指定的標簽所對應的位置處,也就是說如果START:放在后面,goto到標簽的中間的部分就不會執行了!其實我們想要怎么跳轉就怎么跳轉!

goto只能在本代碼塊內進行使用,函數的都不能跨越,文件間就更不用說了!

有什么問題

[規則1 - 42] 推薦

我的建議

很多公司確實禁止使用goto,不過,這個問題我們還是靈活對待,goto在解決很多問題是有有效的。我們可以認為goto引用場景較少,一般不使用,但是必須得知道goto,需要的時候,也必須會用

有人用嗎

Linux內核源代碼中充滿了大量的goto,只能說我們目前,或者很多公司的業務邏輯不是那么復雜


1.11?void?關鍵字

1.11.1?void a

// 問是否可以定義變量
#include <stdio.h>
#include <windows.h>int main()
{void a;system("pause");return 0;
}

為何 void 不能定義變量

定義變量的本質:開辟空間

void作為空類型,理論上是不應該開辟空間的。即使開了空間,也僅僅作為一個占位符看待

所以,既然無法開辟空間,那么也就無法作為正常變量使用,既然無法使用,編譯器干脆就不讓他定義變量了。

  • 在vs2013中,sizeof(void)=1(但編譯器依舊理解成,無法定義變量)
  • 在Linux中,sizeof(void)=1(但編譯器依舊理解成,無法定義變量)

1.11.2 void修飾函數返回值和參數

場景1:void作為函數返回值

// void修飾函數返回值和參數
#include <stdio.h>
#include <windows.h>void show()
{printf("no return value!\n");
}
int main()
{show();system("pause");return 0;
}

如果自定義函數,或者庫函數不需要返回值,那么就可以寫成void

那么問題來了,可以不寫嗎?不可以,自定義函數的默認返回值是int!!!

所以,沒有返回值,如果不是void,會讓閱讀你代碼的人產生誤解:他是不是忘了寫,還是想默認int?

結論:void作為函數返回值,代表不需要,這里是一個“占位符”的概念,是告知編譯器和給閱讀源代碼的工程師看的。

【規則1 - 43】推薦

場景2:void 作為函數參數

// void 作為函數參數
// 如果一個函數沒有參數,我們可以不寫,如test10
#include <stdio.h>
#include <windows.h>int test1() // 函數默認不需要參數
{return 1;
}
int test2(void) // 明確函數不需要參數
{return 1;
}
int main()
{printf("%d\n", test1(10)); // 依舊傳入參數,編譯器不會告警或者報錯printf("%d\n", test2(10)); // 依舊傳入參數,編譯器會告警(vs)或者報錯(gcc)system("pause");return 0;
}

結論:如果一個函數沒有參數,將參數列表設置成void,是一個不錯的習慣,因為可以將錯誤明確提前發現

另外,閱讀你代碼的人,也一眼看出,不需要參數。相當于“自解釋”。

閱讀書中內容,【規則1-44】推薦

題外話,盡管如此,如果這點你不習慣,也不勉強。

1.11.3 void指針

void不能定義變量,那么void*呢?

#include <stdio.h>#include <windows.h>int main()
{void *p = NULL; // 可以system("pause");return 0;
}

為什么void可以呢?因為void是指針,是指針,空間大小就能明確出來

場景:void* 能夠接受任意指針類型

#include <stdio.h>
#include <windows.h>int main()
{void *p = NULL;int *x = NULL;double *y = NULL;p = x; // 同上p = y; // 同上system("pause");return 0;
}

反過來,在vs/gcc中也沒有報錯。書中編譯器很老了,我們嚴重不推薦

結論:但是我們依舊認為,void*的作用是用來接受任意指針類型的。這塊在后面如果想設計出通用接口,很有用

比如:

void *memset ( void * ptr, int value, size_t num );

void * 定義的指針變量可以進行運算操作嗎

【規則1 - 45】現場驗證,各種標準我們了解一下

//在vs2013中
#include <stdio.h>
#include <windows.h>int main()
{void *p = NULL;p++; // 報錯p += 1; // 報錯system("pause");return 0;
}
//在gcc4.8.5中
#include <stdio.h>
#include <stdio.h>int main()
{void *p = NULL; // NULL在數值層面,就是0p++; // 能通過printf("%d\n", p); // 輸出1p += 1; // 能通過printf("%d\n", p); // 輸出2return 0;
}

為什么在不同的平臺下,編譯器會表現出不同的現象呢?

根本原因是因為使用的c標準版本的問題。具體閱讀書。

void * 用來設計通用接口

【規則1 - 46】推薦

1.11.4 void不能代表一個真實的變量

已經講過,此處略過

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

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

相關文章

Linux相關概念和易錯知識點(43)(數據鏈路層、ARP、以太網、交換機)

目錄1.從網絡層到數據鏈路層&#xff08;1&#xff09;MAC地址&#xff08;2&#xff09;IP地址和MAC地址的區別&#xff08;3&#xff09;ARP&#xff08;4&#xff09;不同層之間的關系2.以太網&#xff08;1&#xff09;以太網的幀格式&#xff08;2&#xff09;數據分片的原…

【科研繪圖系列】R語言繪制多擬合曲線圖

禁止商業或二改轉載,僅供自學使用,侵權必究,如需截取部分內容請后臺聯系作者! 文章目錄 介紹 加載R包 數據下載 函數 導入數據 數據預處理 畫圖 總結 系統信息 介紹 本文通過R語言對海洋微生物群落的動態變化進行了深入分析,并通過可視化技術直觀展示了不同環境條件下微…

【React】React 哲學

1. 聲明式&#xff08;Declarative&#xff09; React 鼓勵開發者 描述 UI 應該是什么樣子&#xff0c;而不是逐步操作 DOM。 // 聲明式 function Greeting({ name }) {return <h1>Hello, {name}</h1>; }不用手動操作 DOM&#xff08;document.getElementById / in…

一、Python開發準備

目錄 一、前言 1、什么是python&#xff0c;為什么學習python? 2、python語言的特點&#xff0c;以及應用場景是什么&#xff1f; 二、前期準備 1、下載python 2、右鍵管理員身份安裝 3、將Python環境配置到環境變量中 三、開發工具 1、開發工具介紹 一、前言 1、什么…

Visual Studio 發布項目 win-86 win-64 win-arm win-arm64 osx-64 osx-64 osx-arm64 ...

Visual Studio 發布項目時&#xff0c;常見的目標平臺標識符代表不同的操作系統和處理器架構組合[TOC]( Visual Studio 發布項目時&#xff0c;常見的目標平臺標識符代表不同的操作系統和處理器架構組合) 以下是詳細解釋及對比列表&#xff1a;一、基礎概念解析二、各平臺標識符…

Redis數據結構之Hash

一、Hash類型簡介 Redis的Hash類型是 Redis 3.2 版本引入的一個數據結構,它允許你在一個鍵下面存儲多個字段和值。在 Redis 內部,Hash 類型可以有多種底層數據結構來實現,這取決于存儲的數據量和特定的使用模式。哈希類型適用于存儲對象,例如用戶信息、商品詳情等。通過使…

【Linux系統】初見線程,概念與控制

前言&#xff1a; 上文我們講到了進程間信號的話題【Linux系統】萬字解析&#xff0c;進程間的信號-CSDN博客 本文我們再來認識一下&#xff1a;線程&#xff01; Linux線程概念 什么是線程 概念定義&#xff1a; 進程內核數據結構代碼和數據&#xff08;執行流&#xff09; 線…

計算機視覺與深度學習 | 具身智能研究綜述:從理論框架到未來圖景

具身智能研究綜述:從理論框架到未來圖景 文章目錄 具身智能研究綜述:從理論框架到未來圖景 一、定義與核心特征 二、關鍵技術體系 2.1 感知-運動融合技術 2.2 認知架構 2.3 強化學習進展 三、發展歷程與里程碑 3.1 理論奠基期(1990-2005) 3.2 技術探索期(2006-2015) 3.3 …

玩轉deepseek之自動出試卷可直接導出word

小伙伴們&#xff0c;最近有新同事入職&#xff0c;經理讓我出一個關于sqlserver相關的試卷&#xff0c;想著既然有deepseek&#xff0c;我們就偷懶下直接用deepseek給我們自動生成出來。打開deepseek官網&#xff0c;輸入提示詞&#xff1a;出一套SQL的試題要有基礎考察&#…

Flutter 語聊房項目 ----- 禮物特效播放

在語聊房項目中&#xff0c;禮物特效播放是一個常見的需求&#xff0c;通常包括動畫、聲音等多種媒體形式。為了處理不同的禮物類型&#xff0c;我們可以采用抽象的設計方法&#xff0c;使得系統易于擴展和維護。設計架構思路&#xff1a;抽象禮物特效接口&#xff1a;定義一個…

如何實現文件批量重命名自動化

在編程、設計、數據處理等工作中&#xff0c;腳本或軟件往往要求文件名符合特定格式。 批量重命名可快速將文件調整為所需命名規則&#xff0c;避免手動操作出錯。 它的體積不到300KB&#xff0c;解壓后直接運行&#xff0c;完全綠色無安裝。 界面清爽&#xff0c;操作直觀&a…

【數據結構——圖與鄰接矩陣】

引入 樹的遍歷方式可分為深搜和廣搜&#xff0c;這同樣適用于圖&#xff0c;不過有些地方會有出入。 樹的節點結構從根到葉子節點都是1&#xff1a;n,到葉子節點后就沒有了。而對于圖來說&#xff0c;如果到了最底下的節點&#xff0c;它可能除了連接已經記錄過的上層節點&am…

Quarkus - 超音速亞原子Java,開啟云原生應用新視界!

Quarkus - 超音速亞原子Java框架 Quarkus 是一個以云為中心、優先考慮&#xff08;Linux&#xff09;容器的框架&#xff0c;專為編寫 Java 應用而設計。它旨在幫助開發者更輕松地構建和部署大規模的容器化 Java 應用&#xff0c;采用了一系列現代開發理念和標準。 核心特點 …

如何查看GPU運行情況:使用 Conda 安裝 nvitop 新手指南

文章目錄 ?? 1. 為什么推薦使用 Conda 環境安裝 ?? 2. 安裝步驟 步驟 1: 安裝 Miniconda 或 Anaconda (如果你還沒有安裝的話) 步驟 2: 創建并激活一個專門的 Conda 環境 步驟 3: 在 Conda 環境中安裝 nvitop 步驟 4: 驗證安裝 ?? 3. 疑難解答 ?? 4. nvitop 的基本使用…

遙感機器學習專欄簡介

專欄定位與受眾本專欄聚焦「機器學習 遙感應用」的落地實踐&#xff0c;專為遙感相關專業大學生、剛入門的遙感工程師、機器學習愛好者打造。避開純理論堆砌&#xff0c;以「實驗課式實操」為核心&#xff0c;幫你解決 “懂理論但不會用代碼落地”“遙感數據處理與模型結合難”…

【更新至2024年】1996-2024年各省農業總產值數據(無缺失)

【更新至2024年】1996-2024年各省農業總產值數據&#xff08;無缺失&#xff09; 1、時間&#xff1a;1996-2024年 2、來源&#xff1a;國家統計局、各省年檢 3、指標&#xff1a;農業總產值 4、范圍&#xff1a;31省 5、缺失情況&#xff1a;無缺失 6、指標解釋&#xf…

大語言模型預訓練流程

大語言模型訓練流程 Pre-training → SFT → RLHF階段1&#xff1a;預訓練Pre-training 海量無標注文本數據訓練自監督學習機制學習語言基礎知識掌握語法、語義、常識形成語言表示能力 核心目標&#xff1a;建立模型的語言理解和文本生成基礎能力 階段2&#xff1a;監督微調Sup…

Zookeeper:分布式協調服務

一、概念ZooKeeper 是一個分布式的、開源的分布式應用程序協調服務&#xff0c;為分布式應用提供一致性、配置管理、命名服務、分布式同步和組服務等。可以把它想象成一個為分布式系統提供的“文件系統”“通知機制”&#xff0c;但它存儲的不是普通的文件&#xff0c;而是少量…

海盜王客戶端BMP紋理圖片解密

海盜王客戶端的紋理貼圖bmp文件有些是加密&#xff0c;很多人想解密并修改替換&#xff0c;現在給出解密的python代碼&#xff1a; import os import struct import copy from pathlib import Pathclass TexEncode:def __init__(self):self.MAGIC_BYTES bmp.x # 魔法字節標識…

《鏈式二叉樹常用操作全解析》

目錄 一.求鏈式二叉樹節點個數 二.求鏈式二叉樹葉子節點個數 三.求鏈式二叉樹第k層節點個數 四.求鏈式二叉樹的深度/高度 五.鏈式二叉樹查找值為x的節點 六.鏈式二叉樹的銷毀 七. 測試函數 八. 總結: 前言: 在學習鏈式二叉樹的常用操作之前 我們需要手動創建一個二叉樹 在…