Не удалось вернуть значение int из функции
Я создал библиотеку myJSON
, чтобы упростить чтение и запись значений из/в FLASH моего ESP8266 NodeMCU/Wemos Mini.
Я не хочу "испортить" вопрос, опубликовав весь свой код/библиотеку, но попытаюсь объяснить, что происходит -
Я получаю значение 0
при чтении определенного key
(а не его сохраненного value
). Я предполагаю, что это не имеет ничего общего с библиотекой myJSON
, но мое понимание возврата значения из функции.
Код выглядит следующим образом:
(сначала некоторые пояснения):
1) json
— это экземпляр библиотеки myJSON
.
2) json.setValue(key, value)
— получает key
и value
(char/int) и сохраняет их в ВСПЫШКА.
3)json.getINTValue(key, return_var)
— получает key
и возвращает его значение int
в return_var
. функция возвращает 1 — в случае успешного чтения и 0 — в противном случае.
внутри setup()
int int_val;
// json.setValue("int_key",343); // закомментировано после первого запуска - чтобы убедиться, что он сохранен и прочитан из флэш-памяти.
Serial.println(json.getINTValue("int_key",int_val)); // ЗАМЕТКА 2
Serial.print("Value is: "); // ЗАМЕТКА 3
Serial.println(int_val); // ЗАМЕТКА 3
myJSON
(только соответствующий код)
bool myJSON::getINTValue (const char *key, int retval){
StaticJsonDocument<DOC_SIZE> tempJDOC;
myJSON::readJSON_file(tempJDOC);
bool hasKey = tempJDOC.containsKey(key);
if (hasKey){
retval = tempJDOC[key];
Serial.print("retval :"); // ПРИМЕЧАНИЕ 1
Serial.println(retval); // ПРИМЕЧАНИЕ 1
return 1;
}
else {
return 0; // когда ключа нет
}
}
void myJSON::setValue(const char *key, char *value){
StaticJsonDocument<DOC_SIZE> tempJDOC;
myJSON::readJSON_file(tempJDOC);
tempJDOC[key]=value;
myJSON::saveJSON2file(tempJDOC);
}
void myJSON::setValue(const char *key, int value){
StaticJsonDocument<DOC_SIZE> tempJDOC;
myJSON::readJSON_file(tempJDOC);
tempJDOC[key]=value;
myJSON::saveJSON2file(tempJDOC);
}
результат (СМ. ОБОЗНАЧЕНИЯ):
21:01:03.198 -> retval :343 // ВЫВОД ПРИМЕЧАНИЕ 1
21:01:03.198 -> 1 // ВЫВОД ПРИМЕЧАНИЕ 2
21:01:03.198 -> Value is: 0 // ВЫВОД ПРИМЕЧАНИЕ 3
Насколько я понял:
1) setValue
работает по мере необходимости (включая сохранение во флэш-память).
2) необъяснимо, кроме получения значения = 0, при установке значения char
(есть 2 функции myJSON::setValue
для работы с int
и char
), код работает по мере необходимости.
Благодарим за любую помощь (и извините за мой английский).
Парень
@Guy . D, 👍1
Обсуждение2 ответа
Лучший ответ:
параметры вызова функции копируются в параметры функции. если указатель копируется, он все еще указывает на память, в которую вы записываете данные. если int копируется, то изменение значения изменяет копию, а не переменную, используемую в качестве параметра. ссылка — это своего рода указатель
как создать входной параметр, передав параметр по ссылке
void setup() {
Serial.begin(115200);
int x = 3;
fnc(x);
Serial.println(x);
}
void loop() {
}
void fnc(int &x) {
x = 5;
}
выводит 5
пример со сложным типом
#include <IPAddress.h>
void setup() {
Serial.begin(115200);
IPAddress ip(192, 168, 1, 5);
fnc(ip);
Serial.println(ip);
}
void loop() {
}
void fnc(IPAddress& ip) {
ip = IPAddress(192, 168, 1, 3);
}
с &ip он печатает 192.168.1.3. без усилителя он печатает 192.168.1.5
Спасибо! и причина, по которой char
ведет себя по-другому, заключается в том, что он указывает на указатель?, @Guy . D
char* — это указатель. и char[] тоже указатель. он копируется, поэтому присвоение ему другого указателя не сработает. но если вы измените память, на которую она указывает, вы прочитаете за пределами функции ту же ячейку памяти с измененным содержимым., @Juraj
Ваша проблема не в том, как вернуть переменную, а в том, как передать переменную извне функции в качестве параметра, который будет заполнен функцией. В основном есть 2 типа того, как вы можете передать переменную функции: по значению или по ссылке
Определение getINTValue()
гласит
getINTValue (const char *key, int retval)
поэтому retval
будет целым числом и будет вызываться по значению. Это означает, что локальная переменная с таким именем создается и заполняется значением из параметров вызова функции. Вы пишете в эту переменную, но она выбрасывается, когда функция возвращается. И запись в локальную переменную не изменила внешнюю переменную.
Вы должны использовать вызов по ссылке. Ваша функция должна принимать указатель на целочисленную переменную. Затем вы разыменовываете его и пишете в него:
getINTValue (const char *key, int *retval){
...
*retval = tempJDOC[key];
...
}
При вызове функции getINTValue()
это должно быть сделано следующим образом:
int value;
bool result = getINTValue("int_key", &value);
Операция &
возвращает вам указатель на переменную value
, которую функция затем использует для записи значения в эту ячейку памяти.
char*
отличается, потому что в этом случае вы передаете массив функции. Компилятор видит, что используемая переменная является массивом и использует в качестве параметра указатель на первый элемент массива. Это распространенный способ, потому что вы можете перебирать массив с помощью указателей (без номеров индексов). Вы можете сделать то же самое с любым массивом любого типа, но в этом случае у вас будет только одна переменная, а не массив.
Ой, извините, неправильно прочитал. Не могли бы вы вкратце уточнить свой комментарий или дать мне подсказку, что здесь искать в Google? Я научился этому так, как показал в своем ответе, и во время поиска в Google я не смог найти ваш способ сделать это (хотя я долго не гуглил). Было бы здорово узнать больше., @chrisl
Я написал это как ответ, @Juraj
- Невозможно преобразовать 'int (*)[size]' в 'int**': Cannot convert 'int (*)[size]' to 'int**'
- Как удалить элемент из массива arduino?
- Как передать несколько переменных в функцию?
- Есть ли функция Adafruit для инвертирования цветов моего экрана для языка Arduino?
- Как вернуть значение массива символов в функции Arduino IDE?
- Проблема с функцией, имеющей параметр со значением по умолчанию
- Ошибка: Переменная или поле объявлены недействительными
- Как получить переменную из функции обратного вызова?
bool myJSON::getINTValue(const char *key, int &retval){
, @Juraj@Юрай, ты можешь объяснить, почему? и почему она отличается от переменной
char
?, @Guy . Dэто не вопрос Arduino. & является «ссылкой». параметр с & не значение, а ссылка на переменную, @Juraj
@Juraj - я знаю среднее значение &, но почему оно не передает свое значение a в
retval
?, @Guy . D