編程技能:格式化打印04,sprintf

專欄導航

本節文章分別屬于《Win32 學習筆記》和《MFC 學習筆記》兩個專欄,故劃分為兩個專欄導航。讀者可以自行選擇前往哪個專欄。

(一)WIn32 專欄導航

上一篇:編程技能:格式化打印03,printf

回到目錄

下一篇:無

(二)MFC 專欄導航

上一篇:編程技能:格式化打印03,printf

回到目錄

下一篇:無

本節前言

在上一節,我們講解了 printf 的實現代碼。

本節,我們來講解與之相近的 sprintf 的實現代碼。

對于本節的講解,是基于 vsprintf 的知識的。

如果你尚未學習過 vsprintf 的知識,請參考下述鏈接所示的文章。

編程技能:格式化打印02,vsprintf-CSDN博客

確保你理解了 vsprintf 的大致邏輯之后,接下來,我們來學習 printf 的實現代碼。

在本節里面,我會用到三個術語。他們分別是【棧指針】,【格式字符串】和【參數列表】。這三個術語,均可以從 vsprintf 文章鏈接中找到。如果你不懂這些術語,請你先去上面的 vsprintf 文章鏈接中,學習好 vsprintf ,然后再進行本節的學習。

我們開始本節的講解。

一.? ? sprintf 函數的實現代碼

代碼如下。

extern int sprintf(char * str, const char *fmt, ...)
{va_list args;int i;va_start(args, fmt);i = vsprintf(str, fmt, args);va_end(args);return i;
}

這段代碼,改編自 Linux 0.12 內核。絕大部分的代碼,都與 0.12 內核一樣。但是呢,我也的確是作出了一點小小的改動。

二.? ? 調用 sprintf 函數的三個案例

下面是案例1 的代碼。

static char buf01[300];
void func01(void)
{int i, a, c;float b;a = 90;b = 3.14;c = 1024;i = sprintf(buf01, "a = %d,b = %f,c = %x", a, b, c);return;
}

以上為案例1 的代碼。

下面是案例2 的代碼。

static char buf02[300];
void func02(void)
{int i;i = sprintf(buf02, "小雪的兜里有 %d 塊錢", 100);return;
}

以上為案例 2 的代碼。

下面是案例3 的代碼

static char buf03[300];
void func03(void)
{int i;i = sprintf(buf03, "I have a pen");return;
}

以上為案例3 的代碼。

這幾個代碼,我們在下面的講解中,隨時會引用。大家需要瀏覽一下這幾個代碼。一會兒,你需要隨時來查閱對照這幾個案例代碼。

三.? ? sprintf 的函數頭部

sprintf 的函數頭部如下。

extern int sprintf(char * str, const char *fmt, ...)

對于此函數的返回值,我們先不去講。我們來看看它的各個參數。

(一)緩沖區

第一個參數,是字符指針 str 。這個字符指針,是由調用 sprintf 的函數提供的。

第二分節的案例1 代碼里,包含有下述兩行代碼。

static char buf01[300];

i = sprintf(buf01,?"a = %d,b = %f,c = %x",?a, b, c);

在案例1 里面,我們聲明了一個大的字符數組,里面包含 300 個元素。數組名為 buf01 。數組元素為 char 型,所以,數組名為字符指針。而在案例1 的調用 sprintf 函數的代碼中,傳入的第一個參數,為字符數組名 buf01 。

在案例2 和案例3 里面,也有類似的代碼邏輯。也就是,申請了一個大的字符數組。同時,在調用 sprintf 函數的時候,給 sprintf 傳入的第一個參數,是這個字符數組的數組名。

一般地,我們平時在申請數組的時候,不會讓數組包含著這么多的元素個數。然而,在本節的第二分節的三個案例代碼里面,我們的確是分別申請了一個大的字符數組。

申請這么大的數組干嘛?

一般來講,當我們選擇申請一個尺寸很大的數組的時候,我們是想要用它來臨時地保存某些數據。這種臨時地保存某些數據的,尺寸很大的數組,我們可以給它換一個名字,緩沖區

