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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Добрый день подскажите пожалуйста, что означает данные предупреждения
Warning pointer targets in passing argument 1 of 'strlen_P' differ in signedness [-Wpointer-sign]
Warning passing argument 6 of 'show_string' from incompatible pointer type [enabled by default]
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

baghear писал(а):Warning pointer targets in passing argument 1 of 'strlen_P' differ in signedness [-Wpointer-sign]
char может быть знаковым и беззнаковым - смотрите что от вас ожидают, и что вы на самом деле передаёте в strlen. И какой тип char у используемого компилятора задан по умолчанию.
baghear писал(а):Warning passing argument 6 of 'show_string' from incompatible pointer type [enabled by default]
Опять-же ожидаемый тип указателя в шестом параметре функции show_string не соответствует тому, что в него передаёте. Код покажете - можно будет сказать точнее.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Есть такая функция
void show_string (unsigned char size,unsigned int start_x,unsigned int start_y,unsigned int color,unsigned int phone,const unsigned char *string)
последним параметром надо передать указатель
const unsigned char string_1 [] PROGMEM = "hello";
передаю вот так
show_string(3,4,2,0XAAAA,0XEEEE, &string_1);
а ошибки не выдает когда передаю так
show_string(3,4,2,0XAAAA,0XEEEE, string_1);
Прочитал что при передаче массива по сути передаю указатель на первый элемент.
Спасибо.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

baghear писал(а):Есть такая функция
void show_string (unsigned char size,unsigned int start_x,unsigned int start_y,unsigned int color,unsigned int phone,const unsigned char *string)
последним параметром надо передать указатель
const unsigned char string_1 [] PROGMEM = "hello";
передаю вот так
show_string(3,4,2,0XAAAA,0XEEEE, &string_1);
Такой подход с легкой правкой имеет право на жизнь, можно использовать если требуется передавать строке начиная не с первого символа:

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

show_string(3,4,2,0XAAAA,0XEEEE, &string_1[3]);
Можно возразить, что написав

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

show_string(3,4,2,0XAAAA,0XEEEE, string_1 + 3);
мы достигнем того-же результата и покажемся себе в зеркале более продвинутыми, но по моему мнению, некоторая неуклюжесть первого варианта заставит потомков зацепится взглядом и таки заметить что там "не с нуля". Хотя комментарий, конечно, надёжнее...
baghear писал(а): а ошибки не выдает когда передаю так
show_string(3,4,2,0XAAAA,0XEEEE, string_1);
Прочитал что при передаче массива по сути передаю указатель на первый элемент.
да,а прибавление к указателю целого числа N - суть смещение в массиве на N-ое количество элементов.

А если написать для эксперимента так:

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

show_string(3,4,2,0XAAAA,0XEEEE, "hello");
то с некоторой долей вероятности можно получить от компилятора предупреждение о несоответствии типа указателя - поскольку строковый литерал дефолтного типа signed char* а в прототипе функции указан что нужен unsigned char*. Шибко переразвитые компиляторы зело полюбляют нас на этом подлавливать. ;-)

Удачи!
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Спасибо большое, стало понятнее!!!!
Почему строковый литерал по дефолту signed char?
разве есть смысл учитывать знак при кодировке?

Еще возник вопрос, есть хэдер, который содержит один массив
static unsigned char const Font8x16[95][16] = {.....}
для чего он объявлен как static?
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

baghear писал(а):Спасибо большое, стало понятнее!!!!
Почему строковый литерал по дефолту signed char?
разве есть смысл учитывать знак при кодировке?
Точно не скажу, но навскидку это настройка компилятора - будет дефолтный char со знаком или без. А вот зачем - этим я как-то не задумывался. Что-то в памяти рядом с триграфами и прочей жуткой легаси болтается - но утверждать не возьмусь.
baghear писал(а):Еще возник вопрос, есть хэдер, который содержит один массив
static unsigned char const Font8x16[95][16] = {.....}
для чего он объявлен как static?
При включении хидеров в сишник - препроцессор формирует один большой файл который и скармливается компилятору. Т.е. выделив массив прямо в хидере - автор выделил его во всех сишниках в которые он будет включен. Компилятор эти массивы так и вставит в результирующие объектные файлы - ведь он работает с одним сишником за проход. После компилятора, как д'Артаньян на белом коне подъезжает линкер и начинает вязать объектники в единое целое. И тут он находит в различных файлах объекты с одинаковыми именами Font8x16 - и резонно начинает нудить про дубликаты символов и отказываться от своей миссии - ему и на самом деле непонятно какие ссылки идут к "тому" экземпляру, а какие к "этому". Но автор, умная голова, объявляет массив в хидере как static и теперь линкер вяжет ссылки из "этого" файла к его собственной копии массива, а из "того" файла - к "той" копии. Вуаля! Автор удовлетворён, счастливы все кроме процессора, ресурсы которого потрачены на несколько копий одних и тех-же данных. Вот где-то так, по моим ощущениям всё и происходило.

