預處理

C語言##預算符

和#運算符一樣,##運算符可以用于宏函數的替換部分。這個運算符把兩個語言符號組合成單個語言符號。看例子:
? ?#define XNAME(n) x ## n
如果這樣使用宏:
? ?XNAME(8)
則會被展開成這樣:
? ?x8
看明白了沒? ##就是個粘合劑,將前后兩部分粘合起來。

C語言#運算符

#也是預處理?是的,你可以這么認為。那怎么用它呢? 別急,先看下面例子:
? ?#define SQR(x) printf("The square of x is %d.\n", ((x)*(x)));
如果這樣使用宏:
? ?SQR(8);
則輸出為:
? ?The square of x is 64.
注意到沒有,引號中的字符x 被當作普通文本來處理,而不是被當作一個可以被替換的語言符號。

假如你確實希望在字符串中包含宏參數,那我們就可以使用“#”,它可以把語言符號轉化為字符串。上面的例子改一改:
? ?#define SQR(x) printf("The square of "#x" is %d.\n", ((x)*(x)));
再使用:
? ?SQR(8);
則輸出的是:
? ?The square of 8 is 64.

很簡單吧?相信你現在已經明白#號的使用方法了。

C語言#pragma預處理

在所有的預處理指令中,#pragma 指令可能是最復雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma 指令對每個編譯器給出了一個方法,在保持與C 和C ++語言完全兼容的情況下,給出主機或操作系統專有的特征。依據定義,編譯指示是機器或操作系統專有的,且對于每個編譯器都是不同的。

其格式一般為:
? ?#pragma para
其中para 為參數,下面來看一些常用的參數。

一、#pragma message

message 參數:Message 參數是我最喜歡的一個參數,它能夠在編譯信息輸出窗口中輸出相應的信息,這對于源代碼信息的控制是非常重要的。其使用方法為:
? ?#pragma message(“消息文本”)
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本打印出來。

當我們在程序中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什么地方定義了_X86 這個宏可以用下面的方法
? ?#ifdef _X86
? ?#Pragma message(“_X86 macro activated!”)
? ?#endif
當我們定義了_X86 這個宏以后,應用程序在編譯時就會在編譯輸出窗口里顯示“_X86 macro activated!”。我們就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。

二、#pragma code_seg

另一個使用得比較多的pragma 參數是code_seg。格式如:
? ?#pragma code_seg( ["section-name"[,"section-class"] ] )
它能夠設置程序中函數代碼存放的代碼段,當我們開發驅動程序的時候就會使用到它。

三、#pragma once

#pragma once (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在Visual C++6.0 中就已經有了,但是考慮到兼容性并沒有太多的使用它。

四、#pragma hdrstop

#pragma hdrstop 表示預編譯頭文件到此為止,后面的頭文件不進行預編譯。BCB 可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁盤空間,所以使用這個選項排除一些頭文件。

有時單元之間有依賴關系,比如單元A 依賴單元B,所以單元B 要先于單元A 編譯。

你可以用#pragma startup 指定編譯優先級,如果使用了#pragma package(smart_init) ,BCB就會根據優先級的大小先后編譯。

五、#pragma resource

#pragma resource "*.dfm"表示把*.dfm 文件中的資源加入工程。*.dfm 中包括窗體外觀的定義。

六、#pragma warning

? ?#pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價于:
? ?#pragma warning(disable:4507 34) // 不顯示4507 和34 號警告信息
? ?#pragma warning(once:4385) // 4385 號警告信息僅報告一次
? ?#pragma warning(error:164) // 把164 號警告信息作為一個錯誤。
同時這個pragma warning 也支持如下格式:
? ?#pragma warning( push [ ,n ] )
? ?#pragma warning( pop ) ?//這里n 代表一個警告等級(1---4)。
? ?#pragma warning( push )保存所有警告信息的現有的警告狀態。
? ?#pragma warning( push, n)保存所有警告信息的現有的警告狀態,并且把全局警告等級設定為n。
? ?#pragma warning( pop )向棧中彈出最后一個警告信息,在入棧和出棧之間所作的一切改動取消。例如:
? ?#pragma warning( push )
? ?#pragma warning( disable : 4705 )
? ?#pragma warning( disable : 4706 )
? ?#pragma warning( disable : 4707 )
? ?//.......
? ?#pragma warning( pop )
在這段代碼的最后,重新保存所有的警告信息(包括4705,4706 和4707)。

