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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
neiver
Родился
Сообщения: 4
Зарегистрирован: Пн апр 25, 2011 15:39:38

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

Сообщение neiver »

ellioh писал(а):Оказывается, вот ТАК нельзя:

Можно:

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

struct a {
   template <typename t> static void f () {}; //Шаблонная статическая функция
};
template <typename t> //Шаблон, который я позже хочу параметризовать структурой a.
struct b {
   static void f () {
      t:: template f<int> (); // ошибки теперь нет - ключевое слово template
   
   }
};
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

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

Сообщение ellioh »

neiver писал(а):Можно:

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

struct a {
   template <typename t> static void f () {}; //Шаблонная статическая функция
};
template <typename t> //Шаблон, который я позже хочу параметризовать структурой a.
struct b {
   static void f () {
      t:: template f<int> (); // ошибки теперь нет - ключевое слово template
   
   }
};


Гениально! Пошёл проверять. Если это так, то, коллега, вы спасли мне день, спасибо! :-)
UPD: Ура, заработало! А то я вроде и погуглил, и даже нашёл пару упоминаний, что так действительно нельзя. А стандарта под рукой нет, да и пока там найдёшь нужное, с ума свернёшься...
Клоподавер упрыгхт
Аватара пользователя
boobonick
Встал на лапы
Сообщения: 123
Зарегистрирован: Сб ноя 18, 2006 17:14:15

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

Сообщение boobonick »

Подскажите, пожалуйста, а есть ли такая конструкция, которая позволяет реализовать вот такое:

struct {

char sub_menu[10];

unsigned char count_menu;

char function(char);

} punkt_menu[2];

т.е. , чтобы можно было punkt_menu[1].function(222);
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

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

Сообщение ellioh »

boobonick писал(а):Подскажите, пожалуйста, а есть ли такая конструкция, которая позволяет реализовать вот такое

Смотря в каком языке. :-) Добро пожаловать в C++. В C, конечно, нет. Максимум, что можно в C -- сделать член структуры, являющийся указателем на функцию, но это потребует места под указатель в каждой структуре.
Клоподавер упрыгхт
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

В применении, которое нужно вопрошающему (как я это понял), по объёму в С++ будет хуже.
Тут есть N структур-описателей, у каждой уникальная функция, указатель на которую в теле структуры. Итого расходов на позицию -- один указатель.

В С++ с виртуальными функциями в структуре будет указатель на VMT -- таблицу указателей на виртуальные функции. Итого расходов на позицию -- указатель на VMT, указатель на функцию в самой VMT плюс какие-то доп. расходы на «служебную» информацию в VMT (у avr-gcc, если правильно помню, добавление в класс первой виртуальнйо функции отжирает 6 байт ОЗУ).
А, например, avr-gcc ещё и в ОЗУ хранит саму VMT, хотя мог бы и во флеше, по скорости проигрыш совсем незначтельный, а ОЗУ зря не занималось бы.

Это если будет несколько экземпляров структуры одного типа (т.е. с одинаковой функцией-обработчиком, только данные у каждой свои), и/или ещё и функция не одна, то тогда VMT выручает по объёму сильно.
Собственно, и в С такой «закат солнца вручную» можно организовать.
Собственно, С++ «без шаблонов» и появился как автоматизатор этих танцев с указателями на функции, которые в С давно и применялись в том числе и для «объектного» подхода.
За что ему и спасибо.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

boobonick писал(а):Подскажите, пожалуйста, а есть ли такая конструкция, которая позволяет реализовать вот такое:

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

char menu_0_func(char ch) { ... }
char menu_1_func(char ch) { ... }

struct {
    char sub_menu[10];
    unsigned char count_menu;
    char (*function)(char);
} punkt_menu[2] = {
    { "...", 0, menu_0_func},
    { "...", 1, menu_1_func}
};
  ...
  punkt_menu[1].function(222);