在 Linux 0.12 內核里面,為了實現 printf 函數,它是申請了包含 1024 個 char 型元素的字符數組,作為緩沖區,來給 printf 函數使用。

關于緩沖區的概念,其實,大家在基礎的 C 語言學習中,大家也聽說過的。那就是鍵盤緩沖區

在 Linux 0.12 內核里面,就包含有一個鍵盤緩沖區,它也是用包含著 1024 個元素的大數組,來作為鍵盤緩沖區的。

buf,常常用作【緩沖區】的含義,它是 buffer 的簡寫。

我們接著往下講。

(二)格式字符串

在 sprintf 的函數頭部里面,第二個參數,為【const char *fmt】。從這里可以看出,本參數用來接收一個字符串,并且,由于 const 關鍵字的存在,我們不可以通過字符指針 fmt 對這個接收的字符串進行任何改動,而只是可以使用其值。

在這里,我將 fmt 接收的字符串,稱作格式字符串

所謂的格式字符串,是說,它里面,可能會含有 %d,%c,%f,%s 等等的格式控制符。

在代碼【printf("a = %d,b = %f,c = %x", a, b, c);】中,【"a = %d,b = %f,c = %x"】是格式字符串。類似地,在本文的的第二分節的案例1 代碼里面,在代碼【i = sprintf(buf01, "a = %d,b = %f,c = %x", a, b, c);】中,?【"a = %d,b = %f,c = %x"】也是格式字符串,由sprintf 的第二個形參 fmt 來接收。

在代碼【printf("小雪的兜里有 %d 塊錢", 100);】里面,【"小雪的兜里有 %d 塊錢"】是格式字符串。類似地,在本文的的第二分節的案例2?代碼里面,在代碼【i = sprintf(buf02, "小雪的兜里有 %d 塊錢", 100);】中,?【"小雪的兜里有 %d 塊錢"】也是格式字符串,由sprintf 的第二個形參 fmt 來接收。

在代碼【printf("I have a pen");】里面,【"I have a pen"】是格式字符串。類似地,在本文的的第二分節的案例3?代碼里面,在代碼【i = sprintf(buf03, "I have a pen");】中,?【"I have a pen"】也是格式字符串,由sprintf 的第二個形參 fmt 來接收。

格式字符串,里面可以包含有 %d 等等的格式控制符,也可以不包含。

到了這里,sprintf 的第二個形參我們就講完了。我們接著講。

(三)可變參數

在 sprintf 函數頭部里面,在 fmt 形參的右邊,是【...】,這個東西,不是省略號。你也可以在你自己的代碼里面包含這樣的東西。不過呢,使用的時候,是三個英文句點,不可以是中文的三個句點。在數量上,必須是三個,多一個不行,少一個也不行。

這個【...】,有一個專有名字,叫做可變參數

可變參數,是說,它的數目是可變的,每一個參數的數據類型也是可變的,沒有固定的范式。在數目方面,可變參數中,可以包含有一個參數,兩個參數,或者多個參數,也可以不包含參數。

在代碼【printf("a = %d,b = %f,c = %x", a, b, c);】中,【a, b, c】的部分,便是可變參數部分。類似地,在本文的的第二分節的案例1 代碼里面,在代碼【i = sprintf(buf01, "a = %d,b = %f,c = %x", a, b, c);】中,【a, b, c】的部分,也是可變參數部分。在此代碼示例中,可變參數部分含有三個參數。

在代碼【printf("小雪的兜里有 %d 塊錢", 100);】中,【100】的部分,為可變參數部分。類似地,在本文的的第二分節的案例2?代碼里面,在代碼【i = sprintf(buf02, "小雪的兜里有 %d 塊錢", 100);】中,【100】的部分,也是可變參數部分。在此代碼示例中,可變參數部分含有一個參數。