七、#pragma comment

#pragma comment(...)
該指令將一個注釋記錄放入一個對象文件或可執行文件中。

常用的lib 關鍵字,可以幫我們連入一個庫文件。比如:
? ?#pragma comment(lib, "user32.lib")
該指令用來將user32.lib 庫文件加入到本工程中。

linker:將一個鏈接選項放入目標文件中,你可以使用這個指令來代替由命令行傳入的或者在開發環境中設置的鏈接選項,你可以指定/include 選項來強制包含某個對象,例如:
? ?#pragma comment(linker, "/include:__mySymbol")

八、#pragma pack

這里重點討論內存對齊的問題和#pragma pack()的使用方法。

什么是內存對齊?先看下面的結構:
struct TestStruct1
{
? ?char c1;
? ?short s;
? ?char c2;
? ?int i;
};
假設這個結構的成員在內存中是緊湊排列的,假設c1 的地址是0,那么s 的地址就應該是1,c2 的地址就是3,i 的地址就是4。也就是c1 地址為00000000, s 地址為00000001, c2地址為00000003, i 地址為00000004。

可是,我們在Visual C++6.0 中寫一個簡單的程序:
struct TestStruct1 a;
printf("c1 %p, s %p, c2 %p, i %p\n",
(unsigned int)(void*)&a.c1 - (unsigned int)(void*)&a,
(unsigned int)(void*)&a.s - (unsigned int)(void*)&a,
(unsigned int)(void*)&a.c2 - (unsigned int)(void*)&a,
(unsigned int)(void*)&a.i - (unsigned int)(void*)&a);
運行,輸出:
c1 00000000, s 00000002, c2 00000004, i 00000008。
為什么會這樣?這就是內存對齊而導致的問題。

1、為什么會有內存對齊?
字,雙字,和四字在自然邊界上不需要在內存中對齊。(對字,雙字,和四字來說,自然邊界分別是偶數地址,可以被4 整除的地址,和可以被8 整除的地址。)無論如何,為了提高程序的性能,數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了訪問未對齊的內存,處理器需要作兩次內存訪問;然而,對齊的內存訪問僅需要一次訪問。

一個字或雙字操作數跨越了4 字節邊界,或者一個四字操作數跨越了8 字節邊界,被認為是未對齊的,從而需要兩次總線周期來訪問內存。一個字起始地址是奇數但卻沒有跨越字邊界被認為是對齊的,能夠在一個總線周期中被訪問。某些操作雙四字的指令需要內存操作數在自然邊界上對齊。如果操作數沒有對齊,這些指令將會產生一個通用保護異常。

雙四字的自然邊界是能夠被16 整除的地址。其他的操作雙四字的指令允許未對齊的訪問(不會產生通用保護異常),然而,需要額外的內存總線周期來訪問內存中未對齊的數據。

缺省情況下,編譯器默認將結構、棧中的成員數據進行內存對齊。因此,上面的程序輸出就變成了:c1 00000000, s 00000002, c2 00000004, i 00000008。編譯器將未對齊的成員向后移,將每一個都成員對齊到自然邊界上,從而也導致了整個結構的尺寸變大。盡管會犧牲一點空間(成員之間有部分內存空閑),但提高了性能。也正是這個原因,我們不可以斷言sizeof(TestStruct1)的結果為8。在這個例子中,sizeof(TestStruct1)的結果為12。

2、如何避免內存對齊的影響?
那么,能不能既達到提高性能的目的,又能節約一點空間呢?有一點小技巧可以使用。比如我們可以將上面的結構改成:
struct TestStruct2
{
? ?char c1;
? ?char c2;
? ?short s;
? ?int i;
};

這樣一來,每個成員都對齊在其自然邊界上,從而避免了編譯器自動對齊。在這個例子中,sizeof(TestStruct2)的值為8。這個技巧有一個重要的作用,尤其是這個結構作為API的一部分提供給第三方開發使用的時候。第三方開發者可能將編譯器的默認對齊選項改變,從而造成這個結構在你的發行的DLL 中使用某種對齊方式,而在第三方開發者哪里卻使用另外一種對齊方式。這將會導致重大問題。
比如,TestStruct1 結構,我們的DLL 使用默認對齊選項,對齊為c1 00000000, s 00000002, c2 00000004, i 00000008,同時sizeof(TestStruct1)的值為12。

