Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Сообщение Пока_без_кота »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3572368#p3572368"]А что мешает передавать размер массива через len? ...[/uquote]
Я хочу, чтобы можно было копировать произвольное количество данных, а не весь массив. А дополнительно, знать размер массива хотел, чтобы сделать контроль (защиту от дурака) того, что пользователь функции не запросил данных больше, чем есть в массиве.
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Вопрос: как имея указатель на массив uint8_t из другого файла проекта, получить длинну этого массива ВНУТРИ этой функции ?
Перейти на stl и передать вместо массива ссылку на объект типа vector или array. А от них уже брать размер.
И день и ночь в пути...
Мои программки: 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 в свой хидер, и подключить к обоим исходным файлам, или не включать их в свой хидер, и подключить в каждом исходнике только необходимые ему хидеры ?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18815
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Сообщение Пока_без_кота »

[uquote="ARV",url="/forum/viewtopic.php?p=3573163#p3573163"]формально ... не формально ...[/uquote]
А как поступаете в таких случаях Вы :))) ?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Пока_без_кота",url="/forum/viewtopic.php?p=3573178#p3573178"]А как поступаете в таких случаях Вы :))) ?[/uquote]Код должен быть написан так, чтобы включение "лишнего" заголовочного файла ни на что не влияло.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18815
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Пока_без_кота писал(а):А как поступаете в таких случаях Вы
начинаю я всегда именно так, как вам и посоветовал, т.е. "правильно". но по мере роста количества модулей растет и колчество связей между ними, и часто в конечном итоге получается "как всегда": в исходнике список на полторы страницы из подключаемых заголовков...
периодически делаю "рефакторинг"...
VladislavS писал(а):Код должен быть написан так, чтобы включение "лишнего" заголовочного файла ни на что не влияло
это правильно сказано. если заключать тело любого заголовочника в "дефайны безопасности", как рекомендуется, то хоть в 250 местах приинклюживай - ничего страшного не произойдет. но в конечном итоге это способствует именно тому бардаку, к которому я и прихожу в своей деятельности :oops:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Сообщение Пока_без_кота »

VladislavS, ARV - благодарю.
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

[uquote="ARV",url="/forum/viewtopic.php?p=3573233#p3573233"]по мере роста количества модулей растет и колчество связей между ними, и часто в конечном итоге получается "как всегда": в исходнике список на полторы страницы из подключаемых заголовков[/uquote]по-хорошему надо при таком положении дел сооружать эдакие "макромодули", хоть как-то группирующие мелкие и светящие наружу своими интерфейсами. Но всегда лень, да :facepalm:
OKF
Это не хвост, это антенна
Сообщения: 1457
Зарегистрирован: Вт июн 07, 2011 08:03:18

Сообщение OKF »

Только не хидеры, а хедеры. А то как то уж совсем неприлично.)
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Скажите пожалуйста, правильно ли я понимаю массивы в Си


Есть у меня потребность в создании двумерного массива, пусть

unsigned long int button [4][4];

Здесь более или менее понятно, что создается массив в памяти, который для простоты понимания является двумерным, у которого 4 строки и 4 столбца. Т.е. 16 ячеек, которые по 32 бита, или 16 слов, 16 элементов.

Теперь мне надо обратиться к первому элементу массива, я должен написать

button [0][0] = 132;

Т.е. Первый элемент считается от нуля, а строки при объявлении массива считаются от 1? И тогда последний элемент массива будет у меня

button [3][3] ???
Станислав
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

да, как всегда, при объявлении - количество элементов, а индексы от нуля.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Путано как-то все. Пришлось в 10 местах про массивы прочитать, чтобы дошло... и все равно неоднозначно так. Размер от 1 до n, а элементы от 0 до n-1. Не логично.

Добавлено after 22 minutes 11 seconds:
Еще вопросик. Я сдвинул число нужное мне вправо на 12 позиций. Типа

temp = (temp >> 12);

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

Как узнать на какой позиции в первых четырех битах стоит единица? Она может быть только одна. Т.е. 0001, либо 0010, либо 0100, либо 1000. Мне надо знать позицию единицы 0, 1, 2 или 3.
Станислав
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

СКАЗОЧНИК писал(а):Размер от 1 до n, а элементы от 0 до n-1. Не логично
Неправильно мыслите. Размер не "от 1 до n", а просто "n"
СКАЗОЧНИК писал(а):Как узнать на какой позиции в первых четырех битах стоит единица?
Как вариант - сдвигать дальше на 1 и считать сдвиги.
Последний раз редактировалось WiseLord Ср фев 20, 2019 16:45:39, всего редактировалось 1 раз.
Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Да, неправильно. Я имею ввиду, что начало размера не от нуля. )

Добавлено after 1 minute 53 seconds:
Я примерно решил задачу выше через цикл и условие. В цикле переменная i автоматом бы заполнялась до нужной позиции, где стоит единица.
Но может есть проще варианты?
Станислав
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

СКАЗОЧНИК писал(а):Я имею ввиду, что начало размера не от нуля. )
У размера нет начала или конца, он просто есть сам по себе - одно число, по сути - количество элементов.

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
}
Контактная информация:
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Если вот так сделаю, примерно правильно будет?

Код: Выделить всё

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

Сообщение viiv »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3574472#p3574472"]Я просто пока мало еще понимаю, что в памяти займет больше места и что по быстродействию будет лучше.... Цикл с условием или просто условия.[/uquote]

Пусть меня закидают тапками. Да пофиг, не парься. Главное, чтобы 1) не было ошибок 2) код был максимально понятным

Код: Выделить всё

unsigned long int stroka = 0;
Почему не просто

Код: Выделить всё

int stroka = 0;
Ситуации, когда не установлен ни один из четырех битов регистра, не может быть? Если может, то цикл будет бесконечным.
Ситуации, когда установлены несколько из четырех бит регистра, не может быть? Если может, то чему должна быть равна переменная stroka в этом случае?

Когда я просматриваю код, приведенный WiseLord, у меня таких вопросов не возникает. :))
Последний раз редактировалось viiv Ср фев 20, 2019 18:17:09, всего редактировалось 1 раз.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

viiv писал(а):Ситуации, когда не установлен ни один из четырех битов регистра, не может быть?
Блин, точно. Может... :facepalm:
viiv писал(а):Ситуации, когда установлены несколько из четырех бит регистра, не может быть?
Теоретически может, но я пока не буду нажимать сразу несколько кнопок. :))) А иначе, возможное значение будет у первой единицы, которая вывалится справа.

У меня просто опрос матричной клавиатуры 4х4. Включаю первую строку (открытый коллектор) и считываю всю строку разом (на строках подтяжка к плюсу). То, что нажато, будет нулем, остальные единицами.
Включаю следующую строку. Опять считываю все разом, но уже номер строки равен двум (ну или единице, если я использую массив).
И т.д.
В итоге, после обработки получаем значение i,j элемента массива, который сохранен в памяти со значением кнопки клавиатуры.
Станислав
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18815
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я матрицу 4х4 опрашиваю проще, за 6 обращений к регистрам порта
сначала делаю биты порта строк входами с подтяжкой, а биты столбцов - выходами с нулем. считываю пины строк - если где-то была нажата кнопка, то в одной или более строк будет считан 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 имеем код, однозначно соответствующий нажатым кнопкам, можно делать с ним, что угодно
ALL_ROW это 0x0F, а ALL_COL это 0xF0 - маски всех битов строк и столбцов соответственно
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»