在代碼【printf("I have a pen");】里面,可變參數部分無參數。類似地,在本文的的第二分節的案例3?代碼里面,在代碼【i = sprintf(buf03, "I have a pen");】中,可變參數部分也是沒有參數的。

在大家平時寫代碼的時候,應該不太會去使用可變參數的。不過,這次,我們要來學習 printf,vsprintf,sprintf 等等的打印函數,那就需要來接觸可變參數了。

我盡力去講,希望大家能夠學好可變參數

到了這里,sprintf 的函數頭部,我們就先進行到這里。返回值,后面會有講解。

四.? ? va_list

我們來看下圖的紅色框線部分的代碼。

圖1

圖1 中的紅色框線部分,是變量聲明。【int i;】,這個簡單,聲明了一個整型變量 i 。問題在于【va_list args;】這一部分,需要去講解一下的,是 va_list 。va_list,是【char *】的意思。

請看下面的參考代碼。

typedef char *va_list;

va_list,是【char *】的別名。這樣一來,由 va_list 聲明的 args 變量,便是一個【char *】類型的變量。

在這里,我來講一講 va_list 的含義。va_list 中的 va,是【variable argument】的意思,翻譯過來,就是可變參數的意思。list,是列表的含義。所以呢,va_list,整個的意思就是【可變參數列表】。用【可變參數列表】類型 va_list 聲明的變量為 args,它是 arguments 的簡寫,就是【各個參數】的意思。

我們接著往下看。

五.? ? va_start

我們來看下圖中的紅色框線部分的代碼。

圖2

va_start,直接翻譯,就是【可變參數開始】的意思。其實,它是用來對可變參數變量 args 進行初始化的宏函數

va_start,從它的使用方法上看,似乎是一個函數。實際上,它是一個宏。對于這種,實際上為宏,而外形為函數的東西,我將其稱作宏函數。別的地方咋叫我記不清了。反正我就管它叫宏函數

va_start,它的宏代碼,具體是什么,在這里,我不展開。原因在于,想要徹底理解其宏代碼,你需要具備匯編語言基礎。在設計本專欄教程的時候,我的一個基本的假定,就是,各位讀者并不具備匯編語言基礎。我希望在各位并不具備匯編語言基礎的情況下,也能夠看懂本專欄教程。

由于假定各位不懂匯編語言,所以,va_start 的宏代碼,我就不去細講了。但是呢,它的功能,我還得來說一說的。

va_start(args, fmt) 的意思是說,將可變參數變量 args,賦值為?fmt 右邊的可變參數列表中第一個變量的棧指針

棧指針又是什么?

我們在講解 vsprintf 的時候,有去詳細講它。

在講解 vsprintf 的時候,我們所給出的棧指針的大致含義如下。

A 函數調用 B 函數的時候,會將 B 函數所需要的參數,也就是傳遞給 B 函數的實參,壓入棧中。完成了參數入棧的工作以后,CPU 才會前往執行 B 函數的代碼。那么,A 函數所傳遞的某一個參數在棧中的位置,就是這個實參的棧指針

在這里,如果你需要進一步理解棧指針的含義,那么,你可以參考 vsprintf 的講解。講解 vsprintf 的文章鏈接如下所示。

編程技能:格式化打印02,vsprintf-CSDN博客

不過,說實話,我在講解 vsprintf 的時候,對棧指針的講解,做不到讓你徹底地理解棧指針的含義。因為,想要徹底地理解棧指針的概念,你需要具備匯編語言基礎。此處,你只要能夠模糊地,大致地理解棧指針的概念就可以了。

我們接著往下講。

為了輔助大家理解 va_start 的含義,我們來舉幾個例子。

在案例1 中的代碼【i = sprintf(buf01, "a = %d,b = %f,c = %x", a, b, c);】中,在調用了 sprintf 函數以后,在 sprintf 函數內部,代碼【va_start(args, fmt);】的執行,會將?args 賦值為格式字符串【"a = %d,b =?%f,c = %x"】右邊的可變參數列表中的第一個參數,a 的棧指針

