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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

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

Сообщение kalobyte »

DX168B писал(а):Однако, этот же шаблон предоставит свободу выбора между float и int, не прибегая к модификации кода.
так это же делает перегрузка функций
DX168B писал(а):Здесь говорится от "глобальных переменных"
ну про глобальные функции я понял
а замыкания эти? когда пишут код в качестве аргумента функции
получается такая каша :facepalm:
тематические ответы только в форуме, в приват не пишите
Реклама
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

По шаблонам. Пример из Википедии:

Обычный класс:

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

class SomeClass
{
    int SomeValue;
    int SomeArray[20];
    ...
};
 
Шаблон:

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

template < int ArrayLength, typename SomeValueType > class SomeClass
{
    SomeValueType SomeValue; // Теперь вместо int тут некий абстрактный тип
    SomeValueType SomeArray[ ArrayLength ];
    ...
};
Отличие от перегрузки функций в том, что тут "перегружается" целый класс.
Вернемся к цитате и разберем ее:
Замыкание (англ. closure) в программировании — функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.
Понял. Тут пишется о функции внутри функции и переменных, локальных во внешней функции,
которые становятся глобальными для внутренней функции (она же вложенная).
Но это неприменимо для C\C++ (ограничения в синтаксисе и парадигме - невозможно объявить функцию внутри функции,
хотя в какой-то версии GCC было нечто подобное, от чего позже отказались), так что можно особо не забивать голову.
Такое есть, например, в Java(Runnable и прочие типы) или в Lua, но не в С\С++

В приведенном Вами примере как раз используется шаблон для реализации "драйверов" в программе.
В одной схеме может применяться микросхема WS2811, в другой - DM164
Для них надо писать собственный код для управления и обменом данными между основной программой и самой микросхемой.
И соответственно, свои классы, которые впоследствии приобретают индивидуальные типы, хоть и организованы одинаково (с одинаковыми названиями функций и прочим) Шаблон был применен как раз для отвязки от этих типов.
Но мне хватает и наследования с полиморфизмом (использование virtual функций).
Я бы создал класс LedDevice с виртуальными методами и наследовался бы от этого класса. А в основной программе оперировал бы указателем на родительский (LedDevice). Кстати, выше я задавал вопросы по этой части и там есть пример.
Кстати. Использование шаблонов может дать более рациональное использование ресурсов процессора (оптимизация),
еже-ли наследование с полиморфизмом.
I am DX168B and this is my favourite forum on internet!
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18617
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

kalobyte писал(а):вот я в быдлодуине и делаю тупо по шаблону
на сколько я понял, речь идет не о C++ templates, а о copy-paste стиле программирования, когда из работающего кода берутся куски и без задействования головного мозга используются в других проектах :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

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

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

template<typename __type>
__type myDivide(__type n, __type d) {
    return n / d;
}
и вызовы:

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

  float f = myDivide(2.f, 1.f);
  double d = myDivide(2., 1.);
  int n = myDivide(2, 1);
компилятор создаст три отдельные функции myDivide для типов float, double и int.

Отличие от перегрузки функций - исходный код меньше замусоривается реализацией одного и того-же алгоритма для всех используемых типов данных.
Фактически имеем тот-же фиговый листок на уровне компилятора как и перегрузка с прочими классовыми обёртками, а на уровне линкера всё возвращается на круги своя - конкретные объекты для конкретных вызовов. ;-)
DX168B писал(а):Но мне хватает и наследования с полиморфизмом (использование virtual функций).
Я бы создал класс LedDevice с виртуальными методами и наследовался бы от этого класса. А в основной программе оперировал бы указателем на родительский (LedDevice). Кстати, выше я задавал вопросы по этой части и там есть пример.
Кстати. Использование шаблонов может дать более рациональное использование ресурсов процессора (оптимизация),
еже-ли наследование с полиморфизмом.
Проблема с виртуальным наследованием - необходимость при каждом вызове искать подходящий метод в VMT и поддерживать сами VMT для каждого объекта, с шаблонами - неявное раздувание кода программы за счёт вышеупомянутого клонирования.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
Эиком - электронные компоненты и радиодетали
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

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