И не верьте тому, кто скажет, что нужно писать
{ "...", 0, &menu_0_func}
и
(*punkt_menu[1].function)(222);
По стандарту С это совершенно не обязательно. Но если Вам будет приятно -- пишите.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

avreal писал(а):Но если Вам будет приятно -- пишите.
почему-то вспомнилось что-то из репертуара какого-то юмориста: "там налево знак "кирпич" висит - обрыв, но вам туда можно" :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

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

Сообщение ellioh »

А... Вот в чём дело, "пункт меню". Я-то поначалу, увидев откровенно C++'ные конструкции, заподозрил, что функция у всех одна, ан нет, нужна именно виртуальность -- вызвать действие, соответствующее пункту меню. Тогда да, указатель на функцию дело решает, совет avreal -- в точку. И для случая, когда виртуальная функция в классе одна, это будет даже эффективнее, чем в C++ (правда, никто не запрещает и в C++ сделать "как в C" с той же эффективностью). Выигрыш по памяти от выноса указателей на виртуальные функции в таблицу, как это делается в C++, начинается, когда этих функций хотя бы две.
Последний раз редактировалось ellioh Вс май 01, 2011 16:33:12, всего редактировалось 1 раз.
Клоподавер упрыгхт
Аватара пользователя
boobonick
Встал на лапы
Сообщения: 123
Зарегистрирован: Сб ноя 18, 2006 17:14:15

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

Сообщение boobonick »

Да, спасибо! Так и сделал, через указатель на функцию, просто в моем понимании было, что структура - просто набор разнотипных данных, я и не подозревал, что можно в структуре указатель на функцию сделать :))
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

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

Сообщение lix »

указатель это тоже разнотипные данные :)
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Особенно учитывая то, что лежит в основе «неймановской» архитектуры -- принцип «программа есть данные».
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Может вопрос и не по Си, Но и пр нему тоже.
Нужно сделать так, чтоб отличать нажатие одной кнопки и нескольких.

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

Pressed=0;
   Cur_btn = 0;         
   Pressed =(PINB & 0b00011101);
   if (~Pressed & 0b00000001)   Cur_btn =   Btn_Rear;      
   if (~Pressed & 0b00010000)   Cur_btn=   Btn_Down;   
   if (~Pressed & 0b00001000)   Cur_btn =   Btn_Up;            
   if (~Pressed & 0b00000100)   Cur_btn =   Btn_Neytral;


Такая конструкция работает, но только если нажата только одна кнопка.ели несколько, то срабатывает то условие, что ниже расположено.

Может для каждой кнопки свою переменную сделать. а потом проверять наличие еденицы в этих переменных?
В поисках истины человек развивается.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

я всегда сначала описываю константы, обозначающие кажду кнопку поотдельности, а затем делаю так:

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

int key = get_key(); // получили код всех нажатых кнопок
switch(key){
case KEY1: // нажата первая кнопка
      break;
case KEY2: // нажата вторая кнопка
      break;
case KEY1 | KEY2: // нажаты обе кнопки сразу
      break;
// и так далее
}
естественно, кнопке соответствует один бит в коде.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

md5sum писал(а):vitalik_1984 Судя по

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

#include <avr/io.h>
         #define F_CPU 12000000UL
         #include <util/delay.h>

Вы используете winavr (avr-gcc), но тогда почему компилятор не ругается на

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

int ISR(TIMER0_OVF_vect){
?
ругался, пока не добавил interrupts.h

ISR макрос описан в заголовочном файле avr/interrupts.h и не надо писать int. И asm ("sei"); то-же не надо. А для разрешения прерываний, в том-же interrupts.h есть функция sei()
Я ещё только учусь:)
правда он должен их перебирать, а зажигается только один


В Вашем последнем листинге есть _Button= Off;, но в основном цикле нету _Button= On;
В прерывании таймера то-же закомментирована эта строка.

Она была раскомментирована, иначе бы кнопки вообще не работали.Сохранил неправильно :oops:

Если планируете менять значение _Button в прерывании, то объявите переменную так

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

volatile uint8_t _Button;