而第三方將對齊選項關閉,導致c1 00000000, s 00000001, c2 00000003, i 00000004,同時sizeof(TestStruct1)的值為8。

除此之外我們還可以利用#pragma pack()來改變編譯器的默認對齊方式(當然一般編譯器也提供了一些改變對齊方式的選項,這里不討論)。

使用指令#pragma pack (n),編譯器將按照n 個字節對齊。
使用指令#pragma pack (),編譯器將取消自定義字節對齊方式。


在#pragma pack (n)和#pragma pack ()之間的代碼按n 個字節對齊。但是,成員對齊有一個重要的條件,即每個成員按自己的方式對齊.也就是說雖然指定了按n 字節對齊,但并不是所有的成員都是以n 字節對齊。其對齊的規則是,每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(這里是n 字節)中較小的一個對齊,即:min( n, sizeof( item )) 。并且結構的長度必須為所用過的所有對齊參數的整數倍,不夠就補空字節。看如下例子:
#pragma pack(8)
struct TestStruct4
{
? ?char a;
? ?long b;
};
struct TestStruct5
{
? ?char c;
? ?TestStruct4 d;
? ?long long e;
};
#pragma pack()

問題:
A)
sizeof(TestStruct5) = ?

B)
TestStruct5 的c 后面空了幾個字節接著是d?
TestStruct4 中,成員a 是1 字節默認按1 字節對齊,指定對齊參數為8,這兩個值中取1,a

按1 字節對齊;成員b 是4 個字節,默認是按4 字節對齊,這時就按4 字節對齊,所以sizeof(TestStruct4)應該為8;TestStruct5 中,c 和TestStruct4 中的a 一樣,按1 字節對齊,而d 是個結構,它是8 個字節,它
按什么對齊呢?對于結構來說,它的默認對齊方式就是它的所有成員使用的對齊參數中最大的一個, TestStruct4 的就是4.所以,成員d 就是按4 字節對齊.成員e 是8 個字節,它是默認按8字節對齊,和指定的一樣,所以它對到8 字節的邊界上,這時,已經使用了12 個字節了,所以又添加了4 個字節的空,從第16 個字節開始放置成員e.這時,長度為24,已經可以被8(成員e 按8字節對齊)整除.這樣,一共使用了24 個字節.內存布局如下(*表示空閑內存,1 表示使用內存。單位為1byete):
a b
TestStruct4 的內存布局:1***,1111,

c
TestStruct4.a TestStruct4.b d
TestStruct5 的內存布局: 1***, 1***, 1111, ****,11111111

這里有三點很重要:
首先,每個成員分別按自己的方式對齊,并能最小化長度。
其次,復雜類型(如結構)的默認對齊方式是它最長的成員的對齊方式,這樣在成員是復雜類型時,可以最小化長度。
然后,對齊后的長度必須是成員中最大的對齊參數的整數倍,這樣在處理數組時可以保證每一項都邊界對齊。


補充一下,對于數組,比如:char a[3];它的對齊方式和分別寫3 個char 是一樣的.也就是說它還是按1 個字節對齊.如果寫: typedef char Array3[3];Array3 這種類型的對齊方式還是按1個字節對齊,而不是按它的長度。

但是不論類型是什么,對齊的邊界一定是1,2,4,8,16,32,64....中的一個。

另外,注意別的#pragma pack 的其他用法:
#pragma pack(push) //保存當前對其方式到packing stack
#pragma pack(push,n) 等效于
#pragma pack(push)
#pragma pack(n) //n=1,2,4,8,16 保存當前對齊方式,設置按n 字節對齊
#pragma pack(pop) //packing stack 出棧,并將對其方式設置為出棧的對齊方


C語言#line預處理

#line 的作用是改變當前行數和文件名稱,它們是在編譯程序中預先定義的標識符命令的基本形式如下:
? ?#line number["filename"]
其中[]內的文件名可以省略。例如:
? ?#line 30 a.h
其中,文件名a.h 可以省略不寫。

