LINUX.ORG.RU

Как создать массив элементов с размером элементов некратным 2 и 4 байт и вообще из любой длины бит

 ,


0

4

Что-то я си подзабыл =)

Нужно:

Массив элементов, длиной три байта (вообще произвольное число байт). Как его объявить и использовать? Пока что придумалось только

struct __attribute__((__packed__)) byte3 
{
   char b1,b2,b3; /* или char b[3]; */
};

struct byte3 A[100000];

А есть ли более, так сказать, красивый способ? Тем более, что __attribute__((__packed__)) компиляторозависим. И нет уверенности, что в массиве компилятор не примется выравнивать байты, а надо чтобы 3+3+3+3+3+... плотно шли.

Задачка потруднее:

То же самое, но с массивом с произвольным количеством бит элементов, как правильно работать? Есть же какие-то типовые приемы.

★★★★★

Последнее исправление: praseodim (всего исправлений: 7)

char A[100000 * 3];
...
A[i * 3 + j]

То же самое, но с массивом с произвольным количеством бит элементов, как правильно работать? Есть же какие-то типовые приемы.

битовые маски

anonymous
()

с массивом с произвольным количеством бит элементов, как правильно работать? Есть же какие-то типовые приемы.

Делаешь функции для чтения-записи полей произвольной битности.

i-rinat ★★★★★
()

А что мешает в качестве элементов тоже массивы использовать?

bodqhrohro_promo
()

есть ещё #pragma оно более переносимо.

MKuznetsov ★★★★★
()

говнокод и говнокодер детекдет, идите заводы восстанавливать, не надо вам в ИТ

anonymous
()
Ответ на: комментарий от anonymous

А как великий гуру приказывает работать с бинарным файлом с примерно такой структурой данных?

praseodim ★★★★★
() автор топика
struct byte 
{
unsigned char bit0 : 1,
bit1 : 1,
bit2 : 1,
bit3 : 1,
bit4 : 1,
bit5 : 1,
bit6 : 1,
bit7 : 1;
} arr[1000];

Кривой костыль, да. Увы, задавать длину в битах элементам массива си не может. Шоб молучить доступ по адресу надо писать обертку.

timdorohin ★★★★
()
Последнее исправление: timdorohin (всего исправлений: 2)
Ответ на: комментарий от praseodim

А как великий гуру

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

А по теме - либо __packed__ и bitfields, или читай в буфер, а потом его расковыривай в нужные тебе структуры побитово.

Stanson ★★★★★
()
Ответ на: комментарий от Stanson

зачем вообще какие-либо структуры, когда речь идёт о наборе байт/бит? тем более ТС хочет хранить всё компактно и не париться из-за выравнивания. тут идеально подходит массив + набор макросов для доступа к элементам

anonymous
()
Ответ на: комментарий от anonymous

зачем вообще какие-либо структуры, когда речь идёт о наборе байт/бит?

Затем, чтобы сделать read( fd, data, sizeof( struct _binary_data ) ); и сразу получить готовые к использованию данные, а не заниматься онанизмом типа:

массив + набор макросов для доступа к элементам

Stanson ★★★★★
()
Ответ на: комментарий от praseodim

бинарные файлы приблизительно такой структуры имеют бесконечный размер, вот к примеру бинарный формат jpeg, сходите и полистайте как его читают, а он может быть ооочень большого размера

anonymous
()
Ответ на: комментарий от Stanson

кому очевидно ? вы себя в зеркале увидели ?

anonymous
()
Ответ на: комментарий от Stanson

ога, откуда знать похапешнику который кроме json ничего не умеет

anonymous
()
Ответ на: комментарий от anonymous

char A[100000][3];

Вообще конечно формально правильно и так лучше, но наверное надо уточнить, что массив на самом деле будет динамическим, то есть, заранее не известно число строк и не получится его объявить в памяти просто так.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от anonymous

__attribute__((__packed__)) компиляторозависим

Перед структурой:

