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

 
 
> Выдать из функции указатель на ее статическую переменную
ViKo
сообщение Dec 5 2014, 10:26
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



В функции преобразую строку в число, и хочу выдать указатель на это число, если оно получилось из строки, и NULL, если в строке галимотня.
Можно определить глобальную int32_t переменную, в которую преобразовывать строку, и выдавать указатель на нее. Не нравится, что переменная глобальная.
Могу ли создать статическую переменную внутри функции, и выдавать указатель на нее?
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 14)
Mc_off
сообщение Dec 5 2014, 10:35
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-01-07
Из: Ростовская область
Пользователь №: 24 044



При вызове функции передавайте туда указатель на внешнюю переменную, в которую будете возвращать указатель на переменную внутри функции. Стандартный подход.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 5 2014, 10:39
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если переменная внутри функции не статическая, то после выхода из функции ее не станет, аннигилирует.
Мне незачем передавать указатель в функцию, если я знаю, указатель на что хочу выдать.
Go to the top of the page
 
+Quote Post
_pv
сообщение Dec 5 2014, 10:45
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



да можно конечно, только вот зачем?
использовать нулевой указатель в качестве индикатора ошибки что строка плохая? не надо так делать.

int * func(const char * str){
static int num = 0;
if (!str) return 0;
num = atoi(str);
return #
}
Go to the top of the page
 
+Quote Post
adnega
сообщение Dec 5 2014, 10:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ViKo @ Dec 5 2014, 14:39) *
Если переменная внутри функции не статическая, то после выхода из функции ее не станет, аннигилирует.
Мне незачем передавать указатель в функцию, если я знаю, указатель на что хочу выдать.

Либо передавать указатель в функцию, либо передавать результат в возвращаемом значении.
Глобальная переменная, а уж тем более локальная переменная (пусть даже и static) - неоправданно для такого функционала.
Вроде, есть стандартные функции для перевода строки в число. Чем они не устраивают?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 5 2014, 10:54
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_pv @ Dec 5 2014, 13:45) *
да можно конечно, только вот зачем?
использовать нулевой указатель в качестве индикатора ошибки что строка плохая? не надо так делать.

int * func(const char * str){
static int num = 0;
if (!str) return 0;
num = atoi(str);
return #
}

Да, именно, для индикации ошибки. А чем плохо? atoi при неправильной строке выдает неопределенное значение. Мне это не подходит. Свое преобразование буду делать.

Цитата(adnega @ Dec 5 2014, 13:48) *
Либо передавать указатель в функцию, либо передавать результат в возвращаемом значении.
Глобальная переменная, а уж тем более локальная переменная (пусть даже и static) - неоправданно для такого функционала.
Вроде, есть стандартные функции для перевода строки в число. Чем они не устраивают?

А что мне выдаст atoi("XPEN_TEBE!") ? rolleyes.gif И как я об этом узнаю? Можно bool OK выдать, но все равно ссылку на результат нужно (ну, да, глобальную переменную можно).
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 5 2014, 11:09
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(ViKo @ Dec 5 2014, 13:54) *
А что мне выдаст atoi("XPEN_TEBE!") ? rolleyes.gif И как я об этом узнаю?

Для этого более продвинутая strtol есть.

А вообще, в старые добрые времена, для этого глобальная переменная "errno" была. Чтобы за собой всякие коды ошибок сообщать. Чем такой подход не устроил? сделать my_errno
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 5 2014, 11:19
Сообщение #8


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(ViKo @ Dec 5 2014, 12:26) *
В функции преобразую строку в число, и хочу выдать указатель на это число, если оно получилось из строки, и NULL, если в строке галимотня.
Можно определить глобальную int32_t переменную, в которую преобразовывать строку, и выдавать указатель на нее. Не нравится, что переменная глобальная.
Могу ли создать статическую переменную внутри функции, и выдавать указатель на нее?


Я бы возвращал число, а не указатель.
А в аргументы бы добавил указатель на идентификатор ошибки.
Если указатель на идентификатор NULL, то ошибку не записывать.

Таким образом можно либо вообще игнорировать ошибки (чтобы быстрее писать код) либо делать в определенных случаях детализированный лог ошибок.
Неплохой вариант переменную ошибки сделать глобальной.

Смысл в том чтобы с рабочими переменными поменьше применять указатели, а все что касается отладочных ситуаций и ошибок переводить на указатели как менее критичный код.
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Dec 5 2014, 11:20
Сообщение #9


Местный
***

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



Цитата(ViKo @ Dec 5 2014, 10:26) *
В функции преобразую строку в число, и хочу выдать указатель на это число, если оно получилось из строки, и NULL, если в строке галимотня.
Можно определить глобальную int32_t переменную, в которую преобразовывать строку, и выдавать указатель на нее. Не нравится, что переменная глобальная.
Могу ли создать статическую переменную внутри функции, и выдавать указатель на нее?