這條指令可以改變當前的行號和文件名,例如上面的這條預處理指令就可以改變當前的行號為30,文件名是a.h。初看起來似乎沒有什么用,不過,他還是有點用的,那就是用在編譯器的編寫中,我們知道編譯器對C 源碼編譯過程中會產生一些中間文件,通過這條指令,可以保證文件名是固定的,不會被這些中間文件代替,有利于進行分析。


C語言#error預處理

#error 預處理指令的作用是,編譯程序時,只要遇到#error 就會生成一個編譯錯誤提示消息,并停止編譯。其語法格式為:
? ?#error error-message

注意,宏串error-message 不用雙引號包圍。遇到#error 指令時,錯誤信息被顯示,可能同時還顯示編譯程序作者預先定義的其他內容。關于系統所支持的error-message 信息,請查找相關資料,這里不浪費篇幅來做討論。


C語言文件包含#include

文件包含是預處理的一個重要功能,它可用來把多個源文件連接成一個源文件進行編譯,結果將生成一個目標文件。C語言提供#include 命令來實現文件包含的操作,它實際是宏替換的延伸,有兩種格式:

一、#include <filename>
其中,filename 為要包含的文件名稱,用尖括號括起來,也稱為頭文件,表示預處理到系統規定的路徑中去獲得這個文件(即C 編譯系統所提供的并存放在指定的子目錄下的頭文件)。找到文件后,用文件內容替換該語句。

2、#include “filename”
其中,filename 為要包含的文件名稱。雙引號表示預處理應在當前目錄中查找文件名為filename 的文件,若沒有找到,則按系統指定的路徑信息,搜索其他目錄。找到文件后,用文件內容替換該語句。

需要強調的一點是:#include 是將已存在文件的內容嵌入到當前文件中。

另外關于#include 的路徑也有點要說明:include 支持相對路徑,格式如trackant(蟻跡尋蹤)所寫:.代表當前目錄,..代表上層目錄。


C語言條件編譯#ifdef

條件編譯的功能使得我們可以按不同的條件去編譯不同的程序部分,因而產生不同的目標代碼文件。這對于程序的移植和調試是很有用的。條件編譯有三種形式,下面分別介紹:

第一種形式:
#ifdef 標識符
? ?程序段1
#else
? ?程序段2
#endif
它的功能是,如果標識符已被#define 命令定義過則對程序段1 進行編譯;否則對程序段2進行編譯。如果沒有程序段2(它為空),本格式中的#else 可以沒有,即可以寫為:
#ifdef 標識符
? ?程序段
#endif

第二種形式:
#ifndef 標識符
? ?程序段1
#else
? ?程序段2
#endif

與第一種形式的區別是將“ifdef”改為“ifndef”。它的功能是,如果標識符未被#define 命令定義過則對程序段1 進行編譯,否則對程序段2 進行編譯。這與第一種形式的功能正相反。

第三種形式:
#if 常量表達式
? ?程序段1
#else
? ?程序段2
#endif

它的功能是,如常量表達式的值為真(非0),則對程序段1 進行編譯,否則對程序段2 進行編譯。因此可以使程序在不同條件下,完成不同的功能。

C語言宏定義#define

一、數值宏常量

#define 宏定義是個演技非常高超的替身演員,但也會經常耍大牌的,所以我們用它要慎之又慎。它可以出現在代碼的任何地方,從本行宏定義開始,以后的代碼就就都認識這個宏了;也可以把任何東西定義成宏。因為編譯器會在預編譯的時候用真身替換替身,而在我們的代碼里面卻又用常常用替身來幫忙。看例子:
? ?#define PI 3.141592654
在此后的代碼中你盡可以使用PI 來代替3.141592654,而且你最好就這么做。不然的話,如果我要把PI 的精度再提高一些,你是否愿意一個一個的去修改這串數呢?你能保證不漏不出錯?而使用PI 的話,我們卻只需要修改一次。這種情況還不是最要命的,我們再看一個例子:
? ?#define ERROR_POWEROFF -1
如果你在代碼里不用ERROR_POWEROFF 這個宏而用-1,尤其在函數返回錯誤代碼的時候(往往一個開發一個系統需要定義很多錯誤代碼)。肯怕上帝都無法知道-1 表示的是什么意思吧。這個-1,我們一般稱為“魔鬼數”,上帝遇到它也會發狂的。所以,我奉勸你代碼里一定不要出現“魔鬼數”。