Сообщение kalobyte »

ARV писал(а):на сколько я понял, речь идет не о C++ templates, а о copy-paste стиле программирования
ну да, до шаблонов я не дошел, бросил читать унылый текст
потом внезапно в голове возник образ, что тут есть тема по вопросам с++ и надо задать тут вопрос
DX168B писал(а):Но это неприменимо для C\C++ (ограничения в синтаксисе и парадигме - невозможно объявить функцию внутри функции,
если я ничего не путаю, то эта мода добралась и до нового стандарта с++
ну по крайней мере в интерпретируемых языках оно везде есть
DX168B писал(а):Но мне хватает и наследования с полиморфизмом (использование virtual функций).
вот я о чем и говорю, что когда я писал на плюсах и там тоже был индикатор светодиодный и люминисцентный со своими драйверами
и как раз виртуальная функция позволяла задействовать любой тип индикатора, надо было только дописать управление им

а потом эти шаблоны вот свалились и я подумал, что может быть это я необразованое быдло и надо умных людей спросить

тогда скажите, зачем в пхп такой вот гимор?

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

require 'flight/Flight.php';

Flight::route('/', function(){
    echo 'hello world!';
});

Flight::start();
писать анонимную функцию с кодом в ее теле в качестве аргумента другой функции
это же как код засирается и падает читабельность :shock: :facepalm:
я когда это стал видеть во всех этих фреймворках и яваскриптах и их фреймворках, то у меня чуть крыша не поехала

почему нельзя просто написать именованую функцию и вызвать ее как аргумент функции route типа
Flight::route('/', helloworld()); ?

упд
собственно почитал там дальше доку (просто взял первый попавшийся рестфул пхп фреймворк для примера)
там вот дальше
The callback can be any object that is callable. So you can use a regular function:

function hello(){
echo 'hello world!';
}

Flight::route('/', 'hello');

скобочек нет и что такое hello - непонятно сразу, если не знать заранее
может просто строка

а как тогда передать параметры в эту функцию, если скобочек нет? :shock:
тематические ответы только в форуме, в приват не пишите
Реклама
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Siarzhuk а разве обычная перегрузка функций не вызовет аналогичное раздувание кода, как и шаблоны?
Ведь, по сути, мы пишем несколько функций с одинаковыми именами, но с разными аргументами и телами. В MFC и WinAPI это применяется везде, где только можно.
Я потому и написал "перегружается" в кавычках. Ясное дело, что оно клонируется.

kalobyte
В php я не силен, но могу показать пример на Lua

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

function MyAddFunc(x)
  return function(y) -- Функция внутри функции
    return x + y;
  end
end

PlusTwo = MyAddFunc(2); -- Вытащим функцию.
print(PlusTwo(5)); -- Теперь можно прибавлять двойку к любому переданному числу. В данном случае результат - 7
Суть примера в том, что при вызове MyAddFunc с передачей ей значения (х), она запомнит где-то у себя это значение,
а обратно вернет функцию, с помощью которой можно в дальнейшем складывать это сохраненное значение с переданным аргументом этой функции.
Данный подход позволяет не захламлять глобальное пространство всякими переменными.
I am DX168B and this is my favourite forum on internet!
Реклама
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

DX168B писал(а):Siarzhuk а разве обычная перегрузка функций не вызовет аналогичное раздувание кода, как и шаблоны?
С вашего разрешения ещё немножко позанудствую - при перегрузке функций мы видим все эти функции в исходном коде - и они транслируются компилятором в соответствующее количество функций в объектном файле. Т.е. всё "по честному". В случае шаблона - в исходном коде мы видим одну функцию - а компилятор её уже размножает для разных типов данных в объектном файле - и получается не совсем прозрачно для программиста. Т.е. я имел ввиду субъективное ощущение "раздувания объектников" которое в случае использования шаблонов ИМХО больше.
DX168B писал(а):Ведь, по сути, мы пишем несколько функций с одинаковыми именами, но с разными аргументами и телами. В MFC и WinAPI это применяется везде, где только можно.
В WinAPI всё-же с большего чистый C - там перегрузить функцию видимо будет затруднительно. ;)
DX168B писал(а):Я потому и написал "перегружается" в кавычках. Ясное дело, что оно клонируется.
Да, вы совершенно правы - мы имеем ввиду одно и то же явление. Кстати, мой термин "клонируется" также не совсем точен - копия то не идентичная получается. Можно было бы блеснуть прямой калькой про "инстанциацию" - но, боюсь, это только запутает.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