在案例2?中的代碼【i = sprintf(buf02, "小雪的兜里有 %d 塊錢", 100);】里面,在調用了 sprintf 函數以后,在 sprintf 函數內部,代碼【va_start(args, fmt);】的執行,會將?args 賦值為格式字符串【"小雪的兜里有 %d 塊錢"】右邊的可變參數列表中的第一個參數,【100】的棧指針

在案例3?中的代碼【i = sprintf(buf03, "I have a pen");】里面,可變參數部分無參數。在這種情況下,代碼【va_start(args, fmt);】的執行也會令 args 指向一個東西,不過,在可變參數部分無參數的情況下,args 究竟是指向啥,我們就不必關心了。我們暫時只關心可變參數列表中至少含有一個參數的情形,并且將可變參數列表中包含至少一個參數的情形視為典型。

再次重復一下,va_start(args, fmt) 的意思是說,將可變參數變量 args,賦值為?fmt 所指向的格式字符串右邊的可變參數列表中的第一個變量的棧指針

正是在 va_start 宏函數的作用之下,可變參數列表中的第一個參數的棧指針,被提取出來了。

不知道,你理解得是否費勁兒。反正,此刻,我是覺得,講得挺費勁兒的。

接著來吧。

六.? ? 調用 vsprintf

我們接著看下圖的紅色框線所示的代碼。

圖3

在圖3 的紅色框線部分,我們調用了 vsprintf 函數,傳給它的三個參數,分別是由上一級的調用函數傳過來的字符緩沖區指針【str】,格式字符串的指針【fmt】,還有可變參數列表中第一個參數的棧指針【args】。

vsprintf 函數的功能,是根據 fmt 與 args,對 fmt 所指向的格式字符串進行格式化轉換,轉換結果放在字符緩沖區指針 str 所指向的字符數組里面。格式化轉換的工作完成以后,str 中的字符串的不含 NUL 結束符的有效字符長度,會作為返回值,予以返回。在圖3 里面,這個返回值由 int 型變量 i 來接收了。

vsprintf 是如何進行格式化轉換的,請大家參考 vsprintf 文章鏈接,鏈接如下。

編程技能:格式化打印02,vsprintf-CSDN博客

不過呢,在這里,雖說我不想細講 vsprintf 的執行過程。不過呢,我還是想要舉幾個例子。

例如,在執行本文第二分節的案例1 中的代碼【i = sprintf(buf01, "a = %d,b = %f,c = %x", a, b, c);】以后,sprintf 會在內部調用 vsprintf 。 vsprintf 會根據格式字符串【"a = %d,b =?%f,c = %x"】與可變參數列表中第一個參數的棧指針,對格式字符串進行格式化轉換。對于案例1 而言,格式化轉換的結果為【"a = 90,b = 3.14,c = 400"】,這個轉換結果會被存放在 str 緩沖區里面,或者說是存放在案例1 中的 buf01 緩沖區里面。十進制 1024?的十六進制值為 0x400?。我在格式字符串里面,沒有給十六進制值加上十六進制前綴,你可以自己添加啊。這里,我偷個懶。

再比如,在執行本文第二分節的案例2?中的代碼【i = sprintf(buf02, "小雪的兜里有 %d 塊錢", 100);】以后,sprintf 會在內部調用 vsprintf 。 vsprintf 會根據格式字符串【"小雪的兜里有 %d 塊錢"】與可變參數列表中第一個參數的棧指針,對格式字符串進行格式化轉換。格式化轉換的結果為【"小雪的兜里有 100?塊錢"】,這個轉換結果會被存放在 str 緩沖區里面,或者說是存放在案例2 中的 buf02 緩沖區里面。

再比如,在執行本文第二分節的案例3?中的代碼【i = sprintf(buf03, "I have a pen");】以后,sprintf 會在內部調用 vsprintf 。 vsprintf 會根據格式字符串【"I have a pen"】與可變參數列表中第一個參數的棧指針,對格式字符串進行格式化轉換。在此例子代碼中,由于格式字符串里面不含有格式控制符,可變參數列表里面也不含有參數,因此,vsprintf 的工作,是直接把字符串【"I have a pen"】放在 str?緩沖區中,或者說是存放在案例3 中的 buf03 緩沖區中,而并不需要專門的格式化轉換工作。