第一章我們詳細討論了const 這個關鍵字,我們知道const 修飾的數據是有類型的,而define 宏定義的數據沒有類型。為了安全,我建議你以后在定義一些宏常數的時候用const代替,編譯器會給const 修飾的只讀變量做類型校驗,減少錯誤的可能。但一定要注意const修飾的不是常量而是readonly 的變量,const 修飾的只讀變量不能用來作為定義數組的維數,也不能放在case 關鍵字后面。

二、字符串宏常量

除了定義宏常數之外,經常還用來定義字符串,尤其是路徑:
A),#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3
B),#define ENG_PATH_2 “E:\English\listen_to_this\listen_to_this_3”
噢,到底哪一個正確呢?如果路徑太長,一行寫下來比較別扭怎么辦?用反斜杠接續符啊:
C), #define ENG_PATH_3 E:\English\listen_to_this\listen\_to_this_3

還沒發現問題?這里用了4 個反斜杠,到底哪個是接續符?回去看看接續符反斜杠。

反斜杠作為接續符時,在本行其后面不能再有任何字符,空格都不行。所以,只有最后一個反斜杠才是接續符。至于A)和B),那要看你怎么用了,既然define 宏只是簡單的替換,那給ENG_PATH_1 加上雙引號不就成了:“ENG_PATH_1”。

但是請注意:有的系統里規定路徑的要用雙反斜杠“\\”,比如:
#define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this_3

三、用define 宏定義注釋符號?

上面對define 的使用都很簡單,再看看下面的例子:
#define BSC //
#define BMC /*
#define EMC */
D),BSC my single-line comment
E),BMC my multi-line comment EMC

D)和E)都錯誤,為什么呢?因為注釋先于預處理指令被處理,當這兩行被展開成//…或/*…*/時,注釋已處理完畢,此時再出現//…或/*…*/自然錯誤.因此,試圖用宏開始或結束一段注釋是不行的。

四、用define 宏定義表達式

這些都好理解,下面來點有“技術含量”的,定義一年有多少秒:
? ?#define SEC_A_YEAR 60*60*24*365
這個定義沒錯吧?很遺憾,很有可能錯了,至少不可靠。你有沒有考慮在16 位系統下把這樣一個數賦給整型變量的時候可能會發生溢出?一年有多少秒也不可能是負數吧。修改一下:
? ?#define SEC_A_YEAR (60*60*24*365)UL
又出現一個問題,這里的括號到底需不需要呢?繼續看一個例子,定義一個宏函數,求x 的平方:
? ?#define SQR (x) x * x
對不對?試試:假設x 的值為10,SQR (x)被替換后變成10*10。沒有問題。

再試試:假設x 的值是個表達式10+1,SQR (x)被替換后變成10+1*10+1。問題來了,這并不是我想要得到的。怎么辦?括號括起來不就完了?
? ?#define SQR (x) ((x)*(x))
最外層的括號最好也別省了,看例子,求兩個數的和:
? ?#define SUM (x) (x)+(x)
如果x 的值是個表達式5*3,而代碼又寫成這樣:SUM (x)* SUM (x)。替換后變成:(5*3)+(5*3)*(5*3)+(5*3)。又錯了!所以最外層的括號最好也別省了。我說過define 是個演技高超的替身演員,但也經常耍大牌。要搞定它其實很簡單,別吝嗇括號就行了。

注意這一點:宏函數被調用時是以實參代換形參。而不是“值傳送”。

留四個問題:
A)
上述宏定義中“SUM”、“SQR”是宏嗎?
B)
#define EMPTY
這樣定義行嗎?
C)
打印上述宏定義的值:printf(“SUM (x)”);結果是什么?
D)
“#define M 100”是宏定義嗎?

五、宏定義中的空格

另外還有一個問題需要引起注意,看下面例子:
? ?#define SUM (x) (x)+(x)
這還是定義的宏函數SUM(x)嗎?顯然不是。編譯器認為這是定義了一個宏:SUM,其代表的是(x) (x)+(x)。

為什么會這樣呢?其關鍵問題還是在于SUM 后面的這個空格。所以在定義宏的時候一定要注意什么時候該用空格,什么時候不該用空格。這個空格僅僅在定義的時候有效,在使用這個宏函數的時候,空格會被編譯器忽略掉。也就是說,上一節定義好的宏函數SUM(x)在使用的時候在SUM 和(x)之間留有空格是沒問題的。比如:SUM(3)和SUM (3)的意思是一樣的。

