Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.50/10: Рейтинг темы: голосов - 10, средняя оценка - 4.50
BeginerMan
49 / 48 / 14
Регистрация: 17.11.2012
Сообщений: 427
#1

Как сохранить float в переменной типа char?

01.05.2016, 20:43. Просмотров 1856. Ответов 76
Метки нет (Все метки)

Всем здрасьте.
Как можно записать float в char ?
И как потом float вытащить из char, если он будет находится примерно посередине ну или в начале?

C++
1
2
3
4
5
6
7
8
float x;
char str[100]
// Запих x в str
//...
// Вытащить float ?
str[0-40] = // ... 
str[41] = //  если я знаю, что float начинается с 41 символа, к примеру
str[45-99] = //....
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2016, 20:43
Ответы с готовыми решениями:

Как присвоить значение одного из элементов массива типа char переменной типа int?
С++ начал буквально только что так что буду благодарен за терпение и понимание...

Переменной d присвоить первую цифру после запятой некоторой переменной x типа float
Нужно целой переменной d присвоить первую цыфру после комы некоторой переменной...

Как работать с переменной типа char?
Не понимаю переменную char и как с ней работать.

Как получить адрес переменной типа unsigned char?
Всем привет! Как получить адрес переменной типа unsigned char? Всё ерунда...

Преобразование типа char в тип float
При считывании из файла чисел (каждое число расположено на новой строке, целая...

76
ValeryS
Модератор
7211 / 5474 / 681
Регистрация: 14.02.2011
Сообщений: 18,523
02.05.2016, 13:29 #21
Цитата Сообщение от hoggy Посмотреть сообщение
я так и не понял, содержит ли такой код UB,
код не атомарный
представь что один поток достает char-ы достал парочку, в это время другой поток переписывает float следующие char-ы могут быть из нового значения

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
memcpy(&ret,&src,sizeof(src));
тоже не атомарный
0
hoggy
Заблокирован
Эксперт С++
02.05.2016, 13:42 #22
Цитата Сообщение от ValeryS Посмотреть сообщение
код не атомарный
атомарность не причем.

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

хотя в с++11 вроде какие то оговорки появились, что можно,
если у них "common initial sequence"

но в данной ситуации это не тот случай.
0
vxg
Модератор
3247 / 2048 / 322
Регистрация: 13.01.2012
Сообщений: 7,926
02.05.2016, 20:36 #23
hoggy, инвалидская оптимизация уродуюшая 100% легальный код, зашибись подарочек, ну будем знать, спс
0
hoggy
Заблокирован
Эксперт С++
02.05.2016, 21:02 #24
Цитата Сообщение от vxg Посмотреть сообщение
оптимизация уродуюшая 100% легальный код
в том то и дело, что код нелегальный.
оптимизации не вредят легальному коду.
0
vxg
Модератор
3247 / 2048 / 322
Регистрация: 13.01.2012
Сообщений: 7,926
02.05.2016, 21:13 #25
hoggy, этот код легальный. memcmp - легальная? А где в ней все эти страшные модификаторы ? Нет.
0
hoggy
Заблокирован
Эксперт С++
02.05.2016, 21:18 #26
Цитата Сообщение от vxg Посмотреть сообщение
этот код легальный
код, который нарушает алиасинг нелегальный.
код, который использует конструкции не имеющие гарантий - нелегальный.
Цитата Сообщение от vxg Посмотреть сообщение
memcmp - легальная?
memcpy легальна.
Цитата Сообщение от vxg Посмотреть сообщение
А где в ней все эти страшные модификаторы
не понял вопроса.
0
cordfield
44 / 44 / 19
Регистрация: 04.05.2014
Сообщений: 189
02.05.2016, 21:45 #27
vxg, технически данная оптимизация компилятора легальна исходя из стандарта C++. Но даже Линус Торвальдс жаловался на такое поведение. Стандарт допускает подобное, но не предписывает компилятору так себя вести. С точки зрения разработчиков компилятора - это как поиск лазеек в законе, чтобы программистам жизнь мёдом не казалась.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
02.05.2016, 22:18 #28
В примере из
https://habrahabr.ru/post/114117/
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
typedef unsigned int DWORD;
typedef unsigned short WORD;
 
inline DWORD SwapWords ( DWORD val )
{
      WORD * p = (WORD*) &val;
      WORD t;
      t = p[0];
      p[0] = p[1];
      p[1] = t;
      return val;
}
 
int main()
{
      printf ( "%d\n", SwapWords(1) );
      return 0;
}
как я понял, компилятор не пишет по указателю p так как уверен, что на значении val это никак отразиться не может. Умный.
У меня MVS и я не могу это проверить, но верю.
Однако когда берётся указатель на отдельную память, соответствующего ему типа (и туда ничего больше не указывает!) и туда пишется значение полученное от разыменования указателя полученного приведением от другого типа, то о какой оптимизации тут может идти речь? Или таки может? Не ужели такой код не будет вести себя предсказуемо:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const size_t storage_size=6;
unsigned long long strange_storage[storage_size];
double arr_fl[]={1.234, 5.678, 123.34e25, 34, -0.3131, +33434.2};
for( size_t i=0; i<storage_size; ++i){
strange_storage[i]=*reinterpret_cast<unsigned long long*>(arr_fl+i);
cout<<strange_storage[i]<<"\tis\t"<<*reinterpret_cast<double*>(strange_storage+i)<<endl;
}
    system("pause");
return 0;
}
?
0
vxg
Модератор
3247 / 2048 / 322
Регистрация: 13.01.2012
Сообщений: 7,926
02.05.2016, 22:30 #29
hoggy, если легальная функция оперирующая указателями на память по адресам которых хранится не тот тип что указан в указателях и эти указатели не объявлены рестрикт то чем это отличается от простого кода без всей этой лабуды?
0
grizlik78
Эксперт С++
1983 / 1476 / 191
Регистрация: 29.05.2011
Сообщений: 3,050
02.05.2016, 22:46 #30
Преобразования типов действительно опасная штука, но не стоит нагонять панику, совместимость char* с другими типами никто не отменял.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
using namespace std;
 
