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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

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

когда в .data уже 0, а в .text ещё место есть и можно заколоть корову эффективности, чтобы вымолить пару байт на данные.
Вы правда считаете, что я должен гадать, что вы хотели сказать этой фразой? ;)
Так что, несите людям знания, а не молитвы.
Не выдумывайте. ;)
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

[uquote="da-nie",url="/forum/viewtopic.php?p=3322397#p3322397"]Вообще-то, жизненный цикл программы это самое "потом" предполагает всегда. Знаете, как часто могут перетряхиваться самые простые структуры данных в программе?[/uquote]
Раздел темы "Разные вопросы по МК", форум любительский, тема "Вопросы по С/С++" - вряд-ли это место для лекций о филологии, управлению проектами, общих принципах написания надёжного кода, автоматизации тестирования и т.п. [О, Коте Всемогущий, не сочти это за самовольное модерирование.] 99% аудитории хочет видеть конкретные ответы на интересующие их вопросы, да и только. И хорошие привычки им прививать нужно дозированно, не перенагружая их входные цепи информацией. Такой вот мой вам оффтопичный намёк. ;-)

Добавлено after 11 minutes 16 seconds:
[uquote="da-nie",url="/forum/viewtopic.php?p=3322522#p3322522"]
когда в .data уже 0, а в .text ещё место есть и можно заколоть корову эффективности, чтобы вымолить пару байт на данные.
Вы правда считаете, что я должен гадать, что вы хотели сказать этой фразой?[/uquote]
Двух слов .data и .text - sapienti sat, чтобы понять о чём речь. У вас пробел в знаниях.
[uquote="da-nie",url="/forum/viewtopic.php?p=3322522#p3322522"]Не выдумывайте. ;)[/uquote]
Т.е. на моей актуальной платформе RX63N + 32 MB etx. SDRAM ваша аксиома о всегдашности использования упаковки структур принесёт что-то кроме замусоривания кода - это выдумка? :))) И про word-aligned memory access вы тоже не слышали. [Канделябр, заходи...]
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

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

99% аудитории хочет видеть конкретные ответы на интересующие их вопросы, да и только.
Телепатией не обладаю. Уж извините. :music:

Добавлено after 14 minutes 29 seconds:
Двух слов .data и .text - sapienti sat, чтобы понять о чём речь. У вас пробел в знаниях.
Всегда удивляла подобная самоуверенность, переходящая в наглость. ;) Вы правда думаете, что будете писать что вздумается и при этом ожидать, что вас поймут? Да откуда бы?! Секция .data - содержит статические инициализированные данные. А про секцию .bss вы как-то забыли. И про кучу тоже не вспомнили. Забыли вы и про то, что переменные могут создаваться и на стеке (и рекурсию на МК никто не запрещал - есть и такие задачи). Да даже может потребоваться передать структуру по значению в функцию - и то на 1 КБ ОЗУ памяти может не хватить. Поэтому я написал, как оно и должно быть написано - мало памяти. А вы по сути написали, что если вы заняли всю память под .data, то... Но речь не идёт о том, чтобы занять всю память одной секцией. Речь идёт о том, что при работе программы памяти может не хватить (в том числе в процессе выполнения) (а так оно и бывает чаще всего). Поэтому написали вы совсем не то же самое, что и я.
Т.е. на моей актуальной платформе RX63N + 32 MB etx. SDRAM ваша аксиома о всегдашности использования упаковки структур принесёт что-то кроме замусоривания кода - это выдумка?
Вообще, вы странные люди. Я вам давно объяснил, о чём написал. Но вы продолжаете упорно сами придумывать случаи, где вам выравнивание структур мешает.
Последний раз редактировалось da-nie Вс мар 04, 2018 15:25:44, всего редактировалось 3 раза.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

[uquote="Пока_без_кота",url="/forum/viewtopic.php?p=3322257#p3322257"]Доброго времени суток. Прошу помощи. Почему код...[/uquote]
Думаю, ошибка в этой строчке:

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

		for (key_number = 0; key_number < 8; key_number++, keys_code >>=1)
вы бы уточнили при каких дефайнах собираете.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Пока_без_кота
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

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

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