六、#undef

#undef 是用來撤銷宏定義的,用法如下:
#define PI 3.141592654

// code
#undef PI
//下面的代碼就不能用PI 了,它已經被撤銷了宏定義。

也就是說宏的生命周期從#define 開始到#undef 結束。很簡單,但是請思考一下這個問題:
#define X 3
#define Y X*2
#undef X
#define X 2
int z=Y;
z 的值為多少?


C語言預處理命令有哪些

往往我說今天上課的內容是預處理時,便有學生質疑:預處理不就是include 和define么?這也用得著講啊?。是的,非常值得討論,即使是include 和define。但是預處理僅限于此嗎?遠遠不止。先看幾個個常識性問題:
A)
預處理是C 語言的一部分嗎?
B)
包含“#”號的都是預處理嗎?
C)
預處理指令后面都不需要加“;”號嗎?

不要急著回答,先看看ANSI 標準定義的C 語言預處理指令:
另外ANSI 標準C 還定義了如下幾個宏:
  1. _LINE_ 表示正在編譯的文件的行號
  2. _FILE_ 表示正在編譯的文件的名字
  3. _DATE_ 表示編譯時刻的日期字符串,例如: "25 Dec 2007"
  4. _TIME_ 表示編譯時刻的時間字符串,例如: "12:30:55"
  5. _STDC_ 判斷該文件是不是定義成標準C 程序

如果編譯器不是標準的,則可能僅支持以上宏的一部分,或根本不支持。當然編譯器也有可能還提供其它預定義的宏名。注意:宏名的書寫由標識符與兩邊各二條下劃線構成。

相信很多初學者,甚至一些有經驗的程序員都沒有完全掌握這些內容,下面就一一詳細討論這些預處理指令。



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

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

相關文章

Lambda表達式使用2

1.概述    本篇主要介紹lambda中常用的收集器&#xff0c;收集器的作用就是從數據流中生成需要的數據接口。    最常用的就是Collectors.toList()&#xff0c;只要將它傳遞給collect()函數&#xff0c;就能夠使用它了。    在我們使用收集器的時候經常會用到“方法…

notepad++ 使用去掉自動檢查紅線

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 notepad新升級了之后就有自動判斷的紅線&#xff0c;單詞拼錯了就給提示&#xff0c;看著這紅線實在難受 在 菜單選項&#xff1a;[插件…

cAdvisor+InfluxDB+Grafana 監控Docker

容器的監控方案其實有很多&#xff0c;有docker自身的docker stats命令、有Scout、有Data Dog等等&#xff0c;本文主要和大家分享一下比較經典的容器開源監控方案組合&#xff1a;cAdvisorInfluxDBGrafan 一、概念 1). InfluxDB是什么nfluxDB是用GO語言編寫的一個開源分布式時…

C語言return關鍵字

return 用來終止一個函數并返回其后面跟著的值。return &#xff08;Val&#xff09;&#xff1b;//此括號可以省略。但一般不省略&#xff0c;尤其在返回一個表達式的值時。return 可以返回些什么東西呢&#xff1f;看下面例子&#xff1a;char * Func(void){char str[30];…r…

win7旗艦版怎么降級到專業版

一、操作準備及注意事項 1、UltraISO光盤制作工具9.5 2、備份C盤及桌面文件 二、win7旗艦版改成專業版的步驟 1、當前系統為Win7 SP1 64位旗艦版&#xff1b; 2、按WinR打開運行&#xff0c;輸入regedit打開注冊表編輯器&#xff0c;定位到HKEY_LOCAL_MACHINE\Software\Microso…

JPA criteria 查詢:類型安全與面向對象

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 JPA的標準查詢,名為:JPA criteria查詢. 相比JPQL,其優勢是類型安全,更加的面向對象.使用標準查詢,開發人員可在編譯的時候就檢查 查詢的…

Algs4-1.4.18數組的局部最小元素

1.4.18數組的局部最小元素。編寫一個程序&#xff0c;給定一個含有N個不同整數的數組&#xff0c;找到一個局部最小元素:滿足a[i]<a[i-1],且a[i]<a[i1]的索引i。程序在最壞情況下所需的比較次數為~2lgN。答&#xff1a;檢查數組的中間值a[N/2]以及和它相鄰的元素a[N/2-1]…

