2017-03-07 112 views
-1

我想讀取我的Arduino UNO上閃存中一些字符串的長度。數組string_table給我的問題,如果我得到它的索引與編譯器優化爲一個常數,然後我得到預期的價值。如果我在運行時使用某個變量來訪問它,那麼每次我都會得到不同的答案。Arduino訪問數組產生意想不到的結果

我不認爲這是特定於Arduino,因爲我似乎沒有調用任何Arduino特定的功能。

代碼:

#include <avr/pgmspace.h> 

// Entries stored in flash memory 
const char entry_0[] PROGMEM = "12345"; 
const char entry_1[] PROGMEM = "abc"; 
const char entry_2[] PROGMEM = "octagons"; 
const char entry_3[] PROGMEM = "fiver"; 

// Pointers to flash memory 
const char* const string_table[] PROGMEM = {entry_0, entry_1, entry_2, entry_3}; 

void setup() { 
    Serial.begin(115200); 
    randomSeed(analogRead(0)); 

    int r = random(4); 
    Serial.print("random key (r) : "); 
    Serial.println(r); 
    Serial.print("Wrong size for key = "); 
    Serial.print(r); 
    Serial.print(" : "); 
    Serial.println(strlen_P(string_table[r])); 
    int i = 1; 
    Serial.print("Correct size for key = "); 
    Serial.print(i); 
    Serial.print(" : "); 
    Serial.println(strlen_P(string_table[i])); 
    Serial.println("====="); 

    Serial.println("Expected Sizes: "); 
    Serial.print("0 is: "); 
    Serial.println(strlen_P(string_table[0])); 
    Serial.print("1 is: "); 
    Serial.println(strlen_P(string_table[1])); 
    Serial.print("2 is: "); 
    Serial.println(strlen_P(string_table[2])); 
    Serial.print("3 is: "); 
    Serial.println(strlen_P(string_table[3])); 
    Serial.println("++++++"); 

    Serial.println("Wrong Sizes: "); 
    for (i = 0; i < 4; i++) { 
    Serial.print(i); 
    Serial.print(" is: "); 
    Serial.println(strlen_P(string_table[i])); 
    } 
    Serial.println("------"); 
    delay(500); 
} 

void loop() { 
    // put your main code here, to run repeatedly: 

} 

結果:

random key (r) : 1 
Wrong size for key = 1 : 16203 
Correct size for key = 1 : 3 
===== 
Expected Sizes: 
0 is: 5 
1 is: 3 
2 is: 8 
3 is: 5 
++++++ 
Wrong Sizes: 
0 is: 0 
1 is: 11083 
2 is: 3 
3 is: 3 
------ 
+1

這不是C! Arduino不是C! – Olaf

+1

爲什麼downvotes?這是一個有趣的問題(現在標記爲C++)。 –

回答

2

avr-libc - source code

strlen_P()被實現爲在avr/pgmspace.h 頭文件內聯函數,這將檢查是否該字符串的長度爲 常量,並且在編譯時間處已知。如果在編譯 時間內未知,宏將發出對__strlen_P()的調用,然後 將正常計算字符串的長度。

這可以解釋它(雖然呼籲__strlen_P()應該已經固定)。

也許改用以下內容:

strlen_P((char*)pgm_read_word(&(string_table[i]))); 

或者,也許嘗試使用strlen_PF()

+0

'strlen_P((char *)pgm_read_word(&(string_table [i])));'是解決方案。感謝你的簡明扼要的解釋,並且不要投下我的問題。 – Morgoth

相關問題