Без volatile работает :) спасибо за подсказки
Последний раз редактировалось vitalik_1984 Пн май 02, 2011 23:10:36, всего редактировалось 1 раз.
В поисках истины человек развивается.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Вот как раз хотел добраться до функции switch() не разобрался как она работает.
Если не трудно покажите синтаксис с командами.
Ещё вопрос если нажаты две кнопки то условие с одной уже не должно сработать?

Уж простите за глупые вопросы:)

А KEY1 это что-то вроде:

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

#define KEY1 0x01 
?
В поисках истины человек развивается.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

только #define KEY 0x01 :)
естественно, switch будет реагировать на комбинацию, а не на обе кнопки отдельно, хотя и этот вариант можно реализовать, если приспичит... но логически это неверно: комбинация кнопок должна обозначать ДРУГУЮ команду, чем обе кнопки поотдельности. Например, есть кнопка ВЛЕВО и кнопка ВПРАВО. одновременное нажатие, имхо, не должно приводить к перемещению сначала влево, а потом вправо, зато вполне может приводить к ВХОДУ В МЕНЮ :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

зато вполне может приводить к ВХОДУ В МЕНЮ

Ага именно этого я и хотел.

#define KEY 0x01 уже исправил...после отправки:)

Ещё вопросик:
почему в коде :

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

ISR(SIG_OVERFLOW0){
   tiks++;
   if ((_Button==Off)&&(tiks>50)){
      tiks=0;
      _Button=On;
      TCCR0=0x00;   
   }
}
unsigned char read_key (void){
   Pressed=0;
   Cur_btn = 0;         
   Pressed =(PINB & 0b00011101);
   if (~Pressed & 0b00000001)   Cur_btn =   Btn_Rear;      
   if (~Pressed & 0b00010000)   Cur_btn=   Btn_Down;   
   if (~Pressed & 0b00001000)   Cur_btn =   Btn_Up;            
   if (~Pressed & 0b00000100)   Cur_btn =   Btn_Neytral;            
//----------   
   if (Cur_btn>0)
   {   _Button=Off;
      TCNT0=0x00;
      TCCR0=0x05;
      if ((Cur_btn == Btn_Down)&&(_Gear>0)&&(_Gear<6))               _Gear--;
      if ((Cur_btn ==   Btn_Up) && (_Gear<5))                        _Gear++;
      if (Cur_btn == Btn_Neytral && ( _Gear==2 || _Gear==1 || _Gear==6))   _Gear=0;
      if ((Cur_btn == Btn_Rear) && ( _Gear==0))                     _Gear=6;
   }
   return 0;
}   

while(1){//Begin while
      if (_Button== On) read_key();
      if (Cur_btn>0){
         PORTD = Gears[_Gear];
         if ((_Gear>0)&&(_Gear<6)){
пауза:         PORTD |=0x80;
            //_delay_ms(5);
            PORTD &=(0x7F);
         }
      }            
   }//end while


почему переменная tiks, точнее её сравнение с числом в прерывании меняет паузу при метке пауза.Неужели прерывание сравнение с числом занимает столько времени процессора?Таймер вроде не должен:)
Или опять volatile использовать?
В поисках истины человек развивается.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

ARV писал(а):я не понимаю вашего кода :(

Может немного по быдлокодерски.
Смысл программы прочитать клавиатуру, и включить магниты в соответствии с _Gear.
И чтоб переключения не происходили слишком часто запускается таймер включающий кнопки(_Button On или Off).
Плюс дополнительно нужно при переключении на время включить ещё один магнит.
Примерно так.

Код работает, но почему-то затормаживается - при коде

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

PORTD |=0x80;
PORTD &=(0x7F);

возникает пауза пропорционально if ((_Button==Off)&&(tiks>50<-этому числу))
хотя на это по моей логике(может и ошибочной) не связано друг с другом
Вложения
Gear_shift_manual.c
Полный текст программы
(2.25 КБ) 318 скачиваний
В поисках истины человек развивается.
Ответить

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