Я хочу, чтобы можно было копировать произвольное количество данных, а не весь массив. А дополнительно, знать размер массива хотел, чтобы сделать контроль (защиту от дурака) того, что пользователь функции не запросил данных больше, чем есть в массиве.
Вопросы по С/С++ (СИ)
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
[uquote="WiseLord",url="/forum/viewtopic.php?p=3572368#p3572368"]А что мешает передавать размер массива через len? ...[/uquote]
Я хочу, чтобы можно было копировать произвольное количество данных, а не весь массив. А дополнительно, знать размер массива хотел, чтобы сделать контроль (защиту от дурака) того, что пользователь функции не запросил данных больше, чем есть в массиве.
Я хочу, чтобы можно было копировать произвольное количество данных, а не весь массив. А дополнительно, знать размер массива хотел, чтобы сделать контроль (защиту от дурака) того, что пользователь функции не запросил данных больше, чем есть в массиве.
- Реклама
Перейти на stl и передать вместо массива ссылку на объект типа vector или array. А от них уже брать размер.Вопрос: как имея указатель на массив uint8_t из другого файла проекта, получить длинну этого массива ВНУТРИ этой функции ?
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Есть проект из 2 исходных файлов + 1 свой хидер. В обоих исходных файлах необходимо включение своего хидера. В одном из исходных файлов необходимо включение stdio.h + stdint.h, а в другом только stdio.h. Как сделать правильно: включить stdio.h + stdint.h в свой хидер, и подключить к обоим исходным файлам, или не включать их в свой хидер, и подключить в каждом исходнике только необходимые ему хидеры ?
формально правила хорошего тона требуют включать в исходник модуля только те хидеры, что необходимы для компиляции этого модуля.
а не формально - без разницы
а не формально - без разницы
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
[uquote="ARV",url="/forum/viewtopic.php?p=3573163#p3573163"]формально ... не формально ...[/uquote]
А как поступаете в таких случаях Вы
?
А как поступаете в таких случаях Вы
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="Пока_без_кота",url="/forum/viewtopic.php?p=3573178#p3573178"]А как поступаете в таких случаях Вы
?[/uquote]Код должен быть написан так, чтобы включение "лишнего" заголовочного файла ни на что не влияло.
начинаю я всегда именно так, как вам и посоветовал, т.е. "правильно". но по мере роста количества модулей растет и колчество связей между ними, и часто в конечном итоге получается "как всегда": в исходнике список на полторы страницы из подключаемых заголовков...Пока_без_кота писал(а):А как поступаете в таких случаях Вы
периодически делаю "рефакторинг"...
это правильно сказано. если заключать тело любого заголовочника в "дефайны безопасности", как рекомендуется, то хоть в 250 местах приинклюживай - ничего страшного не произойдет. но в конечном итоге это способствует именно тому бардаку, к которому я и прихожу в своей деятельностиVladislavS писал(а):Код должен быть написан так, чтобы включение "лишнего" заголовочного файла ни на что не влияло
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
[uquote="ARV",url="/forum/viewtopic.php?p=3573233#p3573233"]по мере роста количества модулей растет и колчество связей между ними, и часто в конечном итоге получается "как всегда": в исходнике список на полторы страницы из подключаемых заголовков[/uquote]по-хорошему надо при таком положении дел сооружать эдакие "макромодули", хоть как-то группирующие мелкие и светящие наружу своими интерфейсами. Но всегда лень, да 
- Сообщения: 1457
- Зарегистрирован: Вт июн 07, 2011 08:03:18
Скажите пожалуйста, правильно ли я понимаю массивы в Си
Есть у меня потребность в создании двумерного массива, пусть
unsigned long int button [4][4];
Здесь более или менее понятно, что создается массив в памяти, который для простоты понимания является двумерным, у которого 4 строки и 4 столбца. Т.е. 16 ячеек, которые по 32 бита, или 16 слов, 16 элементов.
Теперь мне надо обратиться к первому элементу массива, я должен написать
button [0][0] = 132;
Т.е. Первый элемент считается от нуля, а строки при объявлении массива считаются от 1? И тогда последний элемент массива будет у меня
button [3][3] ???
Есть у меня потребность в создании двумерного массива, пусть
unsigned long int button [4][4];
Здесь более или менее понятно, что создается массив в памяти, который для простоты понимания является двумерным, у которого 4 строки и 4 столбца. Т.е. 16 ячеек, которые по 32 бита, или 16 слов, 16 элементов.
Теперь мне надо обратиться к первому элементу массива, я должен написать
button [0][0] = 132;
Т.е. Первый элемент считается от нуля, а строки при объявлении массива считаются от 1? И тогда последний элемент массива будет у меня
button [3][3] ???
Станислав
Путано как-то все. Пришлось в 10 местах про массивы прочитать, чтобы дошло... и все равно неоднозначно так. Размер от 1 до n, а элементы от 0 до n-1. Не логично.
Добавлено after 22 minutes 11 seconds:
Еще вопросик. Я сдвинул число нужное мне вправо на 12 позиций. Типа
temp = (temp >> 12);
В итоге по задумке нужные мне биты (значащие) находятся в первых четырех битах слова. Остальные нули.
Как узнать на какой позиции в первых четырех битах стоит единица? Она может быть только одна. Т.е. 0001, либо 0010, либо 0100, либо 1000. Мне надо знать позицию единицы 0, 1, 2 или 3.
Добавлено after 22 minutes 11 seconds:
Еще вопросик. Я сдвинул число нужное мне вправо на 12 позиций. Типа
temp = (temp >> 12);
В итоге по задумке нужные мне биты (значащие) находятся в первых четырех битах слова. Остальные нули.
Как узнать на какой позиции в первых четырех битах стоит единица? Она может быть только одна. Т.е. 0001, либо 0010, либо 0100, либо 1000. Мне надо знать позицию единицы 0, 1, 2 или 3.
Станислав
Неправильно мыслите. Размер не "от 1 до n", а просто "n"СКАЗОЧНИК писал(а):Размер от 1 до n, а элементы от 0 до n-1. Не логично
Как вариант - сдвигать дальше на 1 и считать сдвиги.СКАЗОЧНИК писал(а):Как узнать на какой позиции в первых четырех битах стоит единица?
Последний раз редактировалось WiseLord Ср фев 20, 2019 16:45:39, всего редактировалось 1 раз.
Да, неправильно. Я имею ввиду, что начало размера не от нуля. )
Добавлено after 1 minute 53 seconds:
Я примерно решил задачу выше через цикл и условие. В цикле переменная i автоматом бы заполнялась до нужной позиции, где стоит единица.
Но может есть проще варианты?
Добавлено after 1 minute 53 seconds:
Я примерно решил задачу выше через цикл и условие. В цикле переменная i автоматом бы заполнялась до нужной позиции, где стоит единица.
Но может есть проще варианты?
Станислав
У размера нет начала или конца, он просто есть сам по себе - одно число, по сути - количество элементов.СКАЗОЧНИК писал(а):Я имею ввиду, что начало размера не от нуля. )
P.S. А зачем знать именно _позицию_ единицы? Сразу, готовые маски 0x08, 0x04, 0x02, 0x01 вместо позиции никак бы не подошли?
P.P.S.
Код: Выделить всё
int orig_num = 0x4000;
// Вместо сдвига >> 12 и вычисления позиции единицы (2):
if (orig_num & 0x8000) {
// Сразу делаем то, что собирались с вычисленной позицией 3
} else if (orig_num & 0x4000) {
// Сразу делаем то, что собирались с вычисленной позицией 2
} else if (orig_num & 0x2000) {
// Сразу делаем то, что собирались с вычисленной позицией 1
} else if (orig_num & 0x1000) {
// Сразу делаем то, что собирались с вычисленной позицией 0
}Если вот так сделаю, примерно правильно будет?
А где-то дальше уже обращение к элементу массива типа
indikator = button [stroka][stolbetz];
Добавлено after 10 minutes 27 seconds:
Я просто пока мало еще понимаю, что в памяти займет больше места и что по быстродействию будет лучше.... Цикл с условием или просто условия.
Добавлено after 36 seconds:
З.Ы. Еще через case можно сделать.
Ищу красивый оптимальный вариант.
Добавлено after 7 minutes 9 seconds:
З.З.Ы. А вообще это я просто изучаю работу с матричной клавиатурой на СТМ32 с языком Си. Изначально забил массив с кнопками. А потом считываю строки клавиатуры и то значение, которое вернулось должно совпадать с элементом массива. А из массива уже присваиваю на вывод (пусть на индикатор).
Может не оптимальный вариант, но такой взбрел в голову и где-то подсмотрел.
А т.к. опрос клавиатуры происходит по системному таймеру, то надо бы все равно в прерывании побыстрее все делать. Чтобы только готовый результат был с кодом кнопки.
Добавлено after 10 minutes 26 seconds:
P/S И еще, вроде как прерывание по тому же системному 24 битному таймеру - это обычная функция. Но по умолчанию она описана как
void SysTick_Handler (void)
А если у меня в ней вычисляются глобальные переменные, то надо менять тип возвращаемого значения? Или у меня эта функция все равно ничего не возвращает?
Код: Выделить всё
unsigned long int stroka = 0;
temp = (((~(GPIOB->IDR)) & 0xF000) >> 12); // считать первую строку и двинуть ее в начало слова
while ((temp & 1) != 0)
{
temp >>= 1;
stroka++;
}
stolbetz = 0;
indikator = button [stroka][stolbetz];
Добавлено after 10 minutes 27 seconds:
Я просто пока мало еще понимаю, что в памяти займет больше места и что по быстродействию будет лучше.... Цикл с условием или просто условия.
Добавлено after 36 seconds:
З.Ы. Еще через case можно сделать.
Ищу красивый оптимальный вариант.
Добавлено after 7 minutes 9 seconds:
З.З.Ы. А вообще это я просто изучаю работу с матричной клавиатурой на СТМ32 с языком Си. Изначально забил массив с кнопками. А потом считываю строки клавиатуры и то значение, которое вернулось должно совпадать с элементом массива. А из массива уже присваиваю на вывод (пусть на индикатор).
Может не оптимальный вариант, но такой взбрел в голову и где-то подсмотрел.
А т.к. опрос клавиатуры происходит по системному таймеру, то надо бы все равно в прерывании побыстрее все делать. Чтобы только готовый результат был с кодом кнопки.
Добавлено after 10 minutes 26 seconds:
P/S И еще, вроде как прерывание по тому же системному 24 битному таймеру - это обычная функция. Но по умолчанию она описана как
void SysTick_Handler (void)
А если у меня в ней вычисляются глобальные переменные, то надо менять тип возвращаемого значения? Или у меня эта функция все равно ничего не возвращает?
Последний раз редактировалось СКАЗОЧНИК Ср фев 20, 2019 18:08:49, всего редактировалось 1 раз.
Станислав
- Сообщения: 291
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3574472#p3574472"]Я просто пока мало еще понимаю, что в памяти займет больше места и что по быстродействию будет лучше.... Цикл с условием или просто условия.[/uquote]
Пусть меня закидают тапками. Да пофиг, не парься. Главное, чтобы 1) не было ошибок 2) код был максимально понятным
Почему не просто
Ситуации, когда не установлен ни один из четырех битов регистра, не может быть? Если может, то цикл будет бесконечным.
Ситуации, когда установлены несколько из четырех бит регистра, не может быть? Если может, то чему должна быть равна переменная stroka в этом случае?
Когда я просматриваю код, приведенный WiseLord, у меня таких вопросов не возникает.
Пусть меня закидают тапками. Да пофиг, не парься. Главное, чтобы 1) не было ошибок 2) код был максимально понятным
Код: Выделить всё
unsigned long int stroka = 0;Код: Выделить всё
int stroka = 0;Ситуации, когда установлены несколько из четырех бит регистра, не может быть? Если может, то чему должна быть равна переменная stroka в этом случае?
Когда я просматриваю код, приведенный WiseLord, у меня таких вопросов не возникает.
Последний раз редактировалось viiv Ср фев 20, 2019 18:17:09, всего редактировалось 1 раз.
Блин, точно. Может...viiv писал(а):Ситуации, когда не установлен ни один из четырех битов регистра, не может быть?
Теоретически может, но я пока не буду нажимать сразу несколько кнопок.viiv писал(а):Ситуации, когда установлены несколько из четырех бит регистра, не может быть?
У меня просто опрос матричной клавиатуры 4х4. Включаю первую строку (открытый коллектор) и считываю всю строку разом (на строках подтяжка к плюсу). То, что нажато, будет нулем, остальные единицами.
Включаю следующую строку. Опять считываю все разом, но уже номер строки равен двум (ну или единице, если я использую массив).
И т.д.
В итоге, после обработки получаем значение i,j элемента массива, который сохранен в памяти со значением кнопки клавиатуры.
Станислав
я матрицу 4х4 опрашиваю проще, за 6 обращений к регистрам порта
сначала делаю биты порта строк входами с подтяжкой, а биты столбцов - выходами с нулем. считываю пины строк - если где-то была нажата кнопка, то в одной или более строк будет считан 0. запоминаю считанное с инверсией, т.е. нажатые строки равны 1.
теперь делаю стобцы входами с подтяжкой, а строки - выходами и вывожу с инверсией то, что только что запомнил. в итоге получаю нули в тех столбцах, что соответствуют нажатым кнопкам. запоминаю это с инверсией тоже.
теперь оба запомненных значения соединяю в байт и получаю код, однозначно соответствующий нажатым кнопкам.
вот код для AVR для случая, когда матрица подключена к линиям одного и того же порта PORT_KBD (младшие 4 бита строки, старшие 4 бита столбцы):ALL_ROW это 0x0F, а ALL_COL это 0xF0 - маски всех битов строк и столбцов соответственно
сначала делаю биты порта строк входами с подтяжкой, а биты столбцов - выходами с нулем. считываю пины строк - если где-то была нажата кнопка, то в одной или более строк будет считан 0. запоминаю считанное с инверсией, т.е. нажатые строки равны 1.
теперь делаю стобцы входами с подтяжкой, а строки - выходами и вывожу с инверсией то, что только что запомнил. в итоге получаю нули в тех столбцах, что соответствуют нажатым кнопкам. запоминаю это с инверсией тоже.
теперь оба запомненных значения соединяю в байт и получаю код, однозначно соответствующий нажатым кнопкам.
вот код для AVR для случая, когда матрица подключена к линиям одного и того же порта PORT_KBD (младшие 4 бита строки, старшие 4 бита столбцы):
Код: Выделить всё
// подаем на все столбцы нули, а строки делаем входами с подтяжкой
DDR(PORT_KBD) = ALL_COL;
PORT(PORT_KBD) = ALL_ROW;
// запоминаем инверсное значение состояния строк
rows = (~PIN(PORT_KBD)) & ALL_ROW;
// делаем столбцы входами с подтяжкой, а на строки подаем запомненное значение с инверсией
DDR(PORT_KBD) = ALL_ROW;
PORT(PORT_KBD) = ~rows;
// запоминаем инверсное значение состояния столбцов
cols = ~PIN(PORT_KBD) & ALL_COL;
// отключаем порт
DDR(PORT_KBD) = 0;
// если строки и столбцы ненулевые
if(cols && rows) cols |= rows;
else cols = 0;
// теперь в cols имеем код, однозначно соответствующий нажатым кнопкам, можно делать с ним, что угодно
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