#pragma pack(push, 1)
После структуры:
#pragma pack(pop)

SR_team ★★★★★
()
Ответ на: комментарий от anonymous

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

В принципе, учитывая, что реальное чтение данных на нижнем уровне происходит все-равно не по байтово, есть смысл все же попердолиться с указателями и чтением по кратно 32, 64 битам. Просто не хотелось залазить в это.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от SR_team

Проверил. GCC (тестил 4.3, 7.3, 8.2) понимает, clang8 тоже понимает, но clang-format из clang5 говорит, что не знает такого.

SR_team ★★★★★
()
Ответ на: комментарий от crutch_master

не не дружок, смотрим про заводы, зачем зп тыкать ? корреляция зп - нужны = нет, тогда смени свое исходное сообщение, не про ненужны а про тебе хочется по больше денежОк ничего не делая, тогда открываем glassdoor.com и смотрим, тысячи вакансий с зп побольше чем ты тычешь, и тоже никого найти не могут, вывод абсурдный программеры нужны - их нет, рабочие на заводы нужны - их нет, где люди ?

anonymous
()
Ответ на: комментарий от anonymous

смотрим про заводы

Нет зп, нет работяг, нет заводов. В муниципальном ит тоже з/п как на этих заводах и в жопе у кого наше отечественное ит?

crutch_master ★★★★★
()
Ответ на: комментарий от praseodim

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

anonymous
()
Ответ на: комментарий от praseodim

и не получится его объявить в памяти просто так

Тогда делай malloc(100500*3) и всё тоже самое. Это си. Какая разница какие тут структуры, выделяй сколько тебе памяти надо, кастуй через void* и делай с ней что хочешь.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от anonymous

зп на глассдоре нормальные ? в чем проблема ?

20-30 рублей? Для алкоголика, который с мамкой живёт - нормальная. Мужчине, в нашем регионе, надо 50+.
зы. на каком глассдоре? Мы про глубокое замкадье.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от anonymous

да да, как только начинается разбор так сразу все сливаются в абстрактные задачи

Куда сливается, что сливается? Я уже написал рабочий код, который делает то, что мне нужно. Но подумал, что как-то не оптимально и не очень красиво. Еще и с прагмами этими.

Почему и завел тему. Вместо того, чтобы отсылать рыться в исходниках libjpeg можно было бы написать три-четыре строчки, иллюстрирующие «как правильно».

Вывод. Или ты на самом деле тоже не знаешь «как правильно» или это правильно будет не в 3-4 строки, а в десятки строк из макросов и тогда уже не интересно.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от crutch_master

Тогда делай malloc(100500*3) и всё тоже самое.

Реально я сделал mmap на файл и работаю с ним как с массивом структур. Просто думал может можно как-то иначе все указать.

praseodim ★★★★★
() автор топика
Последнее исправление: praseodim (всего исправлений: 1)
Ответ на: комментарий от praseodim

Ну да. Функций кучу, чтобы выбирали что тебе надо по битам, байтам и т.д. Высчитываешь отступ, читаешь память, преобразовываешь, возвращаешь. Нормально, просто понятно. Не знаю, что тебя смущает, там ничего нет каноничного/правильного (даже vector или hashmap). Это си, там все пишут свои велосипеды. Главное, чтобы было просто понятно и после тебя разобраться можно было, поэтому, лучше не городить макросы, если это возможно.

crutch_master ★★★★★
()
Ответ на: комментарий от praseodim

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


char (*A)[3];

A = malloc(3*n);

обращение к элементам будет типа A[i][j].

anonymous
()
Ответ на: комментарий от anonymous

Хм, чего-то даже не подумал о таком. Спасибо.

praseodim ★★★★★
() автор топика
Последнее исправление: praseodim (всего исправлений: 1)
Ответ на: комментарий от LamerOk

По крайней мере в них указаны положительные числа.

Да, мне как-то приснилось, что я пришел на работу и мне там говорят, что я что-то там должен за месяц им заплатить.

crutch_master ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.