Чтобы избежать дубликации - нужно либо не включать хидер в несколько c-файлов, а если нужны ссылки между модулями - в хидере объявить его как extern вместо static, а тельце с инициализацией поместить в одном из c-шников.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Опытный кот
Аватара пользователя
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Сообщение baghear »

Спасибо, большое!!!!
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 183
Зарегистрирован: Ср янв 25, 2012 07:26:40

Сообщение acckyiboxxx »

непонятно почему единоразово самопроизвольно срабатывает прерывание int7 (судя по симуляции в протеусе)

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

ISR(INT7_vect){
	disable_int7();
	PORTB = ~PORTB; // для того что-бы глянуть что прерывание отработало
}

void init_encoders(void){
	//disable_int7(); // РУБИМ ПРЕРЫВАНИЕ ПО INT7
	cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
	DDRE &=  (1<<DDE7); 
	PORTE &=  (1<<PE7); 
	EICRB |= (1<<ISC71) | (1<<ISC70) | (1<<ISC61) | (1<<ISC60); // INT6 И INT7 СРАБОТАЮТ ПО 2-М ВЫБОРКАМ ВЫСОКОГО УРОВНЯ
	sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
}

void enable_int7(void){
	cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
	EIMSK = (1<<INT7); // РАЗРЕШАЕМ ПРЕРЫВАНИЕ НА INT7
	sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
}

void disable_int7(void){
	cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
	EIMSK &= (1<<INT7); // ЗАПРЕЩАЕМ ПРЕРЫВАНИЕ НА INT7
	sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
	PORTB = 0x00;
}

int main(){
	init_encoders(); // НАСТРАИВАЕМ РАБОТУ ЭНКОДЕРОВ
	disable_int7();
	enable_int7();
	while (1)
	{
	};
	return 0;
}
так вот PE7 подтянут резюком к земле а энкодер может подавать на него лог единицу , после чего прерывания должны отключиться и PORTB должен выдать лог единицу на все свои 8 лап , только вот при симуляции в протеусе прерывание уже прилетает еще до того как я начинаю "крутить энкодер"

энкодер запилен по этой статье http://diymicro.ru/sozdanie-ierarxiches ... odera.html вирт. осциллографом проверял от него самопроизвольно лог единица прилетать не может

да и настройки тоже вроде как правильно сделал http://www.gaw.ru/html.cgi/txt/doc/micr ... h128/8.htm

вопрос в том почему прерывание все-же срабатывает первый раз ?

ps: если убираю вызов disable_int7(); из обработчика прерываний то при запуске оно срабатывает 1 раз а затем когда я "работаю энкодером" PORTB переключает состояние своих выводов что говорит о том что прерывание отрабатывает
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Сообщение lix »

acckyiboxxx, вы уверены что правильно биты в регистрах сбрасываете?
Обычно нужно инвертирование

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

 EIMSK &= ~(1<<INT7);
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Разъясните пожалуйста про перечислители.
Допустим, перечислитель _flags:

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

enum _flags {
_READ =01, /* файл открыт на чтение */
_WRITE = 02, /* файл открыт на запись */
_UNBUF = 04, /* файл не буферизуется */
_EOF = 010, /* в данном файле встретился EOF */
_ERR = 020 /* в данном файле встретилась ошибка */
};
Какой смысл в названии перечислителя _flags, если оно напрямую не используется?
Обращение в коде происходит к самим константам(_READ,_WRITE и т.д.).
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

uk8amk писал(а):

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

enum _flags {
_READ =01, /* файл открыт на чтение */
[...]
};
Какой смысл в названии перечислителя _flags, если оно напрямую не используется?
Обращение в коде происходит к самим константам(_READ,_WRITE и т.д.).
enum _flags это определение типа и если нужно определить функцию принимающую, к примеру, параметр этого типа - вот тут имя и пригодится. Но по характерным признакам данного конкретного случая мы имеем дело с битами в маске - и попытка передать комбинацию битов выдаст предупреждение компиляции. Впрочем использование безымянных перечислений также не возбраняется современными стандартами и было-бы тут уместно.

Программы имеют свой жизненный цикл развития и за время разработки этот еnum _flag мог быть изначально запланирован к использованию в качестве типа, а затем по мере развития выродился в набор битов в маске. Ну а имя или забыто, либо, скорее всего, вставлено изначально, чтобы избежать проблем с портированием этого кода на компиляторы не понимающие безымянный enum.

