реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Получить адрес глобальной переменной.
Jenya7
сообщение Jan 21 2016, 09:21
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



хочу получить адрес глобальной переменной
делаю так
Код
uint32_t SetVariable(char *var)
{
    if(strcmp(var,"temp")==0) return &temperature;
    if(strcmp(var,"hum")==0)  return &humidity;
    return 0;
}

Получаю
return makes integer from pointer without a cast [enabled by default]
Go to the top of the page
 
+Quote Post
gerber
сообщение Jan 21 2016, 09:32
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(Jenya7 @ Jan 21 2016, 12:21) *
хочу получить адрес глобальной переменной
делаю так

Хотите получить адрес - адрес и возвращайте:
Код
uint32_t* SetVariable(char *var)
{
    if(strcmp(var,"temp")==0) return &temperature;
    if(strcmp(var,"hum")==0)  return &humidity;
    return 0;
}

Хотите получить значение переменной:
Код
uint32_t SetVariable(char *var)
{
    if(strcmp(var,"temp")==0) return temperature;
    if(strcmp(var,"hum")==0)  return humidity;
    return 0;
}

В обоих случаях название функции не отражает её сути, это скорее GetVariable.

Сообщение отредактировал gerber - Jan 21 2016, 09:32


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
skripach
сообщение Jan 21 2016, 09:38
Сообщение #3


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Цитата(Jenya7 @ Jan 21 2016, 12:21) *
хочу получить адрес


Код
uint32_t SetVariable(char *var)
{
    if(strcmp(var,"temp")==0) return (uint32_t)&temperature;
    if(strcmp(var,"hum")==0)  return (uint32_t)&humidity;
    return 0;
}

..если действительно нужен адрес.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2016, 09:49
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(skripach @ Jan 21 2016, 14:38) *
Код
uint32_t SetVariable(char *var)
{
    if(strcmp(var,"temp")==0) return (uint32_t)&temperature;
    if(strcmp(var,"hum")==0)  return (uint32_t)&humidity;
    return 0;
}

..если действительно нужен адрес.

действительно нужен адрес. но так ругается - return makes integer from pointer without a cast [enabled by default]


а понял. спасибо.

компайлер осторожничает. требует явного приведения.

Сообщение отредактировал Jenya7 - Jan 21 2016, 09:56
Go to the top of the page
 
+Quote Post
SlavaV
сообщение Jan 21 2016, 09:58
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 13-06-06
Из: г.Улан-Удэ
Пользователь №: 18 024



Вам же gerber написал, если хотите возвращать адрес укажите что функция возвращает адрес (указатель) uint32_t* SetVariable(char *var)

PS если возвращаете адрес это ни есть хорош return 0, есть nullptr.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2016, 10:06
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(SlavaV @ Jan 21 2016, 14:58) *
Вам же gerber написал, если хотите возвращать адрес укажите что функция возвращает адрес (указатель) uint32_t* SetVariable(char *var)

PS если возвращаете адрес это ни есть хорош return 0, есть nullptr.

так я получаю - return from incompatible pointer type [enabled by default]
Go to the top of the page
 
+Quote Post
SlavaV
сообщение Jan 21 2016, 10:11
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 13-06-06
Из: г.Улан-Удэ
Пользователь №: 18 024



приведите пожалуйста код где объявлена глобальная переменная.

И объявлена она в этом же файле?
Go to the top of the page
 
+Quote Post
skripach
сообщение Jan 21 2016, 10:12
Сообщение #8


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Цитата(SlavaV @ Jan 21 2016, 12:58) *
aдрес (указатель)

Адрес и указатель всё же разные вещи.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 21 2016, 10:18
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Чтобы не было мучительно больно в дальнейшем, для хранения адреса используйте не uint32_t, а специально предназначенный для этого uintptr_t. Тогда этот код будет работать и на AVR и под 64-битной Windows. А в общем случае, да, надо использовать указатель.
Цитата(Jenya7 @ Jan 21 2016, 11:49) *
компайлер осторожничает. требует явного приведения.
Компилятор строго выполняет требования Стандарта о неявном приведении типов.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 21 2016, 10:56
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



извиняюсь.моя ошибка - у меня переменная флоат.
то есть так я получу адрес переменной?
Код
float * SetVariable(char *var)
{
    var = ToLower(var);
    if(strcmp(var,"temp")==0) return &temperature;
    if(strcmp(var,"hum")==0)  return &humidity;
       return 0;
}

конечная цель сохранить адрес в структуре и иметь доступ к переменной.
Код
struct sTaskParams
{
    float *var;
    float compValue;
    uint8_t logicGate    
       uint8_t compare
};

struct sTaskParams param;

param.var = SetVariable(“temp”);
if(*(param.var) > 100)
  //do something
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Jan 21 2016, 11:45
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(Jenya7 @ Jan 21 2016, 10:56) *
извиняюсь.моя ошибка - у меня переменная флоат.
то есть так я получу адрес переменной?


Гы-гы-гы, нет, конечно..
Вас тут половина форума уже почти год пытается научить кодить пристойно , а воз и ныне там.
Ваша гениальная SetVariable() функция обладает следующими методологическими недостатками:
- Как уже указывалось выше, ее имя не соответствует тому, что она делает
- У нее есть замечательный side effect: либо она пытатся изменить данные по указателю, передаваемому в качестве параметра (привет ToLower("abcd")), либо ToLower() работает криво (одно из двух: теряет память, или возвращает указатель на удаленные данные на стеке).

Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 25 2016, 07:58
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



вобщем то, несмотря на ущербные названия функции и прочие страсти все работает.
а если я хочу сделать обратную операцию? вернуть название переменой по ее адресу?
Код
char *GetVariable(float var)
{
    float * fptr;
    fptr = &var;
    switch ((uint32_t)fptr)
    {
        case 0: return "TEMP";  break;
        case 1: return "HUM";   break;
        case 2:    return "SOIL";  break;
        case 3:    return "LIGHT"; break;
        default: return " ";    break;
    }
}

как мне в кейсах прописать адреса переменных?
Go to the top of the page
 
+Quote Post
gerber
сообщение Jan 25 2016, 08:41
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(Jenya7 @ Jan 25 2016, 10:58) *
а если я хочу сделать обратную операцию? вернуть название переменой по ее адресу?

В вашем примере var - локальная переменная на стеке, поэтому сравнивать её адрес с чем-то бессмысленно.
И break после return тоже лишний.
В функцию нужно передавать уже адрес глобальной переменной.
Код
const char *GetVariableName(float* var_addr)
{
    switch (var_addr)
    {
        case &temperature:  return "TEMP";
        case &humidity:        return "HUM";
        case &soil:            return "SOIL";
        case &light:           return "LIGHT";
        default:                    return "";
    }
}


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 25 2016, 08:42
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Jenya7 @ Jan 25 2016, 09:58) *
как мне в кейсах прописать адреса переменных?
Для начала вам надо усвоить такие понятия, как передача параметра в функцию по значению и по указателю.
Код
char * GetVariable(float * var)
{
    if(var == &temperature)
        return "TEMP"
    elseif(var == &humidity)
        return "HUM";
   ....
}

Со switch() не получится - он требует, чтобы метки case были константными выражениями времени компиляции. А адреса переменным присваивает линкер, т.е. на этапе компиляции они неизвестны.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jan 25 2016, 08:51
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



понял. спасибо.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th May 2024 - 13:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.0152 секунд с 7
ELECTRONIX ©2004-2016