...чем только люди не страдают...
"Число-то" какого типа ?
Что мешает в общем виде сделать так ? предполагаем, что типа нашего числа int32

/**
@param pointer to a string to convert to a number
@param pointer to the variable that will be assigned the value on success
@return true if everything is OK
*/
bool MyAtoI(const char* apStr, int32* apRetVal)
{
[.. some dirty magic here..]
}

Сообщение отредактировал CrimsonPig - Dec 5 2014, 11:20
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 5 2014, 11:31
Сообщение #10


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Вижу, вариантов много. Но не вижу лучшего. rolleyes.gif
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 5 2014, 11:33
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(ViKo @ Dec 5 2014, 14:31) *
Вижу, вариантов много. Но не вижу лучшего. rolleyes.gif


Сделайте как в strtol - результат функции - само число. А указатель - на последний символ, на котором "запнулось" преобразование. По нему все сразу понятно. Если там isspace или ноль (конец строки), значит все ОК. Самая простая проверка - *endptr<=0x20 - под это попадает все сразу, все концы строк, ноль, пробел, табуляция.
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Dec 5 2014, 11:38
Сообщение #12


Местный
***

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



Цитата(ViKo @ Dec 5 2014, 11:31) *
Вижу, вариантов много. Но не вижу лучшего. rolleyes.gif


А не соизволит ли многоуважаемый Дон четко определить критерии "лучшести" ?
с моей т.з. все что есть лучше того бреда из первого поста.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 5 2014, 12:11
Сообщение #13


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(SM @ Dec 5 2014, 14:33) *
Сделайте как в strtol - результат функции - само число. А указатель - на последний символ, на котором "запнулось" преобразование. По нему все сразу понятно. Если там isspace или ноль (конец строки), значит все ОК. Самая простая проверка - *endptr<=0x20 - под это попадает все сразу, все концы строк, ноль, пробел, табуляция.

Функция сложновата, мне столько не нужно. Или в строке десятичное число со знаком или без, или "галимотня".
Указатель, ползущий по строке - сохраняется в глобальной переменной, для других парсерных функций. На этом числе еще не конец.
Go to the top of the page
 
+Quote Post
SM
сообщение Dec 5 2014, 12:18
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(ViKo @ Dec 5 2014, 15:11) *
Функция сложновата, мне столько не нужно. Или в строке десятичное число со знаком или без, или "галимотня".
Указатель, ползущий по строке - сохраняется в глобальной переменной, для других парсерных функций. На этом числе еще не конец.


Так тогда strtol вам и нужна в чистом ее виде. Зачем глобальная переменная с ползущим указателем, когда она при использовании strtol становится локальная - strtol ее и возвращает, именно, чтобы распознать галиматью, конец строки, или продолжить со следующим числом, все зайцы убиты одним выстрелом и без глобальных переменных. В strtol передаем указатель на текущее положение в строке, и передаем в качестве указателя на конец указатель на этот же указатель sm.gif sm.gif sm.gif - в результате он один и "ползет по строке".

Или, сделайте так:

int my_strtol(char **pPtr);

То есть сразу передаете в функцию указатель на указатель, который передвигается по строке. По тому, на чем он остановился после вызова функции, распознаете, что там. Это эквивалентно вызову strtol(ptr, *ptr, 10).
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 5 2014, 12:30
Сообщение #15


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(SM @ Dec 5 2014, 14:18) *
Так тогда strtol вам и нужна в чистом ее виде. Зачем глобальная переменная с ползущим указателем, когда она при использовании strtol становится локальная - strtol ее и возвращает, именно, чтобы распознать галиматью, конец строки, или продолжить со следующим числом, все зайцы убиты одним выстрелом и без глобальных переменных. В strtol передаем указатель на текущее положение в строке, и передаем в качестве указателя на конец указатель на этот же указатель sm.gif sm.gif sm.gif - в результате он один и "ползет по строке".


strtol опасна в плане RTOS, функции этого ряда могут внутри себя лезть в глобальный heap и в глобальные переменные.
Её либо надо ретаргетить, либо не использовать, либо лепить вокруг них критические секции.

Но если до красоты, то на мой эстетский взгляд самое красивое все делать в глобальных структурах. Т.е. объединять глобальные переменные в глобальные структуры.
Пока задача одна структура глобальна, как только задач несколько структуру одним движением превращаем в динамически выделяемую и уводим в управляющую структуру задачи.
Структуры никогда не подведут.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 23:56
Рейтинг@Mail.ru


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