2017-03-07 108 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

相关问题