Спасибо, возможно это так, но я пробовал компилировать и без дефайна для поика порядкового номера нажатой кнопки, и оно все равно не работало. Я тут уже и так и эдак крутил, и даже вроде "оптимизировал" до варианта без массива, сложение 4-х байт в один произвожу прямо в цикле. Получилось даже компактнее, и главное работает (тут переменные немного переименовал, для большей понятности для себя) :)))

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

	for (keys_byte = 0; keys_byte < 4; keys_byte++)						// Будем читать 4 байта состояний кнопок
	{
		spi_put(0);
		spi_wait();
		keys_code |= (TM1638_convert_byte(spi_get()))<<keys_byte;		// Каждый следующий байт накладывается на предыдущий со сдвигом влево на величину порядкового номер принятого байта (начиная с 0 !!!)
	}
П.С. Описываемая проблема относилась к варианту при использовании дефайна USE_USI_FOR_TM1638.

Теперь вся функция выглядит вот так:
Спойлер

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

uint8_t TM1638_get_keys(void)
{
	uint8_t keys_code = 0,keys_byte,key_number;
	
	TM1638_STB_LOW();	
	TM1638_write_byte(TM1638_CMD_READ_KEYS);
//	_delay_us(2);														// Минимально необходимая по даташиту задержка 2 мкс - можно убрать, все равно есть задержка после поднятия CLK в процедуре записи байта

#ifdef	USE_USI_FOR_TM1638
	half_spi_init_receive();											// Init SPI driver as RECEIVED master.

#else
	TM1638_DIO_INPUT();													// Установим ногу на вход !!!
#endif

#ifdef	USE_USI_FOR_TM1638
	for (keys_byte = 0; keys_byte < 4; keys_byte++)						// Будем читать 4 байта состояний кнопок
	{
		spi_put(0);
		spi_wait();
		keys_code |= (TM1638_convert_byte(spi_get()))<<keys_byte;		// Каждый следующий байт накладывается на предыдущий со сдвигом влево на величину порядкового номер принятого байта (начиная с 0 !!!)
	}

#else
	uint8_t key_code = 0;

	for (keys_byte = 0; keys_byte < 4; keys_byte++)						// Будем читать 4 байта состояний кнопок
	{
		for (key_number = 0; key_number < 8; key_number++)				// Перебор всех кнопок этого байта
		{
			TM1638_CLK_LOW();
			_delay_us(TM1638_DELAY_US);
			TM1638_CLK_HIGH();

			if (TM1638_DIO_READ())										// Если есть нажатая кнопка
			{
				key_code |= (1<<key_number);							// Устанавливаем бит нужной кнопки 
				keys_code |= key_code<<keys_byte;						// и накладываем этот байт на предыдущий со сдвигом влево на величину порядковго номера принятого байта (начиная с 0 !!!)
			}

			_delay_us(TM1638_DELAY_US);			
		}
	}
#endif

	TM1638_STB_HIGH();

#ifdef	USE_USI_FOR_TM1638
	half_spi_reinit_transmit();											// Init SPI driver as TRANSMIT master.

#else
	TM1638_DIO_OUTPUT();												// Вернем ногу на выход !!!
#endif

	_delay_us(TM1638_DELAY_US);

	TM1638_send_comm(TM1638_CMD_SET_DATA | TM1638_SET_DATA_F_ADDR);		// Установка режима работы - Запись в индикатор, Фиксированный адрес

	_delay_us(TM1638_DELAY_US);

#ifdef RETURN_KEY_NUMBER
	if (keys_code)														// Если нажата кнопка - вычисляем ее номер (Внимание, будет передана только 1, самая младшая кнопка !!!)
	{
		for (key_number = 0; key_number < 8; key_number++, keys_code >>=1)
		{
			if (keys_code & 0x01)										// Если 0 бит установлен, найдена нажатая кнопка (Внимание, первой будет найдена кнопка из младшего бита)
			{
				return key_number+1;									// Возвращаем порядковый номер первой найденой нажатой кнопки
			}				
		}
	}
#endif

	return keys_code;													// Возвращаем состояние всех кнопок
}
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

нет, это моя ошибка - строка правильная.

Причина пропадания вызова может быть шуткой оптимизатора. Мне сначала показалось, что вы там не сдвигаете keys_code и поэтому оптимизатор выбросил вычисление, которое в конце-концов не понадобится. Поэтому внимательно проверьте, что для вычисления вашего return keys_code это действительно нужно. кстаи, причина может быть внутри функции TM1638_convert_byte(

Мне как-то IAR тоже так был "соптимизировавши". Благодаря ему я и нашел ошибку. Причем, при компиляции с пониженным уровнем оптимизации всё работало
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Shrike1987
Родился
Сообщения: 7
Зарегистрирован: Пт мар 02, 2018 16:31:19

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

Сообщение Shrike1987 »

Уважаемый Siarzhuk!
Благодарю за код!

При попытки скомпилировать его получаю две ошибки в строке:

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

for (p0 = Font2[C].Line, p = Font2[C].Line + 1; 0 == p->eol; p0 = p, p++) 
Сами ошибки: ..\Src\Font.c(51): error: #513: a value of type "const t_point *" cannot be assigned to an entity of type "t_point *"

Чего ему не нравится? Мне вот реализация ооочень даже нравится )))
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Так ведь прямым текстом написано, что. Разные типы указателей.
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

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

