LINUX.ORG.RU

Как посчитать кол-во байт в массиве

 


1

2

Здравствуйте.

Предположим есть массив…

uint8_t buf[] = {0x01,0x06,0x00,0x07,0x00,0x08};

Как посчитать количество байт в этом массиве. strlen() не подходит так как есть нули.

Может вопрос простой, но что-то я не соображу как это сделать?


В общем случае никак. Это же C. В твоём sizeof должен подойти.

hateyoufeel ★★★★★
()

Прежде всего, нужно определиться, что это за массив. Если это просто константа, которую ты задаешь в исходном коде, то sizeof даст тебе значение - размер массива.

Если ты получаешь массив откуда-то извне, то тебе оттуда и должны передать его длину вместе с самим массивом. Иначе никак, это же просто последовательность байт.

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

Собственно да, вопрос по большей части касался этого, - «Если ты получаешь массив откуда-то извне».

Допустим массив передали по УАРТу (микроконтроллер), я принял весь массив, но не считал кол-во принятых байт, то есть массив у меня появился. Получается что я не смогу посчитать его размер?

stD
() автор топика

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

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

Да не в этом дело. Вопрос не совсем корректно задан. Допустим, гипотетически, в программе появился массив. То есть это не массив который создавался на этапе компиляции и к нему можно применить sizeof, и не массив к которому можно применить strlen() так как в середине массива есть нули.

Есть ли возможность измерить его длину/посчитать кол-во байт?

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

А как можно в таком случае принять весь массив и не считать принятые байты

Можно. Задаёшь заведомо больший буфер, и ждёшь прерывания по IDLE (stm32). Или просто получаешь прерывание что буфер заполнен, а то что не влезло уходит в небытиё.

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

Нет.

Должны быть какие-то соглашения, о том, что, как и в каком виде передает данные. Если «просто так», то вся память просто пронумерованная последовательность байт.

Deleted
()

Или терминатор в конце должен быть (в Си это \0, в DOS это '$'). Или размер (как строки в Паскале).

Если (1) точно известно какой последовательности бит не может быть + (2) точно известно максимальный размер принимаемых байт, то можно выкрутиться выделив заведомо больший массив полностью заполненный нелегальными для источника данными. Чтобы (1) было наверняка - закодировать в 7 бит на стороне источника.

Других вариантов не придумывается )

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

Задаёшь заведомо больший буфер, и ждёшь прерывания по IDLE И все сломается если придет больше чем ты рассчитывал. Однако, если принимаешь по прерываниям, то все равно придется инкрементировать адрес по которому пишешь принятые байты. Начальный адрес в любом случае придется хранить, а значит количество байт можно будет вычислить как разницу между конечным адресом и начальным адресом. Или просто получаешь прерывание что буфер заполнен Это теперь про ПДП? Разумеется ПДП считает байты, а можно ли прочитав какой-то регистр узнать сколько принял контроллер ПДП - это уже вопрос по реализации конкретного контроллера.

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

Допустим массив передали по УАРТу (микроконтроллер), я принял весь массив, но не считал кол-во принятых байт, то есть массив у меня появился.

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

Есть ли возможность измерить его длину/посчитать кол-во байт?

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

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

Пардон, соврал. Просто sizeof(buf) , без умножения.

anonymous
()

Как посчитать количество байт в этом массиве

Никак. Ты должен где-то сохранить длину в процессе создания такого массива.

no-such-file ★★★★★
()

привет. я сам не очень в программировании. прошу помощи у всех. вот зашел опять чтобы обратиться с вопросом и увидел твою тему.

что сказать. вобщем если массив не динамический, к примеру имя у него 'A', то делаешь что -то вроде этого...

sizeof(A)// выдаст размер массива в байтах.

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

sizeof(A)/sizeof(A[0])// выдаст количество элементов массива.



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

мы могли бы взять и A[1]; потому как тип у всех элементов массива одинаковый, допустим int(8байт к примеру) то каждый элемент массива будет иметь размер 8байт. на этом принципе и построена адресная арифметика.

A+1; // тут мы прибавили к адресу  первого элемента массива 8байт, и значит перешли ко второму элементу, то есть A+1==A+8байт. вы же помните что имя массива это адрес его первого элемента в памяти. поэтому мы так можем шагать 

A+1;
A+2;
A+3;

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

может не потеме, но вдруг кому сгодится.

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

Не бывает таких «массивов». Это указатели.

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

Все правильно сказал пользователь который удалился.


void test(int arr[]){

printf("%d\n",sizeof(arr)/sizeof(int));

}


void main(){

int arr[] = {10,20,30,40,50};

printf("%d\n",sizeof(arr)/sizeof(int));

test(arr);
}

sizeof(arr) в main выдаст 20 (байт). В функции тест выдаст 4. так как будет расматривать не как массив а как указатель.


$gcc main.c -o main && ./main
$5
$1

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

Допустим массив передали по УАРТу (микроконтроллер), я принял весь массив, но не считал кол-во принятых байт, то есть массив у меня появился.

Тогда придётся запоминать значение переданное функцией read. Или даже делать суммирование в переменную нескольких значений, если ты вычитываешь за несколько проходов. Это и будет размер твоего массива.

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

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

удивлен, что вы изучаете СИ в место шарпов, как это делают все. щас куда не глянь, везде шарписты и джависты.

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

Я даже не расматривал. Только на слуху что такой яп есть. И очень наподобие java.

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

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

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

Храни размер вместе с данными и передавай структуру, а не голый массив.

typedef struct
{  uint8_t * array;
   size_t    size;
}array; 

Чёт типа такого


enum { SIZE = 100500 };

array ar = {malloc(sizeof(char)*SIZE),SIZE};

uint8_t bla[120];
array ra = {&bla,120};

for(int x = 0; x < ar.size,x++)
{
    printf("%d\n",ar.array[i]);
}

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.