我們接著往下看。

七.? ? va_end

我們來看下圖的紅色框線部分所示的代碼。

圖4

va_end,依然是一個宏函數

va_end(args),它的作用,是將 args 置空。由于 args 是 va_list 類型的,也就是【char *】類型,所以呢,【va_end(args);】的作用,相當于執行代碼【args = NULL;】。就這么簡單。在這里,我將 va_end 的宏代碼給展示一下。

#define va_end(AP) (AP = NULL)

這個宏代碼,應該是不難吧?

如果不理解的話,請查閱 C 語言基礎知識教材。

在 va_start 宏函數里面,初始化了 args 變量。在調用 vsprintf 的時候,使用了 args 變量。最后呢,在 va_end 宏函數里面,清理了 args 變量。

我們接著往下看。

八.? ? 打印輸出與返回

請先看下圖的紅色框線所示的代碼。

圖5

圖5 中的紅色框線部分,是返回語句【return i】。

關于變量 i,在本文的第六節中,講解 vsprintf 函數調用的時候,我談到了,vsprintf 會將完成了格式化轉換工作以后,保存在 str 緩沖區中的字符串的不含有 NUL 結束符的有效字符長度作為返回值,予以返回。這個返回值,被賦值給 int 型變量 i 了。

所以呢,此時,變量 i 里面所保存的,是 str 緩沖區中的字符串的不含有 NUL結束符的有效字符長度。

而在 sprintf 函數實現代碼的末尾,這個有效字符長度,再一次作為返回值,予以返回了。

在我的學習經歷中,這個返回值,還是有用的。至于究竟是如何來使用,我們在以后的 Windows 編程教程中,會見到的。

WIndows 編程,我打算分為 Win32 與 MFC 兩塊來講。在 MFC 專欄里面,可能對 sprintf 用得不多。然而,在 Win32 專欄里面,我們用 sprintf 會多一些。當然了,我們不是直接用 sprintf ,而是用它的 WIndows 版本,wsprintf 函數。

九.? ? sprintf 函數總結

我們對 sprintf 的函數功能進行一個小小的總結。

我們還是先來看一下 sprintf 的函數頭部。

extern int sprintf(char * str,?const char *fmt, ...);

sprintf 函數的功能,根據 fmt 所指向的格式字符串可變參數列表中第一個參數的棧指針,對格式字符串進行格式化轉換工作。轉換好的字符串,會被存放在 str 緩沖區里面。函數的返回值格式化轉換工作完成以后,存放在?str 緩沖區中的字符串的不含有 NUL 結束符的有效字符長度

對函數返回值部分,我特意用橄欖色的粗體字來標識了。我還是再來重復一下。簡單地來講,sprintf 函數的返回值,為有效字符長度

到了這里,本節的講課任務就都完成了。

結束語

相比上一節講解 printf 的時候來講,本節的寫作,算是輕松了一些,因為大部分都是復制粘貼。然而,也還有許多東西是需要去修改的。

sprintf,我認為是比較重要的函數。希望大家能夠學習好它。

其實,到了這里,主體任務,vsprintf,printf,sprintf,這三大格式化打印函數,我們就都講完了。到了這里,格式化打印部分,可以說是完成了。

不過,我還想要補充一點東西。那就是,對于格式控制符,它還有一些個東西,我想要去補充補充。也許,這個補充是不必要的。不過,我還是想要補充一下。

下一節,將會是格式化打印板塊的最后一節。同時,Windows 編程的預備知識部分,也將在下一節畫上句號。

本節結束。

專欄導航

本節文章分別屬于《Win32 學習筆記》和《MFC 學習筆記》兩個專欄,故劃分為兩個專欄導航。讀者可以自行選擇前往哪個專欄。