a value of type "const t_point *" cannot be assigned to an entity of type "t_point *"
Ему не нравится, что у вас был указатель на константу, а вы его перенесли в обычный указатель.

У вас const t_point *Line;

А

t_point* p0 = NULL;
t_point* p = NULL;

и дальше вот так:

for (p0 = Font[C].Line, p = Font[C].Line + 1; 0 == p->eol; p0 = p, p++) {

Вам надо модификатор const применить и к p и к p0.

const t_point* p0 = NULL;
const t_point* p = NULL;

Либо снять константность при приравнивании p0 = (t_point *) Font[C].Line и в других местах тоже.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

[uquote="Shrike1987",url="/forum/viewtopic.php?p=3323056#p3323056"]..\Src\Font.c(51): error: #513: a value of type "const t_point *" cannot be assigned to an entity of type "t_point *"[/uquote]
1. Идём на https://translate.google.com/#en/ru;
2. Переводим текст ошибки с аспергерского на русский: error: # 513: значение типа "const t_point *" не может быть присвоено сущности типа "t_point *";
3. Осознаем, что тому кто "слева" неприемлемо значение предлагаемое тем кто "справа";
4. Есть два варианта - либо меняем тип "левого" на const t_point*, либо то, что отдают справа насильно считаем типом t_point* (т.е фактически read-only данные считаем возможным модифицировать);

Впрочем это вам уже объяснили и без меня - остается лишь добавить что const - это указание компилятору считать данные неизменяемыми и он, обладая этим знанием, может оптимизировать работу с ними, сэкономив, к примеру оперативную память, обращаясь напрямую к данным из флеш. Но за такими деталями - это вам к специалистам по используемой вами платформе.

Т.е. если вы не планируете менять данные "шрифта" во время выполнения программы - оставляйте их const, если-же нужно менять - придётся определить некий максимум для размера данных символа - и оперировать в его пределах. Ну и поудалять модификаторы const. Примерно так:

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

#define MAX_CHAR_DATA 32

// [омномномном]

                   // при таком способе инициализации данные массива добиваются нулями до размера 32 (MAX_CHAR_DATA)
t_point ch56[MAX_CHAR_DATA] = { 0x10, 0x30, 0x41, 0x42, 0x33, 0x44, 0x45, 0x36, 0x16, 0x05, 0x04, 0x13, 0x02, 0x01, 0x10, BRK, 0x13, 0x33, EOL } ;
                       

// [омномномном]

const struct TFont {
   t_point *Line;
} Font[255]  = {
   ch00, ch01, ch02,   и.т.д, и т.д.....           ,  ch56, ch57,
};

Резюмирую обеими руками за вариант:
[uquote="da-nie",url="/forum/viewtopic.php?p=3323104#p3323104"]const t_point* p0 = NULL;
const t_point* p = NULL;[/uquote]
А вот, в силу вышеобъяснённого, снимать константность
[uquote="da-nie",url="/forum/viewtopic.php?p=3323104#p3323104"]при приравнивании p0 = (t_point *) Font[C].Line и в других местах тоже[/uquote]
после столь любовного расставления этого модификатора на всех данных шрифта я бы не стал. ;-)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Shrike1987
Родился
Сообщения: 7
Зарегистрирован: Пт мар 02, 2018 16:31:19

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

Сообщение Shrike1987 »

Всем спасибо за участие! Теперь все компилируется и рисуется =)
Заодно дописал функцию сглаженной линии... Вот только шрифт имеет смысл рисовать сглаженным, если он скейлится...
Для тех, кому интересно, прикладываю пример на фото.