double const e_const = 2.7182818284590451;
double e_var;
 
template<typename T>
void test(void *v)
{ 
    e_var = 3.14159;
    for (unsigned i = 0; i < sizeof(double)/sizeof(T); ++i)
        *((T*)v + i) = *((T*)&e_const + i);
    cout << e_var << endl;
}
 
 
int main()
{
    test<int>(&e_var);
    test<char>(&e_var);
}
Если скомпилировать эту программу с помощью GCC с ключом -O0 или -O1, то программа 2 раза ожидаемо напечатает число e, если же скомпилировать с ключами -O2 или -O3, то программа напечатает один раз число пи (ну или вправе напечатать) и один раз число e (поскольку обращение через char* легально к любым данным).
0
hoggy
Заблокирован
Эксперт С++
02.05.2016, 22:56 #31
Цитата Сообщение от vxg Посмотреть сообщение
если легальная функция оперирующая указателями на память по адресам которых хранится не тот тип что указан в указателях и эти указатели не объявлены рестрикт то чем это отличается от простого кода без всей этой лабуды?
1.
тем, что она оперирует понятием "байт", а не тип.

2.
каст к void* - легальная операция в ходе которой
утрачивается информация об исходном типе.

3.
функция имеет ряд ограничений.
например, в стандарте прямо сказано:

To avoid overflows, the size of the arrays pointed to by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).
то бишь области памяти не должны пересекаться (иначе UB).

5.
все остальное - это уже детали реализации самой функции.
разработчик которой писал её под конкретный компилятор,
и он в курсе его особенностей.
0
ValeryS
Модератор
7211 / 5474 / 681
Регистрация: 14.02.2011
Сообщений: 18,523
02.05.2016, 23:43 #32
Цитата Сообщение от hoggy Посмотреть сообщение
атомарность не причем.
спросил про UB,я и ответил при неатомарности любое "неопределенное поведение" может быть
Про strict aliasing rules ничего не могу сказать, с одной стороны разные типы в одном месте памяти, с другой объединения вполне себе легальная стандартная конструкция
0
grizlik78
Эксперт С++
1983 / 1476 / 191
Регистрация: 29.05.2011
Сообщений: 3,050
02.05.2016, 23:45 #33
Цитата Сообщение от ValeryS Посмотреть сообщение
с другой объединения вполне себе легальная стандартная конструкция
Формально она нелегальна, но сумасшедших не нашлось даже среди разработчиков GCC
0
hoggy
Заблокирован
Эксперт С++
03.05.2016, 00:02 #34
Цитата Сообщение от ValeryS Посмотреть сообщение
при неатомарности любое "неопределенное поведение" может быть
не нужно передергивать.

Цитата Сообщение от ValeryS Посмотреть сообщение
объединения вполне себе легальная стандартная конструкция
ага. и стандарт легендарно дает гарантии только при условии,
что активным является только один из членов объединения.

ну и начиная с с++11, добавилась гарантия для случая
"common initial sequence"

причем, стандарт си открыто объявляет доступ по неактивному члену уб.
а вот в стандарте с++ такого прямого тезиса нету.

что дает повод для сомнений.
некоторые полагают с++ близок по низкоуровневой механике к си,
и поэтому опасаются уб.

некоторые полагают, что уб нет,
потому что об этом нет записи в спецификации.

некоторые полагают,
что имеет место быть "поведение определяемое реализацией".

но все мнения сходятся в том,
что ситуация мутная.