Ну, более глубоко С++ я еще не изучил. Так что могу где-то и ошибиться.
Siarzhuk писал(а):В WinAPI всё-же с большего чистый C - там перегрузить функцию видимо будет затруднительно. ;)
В С++ версии библиотек Visual Studio (VC2008 по крайней мере) имеются перегруженные функции WinAPI. WinHelp тот же, или MessageBox.
Это по крайней мере выплевывает IntelliSence среды (несколько вариантов одной и той же функции).
Особенно, когда проект с поддержкой Unicode.
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

DX168B писал(а):
Siarzhuk писал(а):В WinAPI всё-же с большего чистый C - там перегрузить функцию видимо будет затруднительно. ;)
В С++ версии библиотек Visual Studio (VC2008 по крайней мере) имеются перегруженные функции WinAPI. WinHelp тот же, или MessageBox.
Это по крайней мере выплевывает IntelliSence среды (несколько вариантов одной и той же функции).
Особенно, когда проект с поддержкой Unicode.
Под WinAPI я подразумевал собственно программный интерфейс операционной системы - при использовании там плюсов все неродные компиляторы и языки будут иметь проблемы с ABI (как например Hiaku OS до сих пор подобно старой деве вынуждена хранить верность и совместимость с gcc 2.95 пятнадцатилетней давности). Хотя взять тот-же COM, по сути уже неотъемлемую часть системы - он плюсовый в основе своей - но все как-то пользуют и ничего - живы. Студия скорее всего вытягивает перегруженные варианты функций из фреймворков - MFC, ATL - при попытке их использования оно затребует хидеры и библиотеки соответствующего фреймворка. Юникодные и не-юникодные билды в общем-то равнофункциональны - при регулярном использовании для строковых литералов макроса _T() можно месяцами собирать обе конфигурации и не встречать связанные с юникодностью/однобайтностью проблемы - если не считать таковыми козявки в самой программе в ANSI билде. API самой системы содержит входы как для юникодных версий так и для однобайтовых - например MessageBox это фактически дефайн, указываюший либо на системный вызов MessageBoxA либо на MessageBoxW в зависимости от определения UNICODE.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

подскажите, есть буфер rx_buffer[256] в котором появилась (произвольного размера) строка типа "1~2~3"
где тильда ~ разделитель между фразами 1,2,3.

Как разобрать эту строку по фразам в разные буферы?
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Циклом, прогоняющимся по символам. Наткнулись на "~" - перекидываемся на другой массив для записи. И так пока не будет обработана вся строка.
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

вроде

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

i=1;
t=0;
do  {
t++;
buffer1[t]=rx_buffer[t];    
if (t==256) {i=0;};
if (rx_buffer[t]=='~') {i=0;};
}
while (i==1);


i=1;
do  {
t++;
buffer2[t]=rx_buffer[t];    
if (t==256) {i=0;};
if (rx_buffer[t]=='~') {i=0;};
}
while (i==1);

i=1;
do  {
t++;
buffer3[t]=rx_buffer[t];    
if (t==256) {i=0;};
if (rx_buffer[t]=='~') {i=0;};
}
while (i==1);
Последний раз редактировалось Аlex Пн мар 30, 2015 21:44:16, всего редактировалось 1 раз.
Причина: тег CODE
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Типа того.
Только каждый кусок можно немного упростить.

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

t=0;
i=0;
while((t<256) && (rx_buffer[t]!='~')) {
  buffer1[i++]=rx_buffer[t++];    
};
buffer1[i]=0x00;  // Конец строки

