2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3, 4, 5  След.
 
 c++ задача на битовые операции
Сообщение20.11.2019, 23:03 


28/10/19
5
задали задачу, не понимаю, что хотят от меня в условии:/
Вот само условие:
Напишите функцию, позволяющую работать с целым числом (long) как с "массивом" из четырех однобайтовых чисел (char)

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение20.11.2019, 23:10 
Заслуженный участник


27/04/09
28128
Видимо, не одну функцию, а пару:

Используется синтаксис C++
char get_byte(long a, int index)
long set_byte(long a, int index, char new_value)

где a — это число, воспринимаемое как массив. Первая функция выдаёт значение одного из байтов, вторая заменяет и возвращает новое число-массив, в котором заменили старое на новое.

Но плохо, если в задании не описали конкретные прототипы функций. Они могли например хотеть функцию

Используется синтаксис C++
void set_byte(long &a, int index, char new_value)

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

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение20.11.2019, 23:13 


05/09/16
12128
mmarin
Ну видимо на вход подается long и номер байта, а возвращается этот байт.
Хотя если "работать с" то наверное и читать и писать. А вы что думаете?

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение24.11.2019, 15:01 


27/02/09
253
Так это не функция, а юнион нужен. Например, так:

Используется синтаксис C++
#define CHARS_PER_LONG    4

union Long_And_Char {
private:
    long long_value;
    char char_values[CHARS_PER_LONG];
public:
    Long_And_Char() {}
    Long_And_Char(long v) { long_value = v; }
    operator long & () { return(long_value); }
    char & operator [] (size_t idx) { return(char_values[idx]); }
};
 

И теперь можно с этим Long_And_Char работать и как с длинным целым, и как с массивом из четырёх символов.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение24.11.2019, 15:23 
Заслуженный участник


27/04/09
28128
Ну тема называется «задача на битовые операции», значит видимо хотят проверить, как усвоено их использование, а не использование union.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 12:29 


09/05/16
138
guryev, к сожалению, в стандартном C++ этот код содержит неопределённое поведение (хотя в стандартном C работал бы). Согласно стандарту, работа с неинициализированными переменными - это неопределённое поведение, а присвоение одному элементу union автоматически делает все остальные неинициализированными. К счастью, GCC и многие другие компиляторы доопределяют поведение такого кода до ожидаемого.

Правильным согласно стандарту кодом будет использование std::memcpy, которое не использует ни type punning, ни ломает предположение strict aliasing.

Ну, или побитовые операции.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 13:48 


27/02/09
253
arseniiv в сообщении #1427458 писал(а):
Ну тема называется «задача на битовые операции», значит видимо хотят проверить, как усвоено их использование, а не использование union.
В задании написано:
mmarin в сообщении #1426977 писал(а):
Напишите функцию, позволяющую работать с целым числом (long) как с "массивом" из четырех однобайтовых чисел (char)
Согласен, предлагать union вместо функции не совсем верно. С функцией совсем просто, хотя и не так удобно:
Используется синтаксис C++
inline char *long_to_chars(long &v) {
        /* Type conversion from long & to char * here */
}
inline const char *long_to_chars(const long &v) {
        /* Type conversion from const long & to cost char * here */
}
 
Что написать на место /* Type conversion ... */ всяк должен знать.

aitap в сообщении #1427576 писал(а):
guryev, к сожалению, в стандартном C++ этот код содержит неопределённое поведение
Выглядит, как ерунда, но вы можете попробовать проиллюстрировать "неопределённое поведение" моего кода на примере - только в своей теме.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 14:10 
Заслуженный участник
Аватара пользователя


16/07/14
9215
Цюрих
guryev в сообщении #1427585 писал(а):
Выглядит, как ерунда
Выглядит как пересказ Стандарта (и неопределенное поведение - тоже термин из него).
Стандарт, 9.5.1 писал(а):
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.
Стандарт, 9.5.4 писал(а):
In general, one must use explicit destructor calls and placement new operators to change the active member of a union.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 14:22 


27/02/09
253
guryev в сообщении #1427585 писал(а):
Выглядит, как ерунда,
mihaild в сообщении #1427588 писал(а):
Выглядит как пересказ Стандарта (и неопределенное поведение - тоже термин из него).
Не, непохоже:
aitap в сообщении #1427576 писал(а):
guryev, к сожалению, в стандартном C++ этот код содержит неопределённое поведение
В стандарте такого точно нет :D

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 14:47 
Заслуженный участник
Аватара пользователя


16/07/14
9215
Цюрих
guryev в сообщении #1427590 писал(а):
Не, непохоже:
Я же процитировал стандарт с указанием конкретных пунктов, что "не похоже", чего "точно нет"?

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 15:20 


27/02/09
253

(Оффтоп)

mihaild в сообщении #1427594 писал(а):
Я же процитировал стандарт с указанием конкретных пунктов, что "не похоже", чего "точно нет"?
Что уж проще... Вот эта фраза:
aitap в сообщении #1427576 писал(а):
guryev, к сожалению, в стандартном C++ этот код содержит неопределённое поведение
по отношению к моему коду
guryev в сообщении #1427585 писал(а):
Выглядит, как ерунда
и на пересказ стандарта не похожа, поскольку в стандартах явно не содержится.

Может, лучше прочитать внимательнее, о чём шла речь, прежде, чем комментировать?

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 15:35 
Заслуженный участник
Аватара пользователя


16/07/14
9215
Цюрих
guryev в сообщении #1427602 писал(а):
и на пересказ стандарта не похожа, поскольку в стандартах явно не содержится.
Содержится. Ну чуть более точно: из написанного в Стандарте выводится, что ваш код содержит неопределенное поведение.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 15:48 
Заслуженный участник