Добавлено after 7 minutes 21 second:
Забыл добавить: символы еще не все добавил. В верхней части слева - сглаженный, справа обычный. В нижней первая строка скейленый шрифт без сглаживания, во второй строке - те же скейленные символы со сглаживанием.
Вложения
TestAntialasingFont2.jpg
TestAntialasingFont
(194.06 КБ) 393 скачивания
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Как сделать установку несколько IP адресов, по феншую? т.е как инициализировать массив из 4 байт и больше.
уже кучу вариантов, придумал и все не нравятся, хотел объявить структуру с дефектными настройками и от туда копировать до N поля, но тут не нравиться что может глюк с выравниванием структуры.
Сделал в лоб, но тут не нравиться что надо массив объявлять.

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

	uint8_t IP[4]={192,168,0,	6};
	SetIP(RAM_SettingAllVar.WiznetSetting.ip,IP);

void SetIP(uint8_t* src,uint8_t* ip){
	src[0]=ip[0];
	src[1]=ip[1];
	src[2]=ip[2];
	src[3]=ip[3];
}
хотел сделать так, а в нутри функции, сдвигами байты из 0xC0A80006 расставлять, но как-то ip 0xC0A80006 не особо читаем :?

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

SetIPv2(RAM_SettingAllVar.WiznetSetting.ip,0xC0A80006);
Если ещё какие нибудь предложения ?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

typedef union{
   uint32_t ip_long;
   struct{
      uint8_t ip_b0,ip_b1,ip_b2,ip_b3;
   }
} ip_t;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
viiv
Грызет канифоль
Сообщения: 287
Зарегистрирован: Чт ноя 06, 2014 13:09:06

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

Сообщение viiv »

[uquote="pokk",url="/forum/viewtopic.php?p=3324853#p3324853"]но как-то ip 0xC0A80006 не особо читаем[/uquote]

Для повышения читаемости, можно так

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

#define IPV4_ADDR(a,b,c,d) (((uint32_t)(a) << 24) | ((uint32_t)(b) << 16) | \
                            ((uint32_t)(c) <<  8) | ((uint32_t)(d) <<  0))
Компилятор (нормальный) без проблем вычислит констатное выражение

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

IPV4_ADDR (192, 168, 0, 6)
на этапе компиляции.
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Сделал себе структуру модулей так есть глобальный #include "Aplication.h" который подключается ко ВСЕМ модулям
в нем решил включать #include которые могут вызываться в многих модулях к примеру светодиоды(для отладки) и тд.
Все хорошо работало, но засунув в очередной раз модуль в Aplication.h получил кучу ошибок("dataEntryType" is undefined ) совершено в другом модуле, причем dataEntryType находится в другом модуле и он подключен.
т.е это выглядит так:
Есть два модуля в модуле snmp.h объявлена структура dataEntryType
и получаю ошибки на то что в модуле snmp_custom неизвестна dataEntryType, хоть вот выше строчкой структура должна подключиться

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

#include "Aplication.h"
#include "Ethernet\SNMP\snmp.h"
extern dataEntryType snmpData[];
PS: сейчас с модулями snmp.h snmp_custom.h все переделал убрал внутри все ихнии инклуды, и перекинул их все в "Aplication.h все равно все ещё ругается, пока каша в голове отчего все это может быть.
сдается мне что модуль как -то рекурсивно вызывается, в одном он подключился а в другом уже нет.

во всех модулях стоит, естественно с разными define

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

#ifndef SNMP_H_
#define SNMP_H_
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

[uquote="pokk",url="/forum/viewtopic.php?p=3330414#p3330414"]Есть два модуля в модуле snmp.h объявлена структура dataEntryType и получаю ошибки на то что в модуле snmp_custom неизвестна dataEntryType, хоть вот выше строчкой структура должна подключиться[/uquote]
Чтобы основательно разобраться с темой - нужно смотреть что там препроцессор наворотил - поищите кaк для вашего компилятора просмотреть выхлоп препроцессора - т.е. файл, получившийся после разворачивания всех #include директив до передачи его компилятору. В ембедерных ИДЕ это как правило опция в проекте - либо "do not remove intermediate files" либо "preprocess only" - файл нужно искать в папке с объектниками иногда с расширением .pre иногда прямо вместо объектника, иногда .i В майкрософтосвских средах - ключи командной строки /E /P - появится файл с расширением .i

Если по быстрому - иногда спасет т.н. forward declaration - но только в том случае, если компилятору не нужны подробности:

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

#ifndef __H__
#define __H__

struct dataEntryType;  // forward declaration
int cleanThemAll(struct dataEntryType*); // указатель на тип - подробности внутренностей объекта не нужны

