創作內容

2 GP

【編程】巨集的濫用方法

作者:星白夜१ذ??؟¿ᷣᣎ│2024-02-09 03:48:32│巴幣:4│人氣:53
最近我在拿vst3sdk,照著網路上的影片練習寫vst。因為個人想要能夠精確調控,所以在影片基礎上多加了一堆參數,然後就在某個地方陷入了矩陣不太好用的狀況了。因為在這個過程中發現了巨集(C++附屬語言,就是拿來告訴程式怎麼寫程式的語言)可以搞定某些東西,所以就想著試試看用巨集寫類似於for loop的東西(真的在應用的時候拜託不要,這絕對會是個壞習慣),但這很顯然是個它X的難以除厝的東西(尤其是我其實對它的特性不算熟,性質跟程式碼真的有差)。總之在千辛萬苦之後我覺得我可能搞懂了什麼......

在看下面程式碼請注意(因為螢幕有限導致#define內容看起來換行,實際上並沒換行,要換行記得在結尾打\

// 1. 寫在右邊的內容在本次代換中會被忽略一次,例如:

//範例:巨集的小基本觀念
//目標: u"hello"
//c++裡面代表hello的utr-16字元陣列
#pragma once

#define STR(x) # x
#define STR_16(x) u##x
#define X_STR16(x) STR16(x)
STR16(STR(hello)) //代換結果是uSTR(hello),很顯然我不知道這是什麼
X_STR16(STR(hello)) //正確

//第一條式子直接把u跟STR(hello)黏在一起,所以STR(hello)不會被認出來
//第二條式子裡X_STR16(****) 代換出來的 STR16會被忽略一次,所以讓STR(x)有機會被換成 "x"

--------------------------------------------------------------------

// 2. 透過左邊的引數代換的文字內容,不屬於會被忽略的東西,可以連續代換,例如:

//範例:想要把其他巨集函式進行已知範圍的LOOP的錯誤示範
//目標: parameters.addParameter(type_NAME(a), nullptr, 0, defaultValueTable[i], Vst::ParameterInfo::kCanAutomate, type_ID(a));
#pragma once

//我要LOOP的函式,a,i是會隨著迴圈進行而改變的東西,TYPE,defaultValueTable 是進入迴圈之前就要選好的東西
#define ADD_P(a,i,TYPE, defaultValueTable) parameters.addParameter(TYPE##_NAME(a), nullptr, 0, defaultValueTable[i], Vst::ParameterInfo::kCanAutomate, TYPE##_ID(a))
//我決定直接把函數的前半部跟後半部拆了
#define ADD_P_START  ADD_P(
#define ADD_P_END(TYPE,defaultValueTable) ,TYPE,defaultValueTable)
//迴圈定那麼多我展開會很累,因為是實驗所以先試一次就好
#define LOOP_FUNC_1(F_START, F_END) F_START 1,0 F_END ;

LOOP_FUNC_1 (ADD_P_START, ADD_P_END(type, table));
//parameters.addParameter(_NAME(1), nullptr, 0, [0, type, table], Vst::ParameterInfo::kCanAutomate, _ID(1));
//所以誰能來解釋這他X的發生什麼事情了嗎?以上是我今天遇到時的心得

/*LOOP_FUNC_1 (ADD_P_START, ADD_P_END(type, table));
* --> ADD_P_START 1,0 ADD_P_END(type, table)
* --> ADD_P(1,0 ADD_P_END(type, table)  //後方兩個引數從缺直接變空白
* --> parameters.addParameter(_NAME(1), nullptr, 0, [0 ADD_P_END(type, table)], Vst::ParameterInfo::kCanAutomate, _ID(1))
* --> parameters.addParameter(_NAME(1), nullptr, 0, [0, type, table], Vst::ParameterInfo::kCanAutomate, _ID(1))
*/

//跟例子一的STR不同,ADD_P_START會被馬上再檢查,代換出來的ADD_P( 會再馬上被檢查,然後就...
//DoReMiSo~  ADD_P_END(type, table)很顯然沒有機會被好好的換掉

// 3. 對於一個代換函式或單字,它會反覆掃直到掃到完全沒東西為止,就像音樂裡的反覆記號

//範例:所以還是先來做個小實驗吧
//目標:搞清楚巨集是怎麼掃的

#pragma once

#define STR(x) # x
#define X_STR(x) STR(x)
#define PINE_APPLE(x)  I_LOVE_PINE_APPLE
#define APPLE(x) AN_APPLE_A_DAY_KEEP_YOUR_MONEY_AWAY
#define PINE(x) PINE_##x
#define BAD(x) STR( BAD_##x)
#define BAD_APPLE(x) TOUHOU
#define EAT(x) EAT##x
#define X_EAT(x) EAT(x)


X_STR(PINE(APPLE(x))) // "I_LOVE_PINE_APPLE"

/*-->STR(PINE(APPLE(x)) //STR是右邊原本的內容,PINE(APPLE(x)是透過參數代換進來的
*-->STR(PINE_APPLE(x)) //所以參考2. 這個東西會看看能不能代換-->能
*
*//問題:它是優先掃APPLE(x) 還是會掃整個PINE_APPLE(x)?
*
*-->STR(I_LOVE_PINE_APPLE) 顯然##符號執行完之後,它是有把整個PINE_APPLE(x)掃進去
*-->"I_LOVE_PINE_APPLE"
*/

X_EAT(BAD(APPLE(x))) // EAT"BAD_APPLE(x)"

/* --> EAT(BAD(APPLE(x))) //參考1. 暫時不去管EAT
* --> EAT(STR(BAD_APPLE(x))) // BAD(APPLE(x))是參數引入,所以要看能不能代換-->能
* --> EAT("BAD_APPLE(x)") //把原本BAD(APPLE(x))開頭的地方再掃一次,所以STR直接把後面便字串了
* --> EAT"BAD_APPLE(x)" //黏貼EAT跟那個字串,很簡單吧?

//4. 所以以下是2.的正確版本(但要這樣幹你要搞懂你在幹嘛)

//範例:想要把其他巨集函式進行已知範圍的LOOP的小示範

#pragma once

#define ADD_P(a,i,TYPE, defaultValueTable) parameters.addParameter(TYPE##_NAME(a), nullptr, 0, defaultValueTable[i], Vst::ParameterInfo::kCanAutomate, TYPE##_ID(a))
#define X_ADD_P(TYPE, defaultValueTable) Y_ADD_P(TYPE, defaultValueTable,
#define Y_ADD_P(TYPE, defaultValueTable,a,i) ADD_P(a,i,TYPE, defaultValueTable)
#define LOOP_FUNC_1(X_F) X_F##1,0);

LOOP_FUNC_1 (X_ADD_P(type, table)); //parameters.addParameter(type_NAME(1), nullptr, 0, table[0], Vst::ParameterInfo::kCanAutomate, type_ID(1));;

//搞懂巨集原理之後,總算弄出一個能用的版本,當然在這個過程中其實我也(被迫)弄懂了一堆我以前不懂的東西,
//所以這個就算技術上有難度,其實還是可以直接用for迴圈寫出來
//巨集是在編譯之前先把程式碼展開,像這樣進行濫用的話會平白無故把exe檔案給放大的
//就算cpp檔案裡面幾行,編譯的時候會是好幾十行
//在情況允許的狀況下還是用for迴圈才不會浪費程式碼

嗯,我搞懂我就算搞懂可以這樣用巨集其實也不應該這樣用
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5879516
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

2喜歡★shiroyoru 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:【c++練習】有關於巨集... 後一篇:【音遊試玩】Paradi...

追蹤私訊切換新版閱覽

作品資料夾

vicpetsshu大家
分享自己拍的黑絲與肉絲腿腿照ww 喜歡可以看看小屋嘿嘿看更多我要大聲說昨天17:37


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】