27/04/09
28128
guryev в сообщении #1427585 писал(а):
В задании написано: <…>
и притом ещё в названии темы написано «задача на битовые операции». Вообще не понимаю о чём шум-гам, если ТС не появился с самого первого поста больше ни разу. Если бы ему что-то было не понятно или не подходили предыдущие предложения, он бы наверно написал, а так вы только зазря набирали свой пример; скорее всего он нашёл полное решение где-то в другом месте и сюда больше не заглянет вообще.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 16:03 
Заслуженный участник
Аватара пользователя


06/10/08
6422
В новом стандарте это еще более зарегламентированно, правда, разбросано по разным местам.

C++17 писал(а):
6.8(1). The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a
constructor other than a trivial default constructor. [ Note: Initialization by a trivial copy/move constructor is non-vacuous initialization. — end note ] The lifetime of an object of type T begins when:
(1.1) — storage with the proper alignment and size for type T is obtained, and
(1.2) — if the object has non-vacuous initialization, its initialization is complete, except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union (11.6.1, 15.6.2), or as described in 12.3. The lifetime of an object o of type T ends when:
(1.3) — if T is a class type with a non-trivial destructor (15.4), the destructor call starts, or
(1.4) — the storage which the object occupies is released, or is reused by an object that is not nested within o (4.5).

6.8(4). The properties ascribed to objects and references throughout this International Standard apply for a given object or reference only during its lifetime. [ Note: In particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the object, as described below, in 15.6.2 and in 15.7. Also, the behavior of an object under construction and destruction might not be the same as the behavior of an object whose lifetime has started and not ended. 15.6.2 and 15.7 describe the behavior of objects during the construction and destruction phases. — end note ]

6.8(7). Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see 15.7. Otherwise, such a glvalue refers to allocated storage (6.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:
(7.1) — the glvalue is used to access the object, or
(7.2) — the glvalue is used to call a non-static member function of the object, or
(7.3) — the glvalue is bound to a reference to a virtual base class (11.6.3), or
(7.4) — the glvalue is used as the operand of a dynamic_cast (8.2.7) or as the operand of typeid.

6.10(1.1) A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.

12(3). A union is a class defined with the class-key union; it holds at most one data member at a time (12.3). [...]

12.3(1). In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended (6.8). At most one of the non-static data members of an object of union type 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 (12.2), and if a non-static data member of an object of this standard-layout union type is active and is one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of the standard-layout struct members; see 12.2. — end note ]

12.3(5). When the left operand of an assignment operator involves a member access expression (8.2.5) that nominates a union member, it may begin the lifetime of that union member, as described below. For an expression E, define the set S(E) of subexpressions of E as follows:
(5.1) — If E is of the form A.B, S(E) contains the elements of S(A), and also contains A.B if B names a union member of a non-class, non-array type, or of a class type with a trivial default constructor that is not deleted, or an array of such types.
(5.2) — If E is of the form A[B] and is interpreted as a built-in array subscripting operator, S(E) is S(A) if A is of array type, S(B) if B is of array type, and empty otherwise.
(5.3) — Otherwise, S(E) is empty.
In an assignment expression of the form E1 = E2 that uses either the built-in assignment operator (8.18) or a trivial assignment operator (15.8), for each element X of S(E1), if modification of X would have undefined behavior under 6.8, an object of the type of X is implicitly created in the nominated storage; no initialization is performed and the beginning of its lifetime is sequenced after the value computation of the left and right operands and before the assignment. [ Note: This ends the lifetime of the previously-active member of the union, if any (6.8). — end note ]


Рассмотрим Ваш код:
Используется синтаксис C++
#define CHARS_PER_LONG    4

union Long_And_Char {
private:
    long long_value;
    char char_values[CHARS_PER_LONG];
public:
    Long_And_Char() {}
    Long_And_Char(long v) { long_value = v; }
    operator long & () { return(long_value); }
    char & operator [] (size_t idx) { return(char_values[idx]); }
};

Здесь пока неопределенного поведения нет. Но если мы начнем использовать этот union для целей нашей задачи, т.е. напишем, например,

Используется синтаксис C++
Long_And_Char x(12);
char c = x[0];

то во второй строке получим undefined behavior. Следите за руками: в первой строке вызывается конструктор Long_And_Char, и в соответствии с 6.8(1.2) и 12.3(5) по завершении этого конструктора начинается lifetime объектов x и x.long_value, но не x.char_value. Теперь x.long_value является active member of the object x.
Во второй строчке мы вызываем оператор индексации, и пытаемся получить доступ к объекту x.char_values[0] через glvalue char_values[idx], встречающееся в реализации оператора. И получаем undefined behavior, описанный в 6.8(7.1).

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 19:58 


27/02/09
253
mihaild в сообщении #1427605 писал(а):
из написанного в Стандарте выводится, что ваш код содержит неопределенное поведение.
Мой код не содержит неопределённого поведения.

Xaositect в сообщении #1427615 писал(а):
если мы начнем использовать этот union для целей нашей задачи, т.е. напишем, например,
код
Используется синтаксис C++
Long_And_Char x(12);
char c = x[0];
то во второй строке получим undefined behavior. Следите за руками: в первой строке вызывается конструктор Long_And_Char, и в соответствии с 6.8(1.2) и 12.3(5) по завершении этого конструктора начинается lifetime объектов x и x.long_value, но не x.char_value.
Нет, их обоих, это же union.

Другое дело, если написать:
Используется синтаксис C++
Long_And_Char x;
char c = x[0];
Тогда да, можно устроить undefined behavior. Но это уже не в моём коде.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 68 ]  На страницу 1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group