PS: Кстати, использование подчёркивания в начале имён - прерогатива стандартной библиотеки и в своих программах такой нотации рекомендуется избегать.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Пытался ранее докопаться до истины, но везде в интернетах и учебниках только общие слова.
Например объявление типа, относящегося к контроллеру прерываний:

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

typedef enum IRQn
{
  NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                             */
  MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt              */
  BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                      */
бла-бла-бла
} IRQn_Type;
И далее функция, употребляющая этот параметр:

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

__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}
При создании объекта и передачи параметра этого типа в функцию по идее должно резервироваться какое-то кол-во памяти для хранения в ОЗУ или стеке.
Но что выделяется под enum IRQn_Type IRQn ? Ведь это всего лишь набор возможных числовых констант, которые можно было тупо заменить #define-ами. Вот это не понятно.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

все понятно, если внимательно изучить возможности компилятора и стандарт языка.
как правило, под любое число выделяется int, и одновременно, практически каждый компилятор имеет опциональную возможность выделять под enum минимально возможный элемент, т.е. байт (если, конечно, перечисление содержит не более 256 элементов или не содержит элементов с явно заданными большими значениями).

для чего это нужно? снова понятно. язык Си слабо контролирует типы, стандарт С99 немного ужесточает контроль типов, но более-менее нормальный контроль есть только в С++. это означает, что когда в качестве параметра функции вы задаете тип-перечисление, компилятор может на этапе компиляции сообщить (обычно warning, но в С++ может быть и error), когда вы в функцию передаете число, не попадающее в перечисление - это немного помогает избежать грубых ошибок.

например, в WinAVR попробуйте скомпилировать оператор switch с аргументом перечисляемого типа - если вариантов case будет меньше, чем определено в перечислении, компилятор вам тут же сообщит, что не все варианты switch обработаны. для обычных типов чисел так он ругается только на отсутствие default.

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

P.S. я не в курсе, есть ли в каком-либо диалекте Си или С++ возможность определять "края" перечислений, как в Pascal... но это реально полезная фича!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Спасибо за разъяснения, потихоньку начинает проясняться.
Грызет канифоль
Сообщения: 269
Зарегистрирован: Чт мар 11, 2010 17:45:37
Откуда: г.фрязино

Сообщение mastech »

ковыряю код принимающий и отправляющий данные по UART(AVR) и выводящий что отправлено/принято на дисплей, задачя убрать все из кода, что отвечает за отправку обратно в компьютер, начинаю с самого явного убираю из цикла ифы с кнопками и перестает работать вывод на лцд, вступительная заставка работает, стоит вернуть хоть один иф с кнопкой, начинает работать дисплей.
Спойлер

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

//*** Пример работы с USART интерфейсом микроконтроллеров AVR ***

#include <avr/io.h>
#include <avr/interrupt.h>

#define BAUDRATE 9600 // Скорость обмена данными
#define F_CPU 8000000UL // Рабочая частота контроллера

unsigned char NUM = 0;  
unsigned char count = 0;
unsigned char byte_receive = 0;
unsigned char i = 1;

// Функция задержки в мкс
void _delay_us(unsigned char time_us)
{ register unsigned char i;

for(i = 0; i < time_us; i++)
{
asm volatile(" PUSH  R0 ");
asm volatile(" POP   R0 ");
}
}

// Функция задержки в мс
void _delay_ms(unsigned int time_ms)
{ register unsigned int i;

for(i = 0; i < time_ms; i++)
{ 
_delay_us(250);
_delay_us(250);
_delay_us(250);
_delay_us(250);
}
}

#define RS PD2 
#define EN PD3

// Функция передачи команды
void lcd_com(unsigned char p)
{
PORTD &= ~(1 << RS); // RS = 0 (запись команд)
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
}

// Функция передачи данных
void lcd_data(unsigned char p)
{
PORTD |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
}

// Функция инициализации LCD
void lcd_init(void)
{
_delay_ms(50); // Ожидание готовности ЖК-модуля

// Конфигурирование четырехразрядного режима
PORTD |= (1 << PD5);
PORTD &= ~(1 << PD4);

// Активизация четырехразрядного режима
PORTD |= (1 << EN);
PORTD &= ~(1 << EN);
_delay_ms(5); 

lcd_com(0x28); // шина 4 бит, LCD - 2 строки
lcd_com(0x08); // полное выключение дисплея
lcd_com(0x01); // очистка дисплея
_delay_us(100);
lcd_com(0x06); // сдвиг курсора вправо
lcd_com(0x0C); // включение дисплея, курсор не видим
}

// Функция вывода строки на LCD
void lcd_string(unsigned char command, char *string)
{
lcd_com(0x0C);
lcd_com(command);
while(*string != '\0')
{
lcd_data(*string);
string++;
}
}

// Функция передачи данных по USART
void uart_send(char data)
{
while(!( UCSRA & (1 << UDRE)));	// Ожидаем когда очистится буфер передачи
UDR = data; // Помещаем данные в буфер, начинаем передачу
}