#endif /* __H__ */
И в таком случае файл с [полным] объявлением структуры нужно включать только в том .с файле где определяются переменные этого типа.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Благодарю обязательно поищу файл, а так вроде разобрался компилятор IAR выдавал ошибку при компиляции snmp.с который вызывал snmp.h и в самом начале еще до объявлении структуры вызывался файл
"Aplication.h" который открывал snmp_custom.h и видать из за того что вызов был из snmp.h файла, второй раз он уже его не мог открыть по этому компилятор успешно пропускал его в snmp_custom.h и ругался.
viiv
Грызет канифоль
Сообщения: 287
Зарегистрирован: Чт ноя 06, 2014 13:09:06

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

Сообщение viiv »

[uquote="pokk",url="/forum/viewtopic.php?p=3330414#p3330414"]пока каша в голове отчего все это может быть.[/uquote]

pokk, логику диррективы "#include" понимаете? Она очень простая: #include "file" заменяется содержимым указанного файла. Все. Какая каша?
Если ругается на строку, что тип не определен, значит этот тип не определен. Все, другого быть не может.
А) файл с определением типа инклудается позже (компилятор вперед ничего не просматривает)
Б) вообще банальная ошибка, типа определили dataEntryType, а используете dateEntryType
В) тип действительно не определен, например, не заинклуден нужный файл.

PS. По вашему описанию вообще проблематично чтото сказать. Вложите исходник и все инклуды, которые инкудятся, скажите в какой строке и как ругается компилятор, думаю, Вам через пять минут скажут где "косяк".
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

Здравствуйте!!! вопрос в коде:
Спойлер

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


// вот две функции 
void output_level_1_GWS(void);
void output_level_1_HWS(void);

// объявляю тип структуры с полями на указатель функции
typedef struct  
{
void (*Ptr1GWS)(void);       // пункт меню на первом уровне
void (*Ptr1HWS)(void);       // пункт меню на первом уровне
}LEVEL1;                           // тип структуры 1 уровня

//инициализирую ее функциями выше
LEVEL1 MENU_LEVEL1={output_level_1_GWS,output_level_1_HWS};

// создаю указатель на целое беззнаковое
uint8_t  *PtrPunkt;

в него планирую поместить адрес 2 поля структуры LEVEL1 MENU_LEVEL1.Такой вот записью PtrPunkt=&(LEVEL1 MENU_LEVEL1->Ptr1HWS);
1)нужен ли здесь указатель на указатель? :dont_know: 

2)затем используя PtrPunkt нужно вызвать функцию output_level_1_HWS();Правильно ли будет написав так *PtrPunkt;

3)объявления переменных, функции и т.п делаю в хедере, а инициализацию нужно делать в исходнике модуля как и реализацию функции, или в хедере?




Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

Ответы и советы:
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3336557#p3336557"]

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


// вот две функции 
void output_level_1_GWS(void);
void output_level_1_HWS(void);

// sz: делаем каноничненько - алиасим тип указателя на функцию
typedef void (*TvvPtr)(void);

// объявляю тип структуры с полями на указатель функции
typedef struct  {
   TvvPtr Ptr1GWS;       // пункт меню на первом уровне
   TvvPtr Ptr1HWS;       // пункт меню на первом уровне
} LEVEL1;                           // тип структуры 1 уровня

// создаю указатель на целое беззнаковое
uint8_t  *PtrPunkt;  // sz:  когда устанете бороться с компилятором - напишите так: TvvPtr PtrPunkt; 

PtrPunkt=&(LEVEL1 MENU_LEVEL1->Ptr1HWS); // sz: не выйдет в мышь впихнуть кота - любой заметит: - "Фактура не та!" А приведение типов - Зло™. Синтакс - ужасен - достаточно PtrPunkt=MENU_LEVEL1->Ptr1HWS;

// sz: да и за полностью прописные имена типов/переменных и прочих не #define-ов - тру-Сишники из вас кактус сделают. :-) Ибо заповедано: -"Прописными - только #define-ы!"

2)затем используя PtrPunkt нужно вызвать функцию output_level_1_HWS();Правильно ли будет написав так *PtrPunkt;
// sz: а если-бы функция имела аргументы? И таблицу приоритетов посмотрите - кто кого перетянет. ;-)

3)объявления переменных, функции и т.п делаю в хедере, а инициализацию нужно делать в исходнике модуля как и реализацию функции, или в хедере?
// sz: "хидер" - это интерфейс модуля - там объявления, А определения - только в самом модуле. Будь определение в хидере - в каждом включающем этот хидер модуле будет копия переменной - линкер может и заколдобиться.

[/uquote]
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Ответить

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