(一)WIn32 專欄導航

上一篇:編程技能:格式化打印03,printf

回到目錄

下一篇:無

(二)MFC 專欄導航

上一篇:編程技能:格式化打印03,printf

回到目錄

下一篇:無

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

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

相關文章

JavaScript性能優化實戰:深入探討JavaScript性能瓶頸與優化技巧

引言:為什么JavaScript性能至關重要 在現代Web開發中,JavaScript已成為構建交互式應用程序的核心技術。隨著單頁應用(SPA)和復雜前端架構的普及,JavaScript代碼的性能直接影響用戶體驗、轉化率甚至搜索引擎排名。研究表明,頁面加載時間每增加1秒,轉化率可能下降7%,而性能…

Java數據結構——八大排序

排序 插?排序希爾排序直接選擇排序堆排序冒泡排序快速排序歸并排序計數排序 排序的概念 排序:就是將一串東西,按照要求進行排序,按照遞增或遞減排序起來 穩定性:就是比如排序中有兩個相同的數,如果排序后&#xff0c…

WPF響應式UI的基礎:INotifyPropertyChanged

INotifyPropertyChanged 1 實現基礎接口2 CallerMemberName優化3 數據更新觸發策略4 高級應用技巧4.1 表達式樹優化4.2 性能優化模式4.3 跨平臺兼容實現 5 常見錯誤排查 在WPF的MVVM架構中, INotifyPropertyChanged是實現數據驅動界面的核心機制。本章將深入解析屬…

低空城市場景下的多無人機任務規劃與動態協調!CoordField:無人機任務分配的智能協調場

作者:Tengchao Zhang 1 ^{1} 1 , Yonglin Tian 2 ^{2} 2 , Fei Lin 1 ^{1} 1, Jun Huang 1 ^{1} 1, Patrik P. Sli 3 ^{3} 3, Rui Qin 2 , 4 ^{2,4} 2,4, and Fei-Yue Wang 5 , 1 ^{5,1} 5,1單位: 1 ^{1} 1澳門科技大學創新工程學院工程科學系&#xff0…

解決Java項目NoProviderFoundException報錯

前言 在Java開發中,jakarta.validation.NoProviderFoundException 是一個令人困惑的運行時錯誤,常因校驗框架依賴缺失或版本沖突導致。 問題復現:用戶注冊校驗失敗 業務場景 開發一個用戶注冊功能,要求: 校驗郵箱…

重構跨境收益互換價值鏈:新一代TRS平臺的破局之道

當香港券商面對內地洶涌的結構化產品需求,一套智能化的TRS系統正成為打開萬億市場的金鑰匙 在跨境金融的暗流涌動中,一家中資背景的香港券商正面臨甜蜜的煩惱:內地高凈值客戶對港股、美股的杠桿交易需求激增,但傳統TRS業務深陷操作…

實驗設計如何拯救我的 CEI VSR 28G 設計

為了確定總體設計裕量,CEI 28G VSR/100 Gb 以太網設計需要分析 500 萬種通道變化、收發器工藝和均衡設置的組合。蠻力模擬需要 278 天,這顯然超出了可用的時間表。 相反,我們使用實驗設計 (DOE) 和響應面建模 &#x…

【仿生機器人】刀劍神域——愛麗絲蘇醒計劃,需求文檔

