您正在使用全局變量。你確定你需要這種方法嗎?
通過按照您的代碼原樣,您將str_reset_command
定義爲const char *
。這意味着這是一個指向char的指針,它也具有限定符const
。您不得將「const」與const
混淆。 :)
編譯器從涉及文字的表達式構建的每個表達式中考慮「const」。
另一方面,const
限定符意味着您正在定義一個「變量」,其值無法修改,除非在其定義的那一刻。
表達式"\r\nReset"
是一個「const」,因爲它是一個字符串文字。
然而const char * str_reset_command
不是「const」,而是一個不能被修改的變量。
區別在於文字是編譯器的「常量」,因爲它可以在編譯時計算它們的值。但const
對象作爲變量保存,因爲它的值可能會在執行時間內確定。例如,請考慮<string.h>
中幾個函數的const
參數。
您的變量group0
被定義爲指向char數組的指針。
由於它被定義爲一個全局變量,它的初始值必須是一個「const」(在編譯時間意義上)值。但是你提供了str_reset_command
,這不是一個文字(或只涉及文字的表達式)。因此,它的值不能在編譯時確定,並且不能在那裏用作初始化。
也許你可以試着寫一個初始化函數:
const char * str_reset_command = "\r\nReset";
const char * str_config_command = "\r\nConfig";
const char * str_start_command = "\r\nStart";
const char * str_end_command = "\r\nEnd";
char * group0[1];
char * group1[2];
char * group2[3];
void initGroups(void) {
group2[0] = group1[0] = group0[0] = str_reset_command;
group2[1] = group1[1] = str_start_command;
group2[2] = str_end_command;
}
int main(void) {
initGroups();
// Do stuff...
}
我放棄了const
預選賽,因爲現在我們需要修改指針。
無論如何,使用全局變量有一些副作用。
嘗試修改此方面,如果可能的話。
編輯
第二TRY
我想在你的程序,我已經完全改變你的做法。
首先,我不明白你爲什麼使用所有「group []」數組。
既然你想優化內存資源,這不是最優的。
另一方面,你的「常量字符串」似乎只是少數。
通過假設它們不超過8,給定組中涉及的字符串的信息可以保存在1個字節中。
我的意思是,你可以通過一個字節的位來定義一個「組」或「集合」,因此如果一個給定的成員屬於該集合,則將該位置1(開),否則爲0。
此外,由於您接受使用指向恆定字符的指針數組,我認爲您所有的字符串都可以在代碼開始時保存在一個常量字符數組中。這可以通過一個const聲明在ROM中保存。
您已將名稱用作str_reset,str_start等。
看來你需要這些信息才能清楚自己。
這些信息可以通過編譯器常量和/或枚舉的方式保存在代碼中,這些代碼在編譯後的程序中沒有任何代價。
我設計了一個使用位掩碼的代碼。
這可讓您使用最多8個字符串。
由於位掩碼是2的冪,因此不能用作數組索引。然而,人們可以以一種非常隨後的方式定義一個名稱與位掩碼常量「並行」的激勵常量列表。
特別是,你將能夠或改變枚舉的順序,但你的代碼將繼續工作。
爲了完成該圖片,我使用了C99/C11標準的一個特性(您似乎使用了這個特性,因爲您聲明for
語句的方式),允許我們通過寫入數組來初始化數組的不可數成員期望的指數。
由於索引現在將具有枚舉給定的名稱,所以您可以信任此技術,而不必關注已使用的實際索引。
我已經使用<stdio.h>
和printf()
來測試程序。你可以擦除這些行。
#include <stdio.h>
#define bit0 0x01u /* Binary 0000 0001 */
#define bit1 0x02u /* Binary 0000 0010 */
#define bit2 0x04u /* Binary 0000 0100 */
#define bit3 0x08u /* Binary 0000 1000 */
#define bit4 0x10u /* Binary 0001 0000 */
#define bit5 0x20u /* Binary 0010 0000 */
#define bit6 0x40u /* Binary 0100 0000 */
#define bit7 0x80u /* Binary 1000 0000 */
enum {reset_command = 0, config_command, start_command, end_command};
#define bit_reset (1u << reset_command) /* Equal to bit0 */
#define bit_config (1u << config_command) /* Equal to bit1 */
#define bit_start (1u << start_command) /* Equal to bit2 */
#define bit_end (1u << end_command) /* Equal to bit3 */
const char * const str[] = {
[reset_command] = "\r\nReset",
[config_command] = "\r\nConfig",
[start_command] = "\r\nStart",
[end_command] = "\r\nEnd"
};
const unsigned char bitgroup0 = bit_reset;
const unsigned char bitgroup1 = bit_reset | bit_start;
const unsigned char bitgroup2 = bit_reset | bit_start | bit_end;
void doStuffToCharacter(unsigned char the_char){
printf("%c", the_char);
}
void doStuff(const char * const * str, unsigned char bitgroup){
printf("\n\nGroup: %hu\n", bitgroup);
for (unsigned char b=bitgroup, j=0; b; b >>= 1u, j++){
if (b & 1u) {
for(unsigned char idx = 0; str[j][idx]; idx++) {
doStuffToCharacter(str[j][idx]);
}
}
}
}
int main (void){
doStuff(str, bitgroup0);
doStuff(str, bitgroup1);
doStuff(str, bitgroup2);
}
正如您所看到的,每個「組」現在只需要1個字節。 (你的方法至少使用了1,2和3個字節)。
for()
語句中的迭代次數未超過groupbit
參數中的「on」的最大位數。
指針的const char
對象被要求保存在const
指針中也是滿載的。
數組的大小由編譯器自動確定以保存最大索引。
for()
循環在初始化爲您作爲參數傳遞的「組」的「字節」上迭代。
最後一位針對1進行測試。
如果該位爲1,則執行一些操作。
否則,這會跳到下一個迭代中。
最後一位被賦值爲b >>= 1u
。
每次迭代,我們需要走開數組str
的索引j
。
因此,當且僅當處理j
字符串時,第j
位是1。
接下來,每個重複,直到b
沒有更多位1
。
如果您使用其位1全部連續的「組」,那麼該程序的工作方式與您在示例中所期望的相同。
現在您可以選擇所需的操作,只需切換相應的位即可。
澄清更新問題 – Jodes
請參閱我的編輯。 – StoryTeller
昨天我修改了我的答案,標題爲「編輯」(現在我寫了「第二次嘗試」的標題)。在那裏,我解釋了一個基於位掩碼的新代碼。我認爲是一種更好的方法,因爲它可以節省更多的內存,並且不會使用任何數組。另外,您還說過「需要發送各種命令字符串的組合」。我認爲我的方法爲此目的靈活。在這第二個代碼中有幾個#define行,但是這不會在編譯的程序中花費內存。 – pablo1977