t++;   // Исключаем разделитель
i=0;  
..........
..........
..........
Как то, примерно, так...
t обнуляем только вначале, i - перед каждым циклом.

Только в таком случае строка должна быть типа "1~2~3~", т.к. '~' будет не совсем разделителем, а скорее концом каждой подстроки.
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

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

Сообщение levaclaus »

спасибо, попробую.
ещё момент, пришла строка в rx_buffer, я её обработал. Как теперь по быстрому очистить rx_buffer?
как вариант
buffer1[i++]=rx_buffer[t++];
rx_buffer[t]=0x00;
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

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

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

Сообщение ARV »

levaclaus писал(а):спасибо, попробую.
ещё момент, пришла строка в rx_buffer, я её обработал. Как теперь по быстрому очистить rx_buffer?
как вариант
buffer1[i++]=rx_buffer[t++];
rx_buffer[t]=0x00;
тогда уж

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

 buffer1[i++]=rx_buffer[t]; 
rx_buffer[t++]=0x00;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

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

Сообщение kalobyte »

DX168B писал(а):Данный подход позволяет не захламлять глобальное пространство всякими переменными.
и чем плохи глобальные переменные? везде пишут про их вред, но так же проще

вопрос еще возник
в контроллере домена виндовса хочу внести дополнительные поля в схему базы данных
там будут храниться пароли к почтовым акаунтам пользователей на каком-нибудь стороннем сервере
нужно это для механизма автонастройки почтовика thunderbird

хранить пароли в открытом виде нехорошо и вот я подумал, а есть ли алгоритм такой, чтобы зашифровать и потом расшифровать на стороне клиента
и чтобы никто не мог понять как оно зашифровано
я знаю base64, но это не шифрование, а кодировка
знаю еще мд5 и все такое, но это не то совсем, оно не расшифровывается
тематические ответы только в форуме, в приват не пишите
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

kalobyte писал(а):и чем плохи глобальные переменные? везде пишут про их вред, но так же проще
Если писать весь код (для одного мелкого проекта) в одном файле - то так действительно проще, да и код получается компактнее.

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

В общем, для себя можно писать как угодно. Особенно если размер flash поджимает. Но с точки зрения повторного использования кода лучше глобальных переменных избегать.
kalobyte писал(а):а есть ли алгоритм такой, чтобы зашифровать и потом расшифровать на стороне клиента
Есть понятие несимметричного шифрования. Данные шифруются одним ключом (приватным, никому не известным), а расшифровываются другим (публичным). При этом, не имея приватного ключа, нельзя подделать шифрование данных. Пара слов по теме
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

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

Сообщение DX168B »

kalobyte писал(а): и чем плохи глобальные переменные? везде пишут про их вред, но так же проще
Выше уже написали.
kalobyte писал(а): вопрос еще возник
в контроллере домена виндовса хочу внести дополнительные поля в схему базы данных
там будут храниться пароли к почтовым акаунтам пользователей на каком-нибудь стороннем сервере
нужно это для механизма автонастройки почтовика thunderbird

хранить пароли в открытом виде нехорошо и вот я подумал, а есть ли алгоритм такой, чтобы зашифровать и потом расшифровать на стороне клиента
и чтобы никто не мог понять как оно зашифровано
я знаю base64, но это не шифрование, а кодировка
знаю еще мд5 и все такое, но это не то совсем, оно не расшифровывается
MD5 - это алгоритм хеширования.
Смотреть надо в сторону RSA шифрования. Например, теория есть тут: СЦЫЛКО
или AES или DEC или .... тысячи их...
I am DX168B and this is my favourite forum on internet!
kalobyte
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

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

Сообщение kalobyte »

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

и все равно я не вижу причин не использовать глобальные переменные и в библиотеках
современная иде должна показать имена глобальных переменных или взять их из описания в самом файле
а дальше ты уже подстраиваешся

я это спросил потому, что функция иногда требует вернуть результат больше чем просто return x
поэтому можно использовать глобальные переменные и менять их без использования возврата значения
DX168B писал(а):Например, теория есть тут:
написано непонятно для кого и слишком много матана и египетских закорючек

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

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

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