編程技能和做員工的技能——哪個更重要?

摘要&#xff1a;不管我們程序員如何認識這個問題&#xff0c;如果你想在給別人編程打工中獲得事業成功&#xff0c;編程技能不是第一重要的。學會如何做一個好的員工才是重要的&#xff0c;甚至是非常重要的。從最最基本的層面上講&#xff0c;每個員工都應該為最求兩種基本的…

nginx-exporter安裝使用

一、沒有vts的啟動方式 #nginx_exporter -telemetry.address:9113 -nginx.scrape_uri"http://127.0.0.1:10000/nginx_statusnginx_exporter -telemetry.address:9113 -nginx.scrape_uri"https://xx.xx.xx.xx:18443" -insecure #端口9113應該是nginx_exporter監…

spring data jpa 的 in 查詢 Specification 實現

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 只是一個簡單需求&#xff1a; 查詢所有部門id 屬于 idList 的數據 Page<WorkWeight> page workWeightRepository.findAll(new…

在移動互聯網上賺錢,行不行

移動互聯網已被證實是互聯網產業發展的大趨勢。不過&#xff0c;究竟如何賺錢&#xff0c;對海外企業與中國企業來說都是難題。本月初&#xff0c;幾位業界大佬與風投來了一番討論&#xff0c;議題還是一個“在移動互聯網上賺錢&#xff0c;行還是不行”。 百度試圖通過用戶習慣…

計算機網絡知識簡單介紹

一、網絡基礎 1.網絡指的是什么&#xff1f; 計算機與計算機之間通過物理鏈接介質&#xff08;網絡設備&#xff09;連接到一起。 計算機與計算機之間基于網絡協議通信&#xff08;網絡協議就相當于計算機界的英語&#xff09; 2.osi七層協議&#xff1a; 互聯網協議按照功能不…

Linux下安裝FFmpeg

FFmpeg官網&#xff1a;http://www.ffmpeg.org 官網介紹 FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure…

HTTP協議狀態碼詳解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 狀態碼含義100客戶端應當繼續發送請求。這個臨時響應是用來通知客戶端它的部分請求已經被服務器接收&#xff0c;且仍未被拒絕。客戶端應…

【Python web 開發】viewset 實現商品詳情頁的接口

我們如何來完成商品詳情頁的接口呢&#xff1f; 首先要配置一個商品詳情的url 按照我們正常的接口配法 &#xff0c;應該是后面要加一個id 的&#xff0c;為什么這里沒有加id 呢? ,應該是rooter register 的作用吧&#xff0c;等我在學習一遍基礎再來回答&#xff1f; 那么我…

Ignite中的機器學習介紹

為什么80%的碼農都做不了架構師&#xff1f;>>> 本系列共6篇文章&#xff0c;會通過一些代碼示例&#xff0c;講解如何在Ignite中使用機器學習庫&#xff0c;本文是本系列的第一篇。 從Ignite的2.4版本開始&#xff0c;機器學習就可以用于生產環境了。在這個版本中…

4G發牌或提早 電信聯通面臨艱難抉擇

曾幾何時遙不可及的4G&#xff0c;上馬的時間可能要比預期來的要早。今年3月&#xff0c;工信部部長苗圩表示&#xff0c;預計國內需要2-3年才會發放4G牌照。話音猶在耳&#xff0c;苗圩部長9月11日表示&#xff0c;“工信部已決定將于一年左右的時間發放TD-LTE牌照”。 工信部…

mysql 的 sql 執行計劃詳解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 引言&#xff1a; 實際項目開發中&#xff0c;由于我們不知道實際查詢的時候數據庫里發生了什么事情&#xff0c;數據庫軟件是怎樣掃描…

2018-10-28

我的博客即將入駐“云棲社區”&#xff0c;誠邀技術同仁一同入駐。

win10+vscode部署java開發環境

目錄 Java開發插件配置&#xff1a;調試&#xff1a;快捷鍵&#xff1a;啟動配置文件launch.json:啟動配置說明&#xff1a;Launch:Attach:User Setting:遇到的問題&#xff1a;參考&#xff1a;Java開發插件配置&#xff1a; Microsoft有個官方的插件Java Extension Pack&…