Arduino我如何使用char而不是String(以提高内存使用率) [英] Arduino How can I use char instead of String (for better memory usage)

查看:283
本文介绍了Arduino我如何使用char而不是String(以提高内存使用率)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读过数千遍了,String库并不是代码和内存优化的最佳解决方案.所以我需要使用char而不是String.我有几个函数可以返回String,我可以在其中将其用于存储在文件(SD卡)中或将其作为参数发布到Web上.因此,在下面的草图中,如何更改它以与char一起使用.我知道如何保存到SD文件或发布到Web服务器.我只需要帮助将String更改为char.

I have read thousand times that String library is not the best solution for code and memory optimization. So I need to use char instead of String. I have several functions that return String where I use it for store in file (sd card) or post it to web as param. So in the following sketch, how can i change it to work with char. I know how to save to sd file or post to webserver. I need only help for change the String to char.

#include <ThreeWire.h>  
#include <RtcDS1302.h>

ThreeWire myWire(7,8,6); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

#define countof(a) (sizeof(a) / sizeof(a[0]))

String NowDateTime="";

void setup() {
    Serial.begin(9600);       // for debugging
    Rtc.Begin();
    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    if (!Rtc.IsDateTimeValid()) {
        Rtc.SetDateTime(compiled);
    }
    if (Rtc.GetIsWriteProtected()) {
        Rtc.SetIsWriteProtected(false);
    }
    if (!Rtc.GetIsRunning()) {
        Rtc.SetIsRunning(true);
    }
    RtcDateTime tempnow = Rtc.GetDateTime();
    if (tempnow < compiled) {
        Rtc.SetDateTime(compiled);
    }
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now);
    Serial.println((String)"RTC: "+NowDateTime);
}

void loop() {
    delay(1000);
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now); 
    Serial.println(NowDateTime);
}

//RETURN Datetime id Readeable format as stting
String strDT(const RtcDateTime& dt)
{
    char ret[30];
    snprintf_P(ret, 
            countof(ret),
            PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
            dt.Year(),
            dt.Month(),
            dt.Day(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );     
    return ret;
}

在此先感谢您的帮助!

推荐答案

我知道您的意图是了解如何使用c数组而不是String类,但是在您的代码中,很容易避免使用String和将数组保留在函数内,以使代码更简单且更可靠.

I know your intention is to understand on how to use c array instead of String class, but in your code, it is easy to avoid the use of String and keep the array local within the function to make the code simple and more robust.

您不需要返回String,只需将Serial.print添加到函数的末尾即可.

You don't need to return a String, just add the Serial.print to the end of your function.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  printDateTime(now);
}

void printDateTime(const RtcDateTime& dt)
{
    char ret[20];
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    Serial.println(ret);
}

如果您真的希望函数返回包含格式化字符串的数组,则可以在函数内将 ret [20] 声明为 static 数组,因此从函数调用返回后,数组的值将不会释放.

If you really prefer to have the function to return the array that contained the formatted string, you can declare ret[20] as a static array within the function so that the value of the array won't be free up after returning from the function call.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  Serial.println(strDT(now));
}

char* strDT(const RtcDateTime& dt)
{
    static char ret[20];    //local static variable
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    return ret;
}

认为函数的返回类型应该是指向 ret 的点(即 char * ).

Noticed that the return type from the function should be a point to the ret (i.e. char*).

字符串库不是C ++的一部分,它使Arduino诸如python或Java的串联之类的某些功能,例如 String myString ="this string" + this_var +"another string"; ,它们在堆内存中使用动态内存分配malloc.对于Arduino初学者来说,它看起来更容易,但是这可能会导致堆碎片或内存泄漏,特别是如果是编程新手并且不真正了解堆的工作原理时.要完全替换使用Sting类,最好学习如何使用 C ++ cstring.h 处理字符串的功能.

String library you see in Arduino is not part of C++, it gives Arduino some features such as python-like or Java-like concatenation like String myString = "This string " + this_var + " another string";, which use dynamic memory allocation malloc at heap memory. it looks easier for the people who is new to Arduino, it is however could caused heap fragmentation or memory leak especially if one is new to programming and don't really understand how heap works. To complete replace of using Sting class, it is best to learn how to use C++ cstring.h functions to handle string.

这篇关于Arduino我如何使用char而不是String(以提高内存使用率)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