仿生機器人"愛麗絲"系統架構設計需求文檔 一、硬件基礎 已完成頭部和頸部硬件搭建 25個舵機驅動表情系統 頸部旋轉功能 眼部攝像頭(視覺輸入) 麥克風陣列(聽覺輸入) 頸部發聲裝置(語音輸出&#xff09…

【Day44】

DAY 44 預訓練模型 知識點回顧: 預訓練的概念常見的分類預訓練模型圖像預訓練模型的發展史預訓練的策略預訓練代碼實戰:resnet18 作業: 嘗試在cifar10對比如下其他的預訓練模型,觀察差異,盡可能和他人選擇的不同嘗試通…

python打卡訓練營打卡記錄day44

知識點回顧: 預訓練的概念常見的分類預訓練模型圖像預訓練模型的發展史預訓練的策略預訓練代碼實戰:resnet18 作業: 嘗試在cifar10對比如下其他的預訓練模型,觀察差異,盡可能和他人選擇的不同嘗試通過ctrl進入resnet的…

Vue跨層級通信

下面,我們來系統的梳理關于 Vue跨層級通信 的基本知識點: 一、跨層級通信核心概念 1.1 什么是跨層級通信 跨層級通信是指在組件樹中,祖先組件與后代組件(非直接父子關系)之間的數據傳遞和交互方式。這種通信模式避免了通過中間組件層層傳遞 props 的繁瑣過程。 1.2 適用…

webPack基本使用步驟

webPack基本使用步驟 關于webPackwebPack配置的幾個概念entry(入口)output(輸出)loader(輸出)plugin(插件)mode(模式) 基本使用過程示例1.創建測試目錄和代碼…

龍虎榜——20250604

上證指數縮量收陽線,量能依然在5天線上,股價也在5天線上。 深證指數放量收陽線,量能站上5天均線,但仍受中期60天均線壓制。 2025年6月4日龍虎榜行業方向分析 1. 黃金 代表標的:曼卡龍、菜百股份。 驅動邏輯&#…

Viggle:開啟視頻人物替換新紀元

Viggle 的出現,為視頻人物替換帶來了前所未有的變革,為創作者和愛好者們打開了一扇通往無限可能的大門。 一、Viggle 技術原理剖析 Viggle 是一款基于先進人工智能技術的創新平臺,其核心在于能夠精準實現靜態圖片與動態視頻的融合轉化。它…

【BUG解決】關于BigDecimal與0的比較問題

這是一個很細小的知識點,但是很容易被忽略掉,導致系統問題,因此記錄下來 問題背景 明明邏輯上看a和b都不為0才會調用除法,但是系統會報錯:java.lang.ArithmeticException異常: if (!a.equals(BigDecimal…

千年之后再出發,銅官窯駛入微短劇的數字航道

過去一年里,微短劇已經成為走向全民關注、平臺扶持、政策引導的“內容新主流”。從市值百億的爆款平臺到走出國門的“短劇出海”,微短劇正在重塑中國數字文化的表達方式與產業結構,也成為各地競相爭奪的“新藍海”。 就在這樣的背景下&#…

數據庫管理-第333期 Oracle 23ai:RAC打補丁完全不用停機(20250604)

數據庫管理333期 2025-06-04 數據庫管理-第333期 Oracle 23ai:RAC打補丁完全不用停機(20250604)1 概念2 要求3 操作流程4 轉移失敗處理總結 數據庫管理-第333期 Oracle 23ai:RAC打補丁完全不用停機(20250604&#xff0…

Trae CN IDE自動生成注釋功能測試與效率提升全解析

Trae CN IDE 的自動注釋功能可以通過 AI 驅動的代碼分析生成自然語言注釋,以下是具體測試方法和優勢總結: 一、Python 代碼注釋生成測試 1. 測試環境 IDE:Trae CN IDE(需確認支持 Python)代碼示例: def …

軟考 系統架構設計師系列知識點之雜項集萃(79)

接前一篇文章:軟考 系統架構設計師系列知識點之雜項集萃(78) 第141題 軟件測試一般分為兩個大類:動態測試和靜態測試。前者通過運行程序發現錯誤,包括()等方法;后者采用人工和計算機…

有公網ip但外網訪問不到怎么辦?內網IP端口映射公網連接常見問題和原因

有公網IP但外網訪問不到的核心原因通常包括:端口未正確映射、防火墻限制、DNS解析問題、運營商端口屏蔽或路由配置錯誤?。需依次排查這些關鍵環節,其中端口映射和防火墻設置是最常見的原因。?? ?內網IP端口映射公網連接常見問題和原因及解決方案 1…