// Функция передачи строки по USART
void str_uart_send(char *string)
{
while(*string != '\0')
{
uart_send(*string);
string++;
}
}

// Функция приема данных по USART
int uart_receive(void)
{
while(!(UCSRA & (1 << RXC))); // Ожидаем, когда данные будут получены
return UDR; // Читаем данные из буфера и возвращаем их при выходе из подпрограммы
}

// Функция инициализации USART
void uart_init(void)
{
// Параметры соединения: 8 бит данные, 1 стоповый бит, нет контроля четности
// USART Приемник: Включен
// USART Передатчик: Включен
// USART Режим: Асинхронный
// USART Скорость обмена: 9600

UBRRL = (F_CPU/BAUDRATE/16-1); // Вычисляем скорость обмена данными  
UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;

UCSRB |= (1 << RXCIE)| // Разрешаем прерывание по завершению приема данных
          (1 << RXEN)|(1 << TXEN); // Включаем приемник и передатчик
                                                
UCSRC |= (1 << URSEL)| // Для доступа к регистру UCSRC выставляем бит URSEL
         (1 << UCSZ1)|(1 << UCSZ0); // Размер посылки в кадре 8 бит
}

// Прерывание по окончанию приема данных по USART
ISR(USART_RXC_vect)
{
NUM = UDR; // Принимаем символ по USART
byte_receive = 1;
uart_send(NUM); // Посылаем символ по USART
	
if(NUM == 'a') // Если принят символ "a", включаем светодиод
PORTB |= (1 << PB0);
if(NUM == 'b') // Если принят символ "b", выключаем светодиод
PORTB &= ~(1 << PB0);
}

// Главная функция
int main(void)
{
DDRB |= (1 << PB0); // Светодиод
PORTB = 0x00;        			

DDRC  = 0x00;	
PORTC = 0xFF;
	
DDRD  = 0b11111110;
PORTD = 0x00;
	
lcd_init(); // Инициализация LCD
uart_init(); // Инициализация USART
	
sei(); // Глобально разрешаем прерывания

str_uart_send("Initialization system\r\n"); // Передаем строку по USART
lcd_string(0x80, " AVR USART TEST "); // Выводим строку на LCD
_delay_ms(2500);
lcd_com(0x01); // Очищаем LCD
	
while(1)
{

if((PINC & (1 << PC0)) == 0) // Если нажата кнопка 1
{
while((PINC & (1 << PC0)) == 0){} // Ждем отпускания кнопки 1
str_uart_send("Button 1 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 1 TEST"); // Выводим строку на LCD
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}

if((PINC & (1 << PC1)) == 0) // Если нажата кнопка 2
{
while((PINC & (1 << PC1)) == 0){} // Ждем отпускания кнопки 2
str_uart_send("Button 2 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 2 TEST"); // Выводим строку на LCD
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}

if((PINC & (1 << PC2)) == 0) // Если нажата кнопка 3
{
while((PINC & (1 << PC2)) == 0){} // Ждем отпускания кнопки 3
str_uart_send("Button 3 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 3 TEST"); // Выводим строку на LCD 
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}		

if(byte_receive)
{
byte_receive = 0;
count++;
lcd_data(NUM); // Выводим символ на LCD
if(count > 16) // Если строка заполнена
{
count = 0;
lcd_com(0x01); // Очищаем LCD
}
}
}
}
доб 22:14: странно, удаляя все "кнопки" из цикла, if(byte_receive) перестает работать, добавив задержку в 10мс. все работает, почему.

еще вопрос. как иначе записать if(byte_receive) если он один в цикле получается if ненужен?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

а у меня встречный вопрос: почему с задержками изобрели велосипед, если существует отличный модуль для формирования задержек util/delay.h?

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Не знаю как правильно сформулировать запрос для гугла, поэтому попробую спросить здесь.
Есть такая штука как автозавершение кода. Допустим мы пишем имя структуры
MyStruct.
И здесь в редакторе вываливается доступный список её элементов, из них можно выбрать нужный.
Есть к примеру машина состояний, принимающая одно из N возможных константных значений(UP, DOWN, START, STOP и т.д.). Тогда мы пишем
state_machine = STATE_START;
Было бы удобнее собрать эти константные значения в какой-то объект SM_VAL и написать так:
state_machine = SM_VAL.[вываливается список, из которого выбираем]

Использую Си(не ++), есть ли такое?
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

uk8amk писал(а): Было бы удобнее собрать эти константные значения в какой-то объект
Перечисления (enum).
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

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

Сообщение WiseLord »

Эти выпадающие списки уже от используемого IDE.

Я, например, QtCreator использую - там такое есть.
Контактная информация:
Ответить

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