и если нужен портируемый код, то лучше не рисковать,
и не выходить за рамки реально-действующих гарантий.
то бишь не пытаться поиметь доступ через неактивный член,
если он не является layout-compatible type.
0
vxg
Модератор
3247 / 2048 / 322
Регистрация: 13.01.2012
Сообщений: 7,926
03.05.2016, 07:24 #35
hoggy, grizlik78, ValeryS, наверное я все же что-то не так понимаю. Объясните совсем-присовсем просто что непонятного для компилятора должно быть в том что я беру адрес одного типа и пытаюсь работать с этим адресом так как будто по нему лежит другой тип? Я не беру ситуацию когда функция оперирующая с такими указателями (например memcpy) получает указатели на пересекающиеся области - дегенерату а не то что компилятору понятно что поведение функции в этом случае определяется её реализацией но в любом случае результат будет неверным просто потому что аргументы недопустимые. В обычной работе с указателями (в том числе и с преобразованиями их по типам) я не могу увидеть никакого греха - все происходит в рамках самого понятия УКАЗАТЕЛЬ и поведение оптимизатора в данном случае это какой-то идиотский баг.
0
cordfield
44 / 44 / 19
Регистрация: 04.05.2014
Сообщений: 189
03.05.2016, 09:40 #36
vxg, компилятор может подумать, что указатели имеют разные типы, значит указывают на разные данные. И он поменяет местами инструкции чтения и записи данных в целях оптимизации. Скажем, сначала сработает вывод в cout содержимого памяти, а уже потом в эту память будет что-то записано. Следовательно, cout выведет мусор или то, чем память была изначально инициализирована до записи полезных данных.
0
ValeryS
Модератор
7211 / 5474 / 681
Регистрация: 14.02.2011
Сообщений: 18,523
03.05.2016, 09:45 #37
Цитата Сообщение от hoggy Посмотреть сообщение
активным является только один из членов объединения.
вот здесь, реально, не понял
что значит активными?
можно пользоваться?
и когда? в определенный момент времени? или при жизни всей программы?
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7045 / 3346 / 452
Регистрация: 04.12.2011
Сообщений: 9,304
Записей в блоге: 5
03.05.2016, 10:02 #38
Цитата Сообщение от ValeryS Посмотреть сообщение
что значит активными
тот кто писался последним. Напоминает FIFO.
Причем, практически везде, где об этом упоминают, ссылаются на что-то в стандарте, но с оговоркой, что в реальной жизни все известные компиляторы реализуют доступ к обоим значениям по-человечески.
0
hoggy
Заблокирован
Эксперт С++
03.05.2016, 13:29 #39
Цитата Сообщение от vxg Посмотреть сообщение
наверное я все же что-то не так понимаю.
ну почитайте статью на хабре.
я там выше ссылку оставлял.

Цитата Сообщение от ValeryS Посмотреть сообщение
что значит активными?
активный член юниона - тот, через который осуществлялась запись.
при этом все остальные члены являются неактивными.
Цитата Сообщение от ValeryS Посмотреть сообщение
и когда? в определенный момент времени? или при жизни всей программы?
стандарт говорит по этому поводу:
9.5 Unions
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time. [ Note: One special guarantee
is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout
structs that share a common initial sequence (9.2), and if an object of this standard-layout union type
contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2. — end note ]
можно в любой момент
установить (записать) значение юниона по любому члену.

но читать можно только либо по активному члену (по которому выполнялась запись),
либо по члену, которые имеет совместимый леяут.

"совместимый леяут" может быть у двух членов с одинаковыми типами.
либо у двух разных структур,
но которые содержат члены одинакового типа.
1
vxg
Модератор
3247 / 2048 / 322
Регистрация: 13.01.2012
Сообщений: 7,926
03.05.2016, 16:41 #40
cordfield, hoggy, я реально понял лишь то что "эти" уроды добрались до самого лучшего языка и хотят его обессмыслить: "теперь" в "их" понимании указатель это просто некая сущность но никак не адрес по которому можно обратится - и кому он такой "теперь" нужен? Зачем умножили на ноль его гибкость? Для оптимизаторов? Идиотизм. Скажите хоть компиляторов каких стандартов следует избегать?

Добавлено через 4 минуты
... А конструкция
C++
1
char *p = (char *)(DWORD)&x;
Будет работать на 32 битных машинах?
1
03.05.2016, 16:41
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2016, 16:41

Работа с битами: как просмотреть и изменить заданный бит в переменной типа char?
Есть переменная типа char, как посмотреть в нем биты и изменять их?

Как полю класса типа char* присвоить значение типа *char
Проблема в строчке 46 (не пинайте сильно за формат кода и за говнокод) ...

Вывод переменной типа char
Переменная x типа char. x = 65; cout &lt;&lt; x; Так выводиться &quot;A&quot;. x =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru