|
|
  |
К знатокам, Локальные переменные. |
|
|
|
Sep 21 2007, 04:36
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(singlskv @ Sep 20 2007, 20:13)  А на каком проце вы вызываете виртуальные методы классов из прерывания ?
Видимо джиттер в Ваших задачах несущественен ? Atmega128-1280-2560. Сейчас сижу на этой линейке. Там, где он существенен, я делаю методы класса встраиваемыми (и не использую виртуальные) - и никакого джиттера  . Тут надо соблюсти баланс между удобством и скоростью обработки. Там где скорость обработки может быть не сильно высокой, на первый план выходит удобство программирования и реюзабельность кода. Что касается методов классов и виртуальных методов, то по сравнению с ф-циями С для первых оверхед - это лишний двухбайтовый аргумент, а для вторых - этот же аргумент + считывание указателя из флэша и переход по нему. К тому же, за счет передачи указателя, обычно сокращается число передаваемых аргументов - все необходимые данные уже есть в экземпляре класса. Так что там, где допустима ф-ция С, вполне можно использовать и методы объектов С++. Цитата(dxp @ Sep 21 2007, 07:49)  Какая связь между джиттером и виртуальными функциями классов? Джиттер == оверхед или я чего не понял? Если так - то самая прямая - расходы на вызов виртуальной ф-ции больше, чем на вызов обычной ф-ции -члена ... Тока что прочитал: джиттер - нежелательные фазовые и/или частотные случайные отклонения передаваемого сигнала.... Тогда связь действительно малопонятна...
|
|
|
|
|
Sep 21 2007, 05:50
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Непомнящий Евгений @ Sep 21 2007, 11:36)  Джиттер == оверхед или я чего не понял? Под джиттером, связанным с прерываниями, в МК обычно понимают разброс латентности перехода к прерываниям. Какая связь с объктами классов, да еще и вызываемых из прерываний (т.е. когда переход к прерыванию уже произошел), мне не понятно. Цитата(Непомнящий Евгений @ Sep 21 2007, 11:36)  Если так - то самая прямая - расходы на вызов виртуальной ф-ции больше, чем на вызов обычной ф-ции -члена ... Дык виртуальный вызов, он и функциональность несет несколько иную. Это аналог косвенного вызова функции по указателю из таблицы. На С чтобы достичь функциональности виртуальной функции придется городить эти самые таблицы, извлекать оттуда нужный указатель и делать вызов. Накладные расходы ровно те же самые (т.к. механизм также ровно тот же), но делать все надо руками, что загромождает код и предоставляет поле для ошибок. Частенько когда говорят об оверхеде виртуальных функций просто забывают, что сравнивают их при этом с обычными функциями. А это неверно, т.к. это разные по функциональности вещи. Сравнивать надо с таблицами указателей на функции и косвенным вызовом обычных функций. И тут оверхеда по быстродействию как-то и не видно. Оверхед по памяти действительно есть - это необходимость хранения vptr в объекте класса, но это реально очень небольшой оверхед по памяти - один указатель. P.S. В терминах С++ термин "метод" является синонимом термина "виртуальная функция". Т.ч. невиртуальные фукнции - это не методы, это просто функции-члены. Предлагаю придерживаться этой терминологии, дабы не вносить путаницы.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 21 2007, 06:49
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(dxp @ Sep 21 2007, 09:50)  P.S. В терминах С++ термин "метод" является синонимом термина "виртуальная функция". Т.ч. невиртуальные фукнции - это не методы, это просто функции-члены. Предлагаю придерживаться этой терминологии, дабы не вносить путаницы.  Я всегда считал, что функция-член == метод, а вирт. ф-ция-член == вирт. метод. Но не буду спорить А насчет оверхеда виртуальных функций можно посмотреть вот с какой стороны: чтобы сделать эквивалентное в С и минимизировать ручную работу и ошибки, надо хорошо продумать стратегию + возможно реализовать несколько макросов + все равно останется масса ручной работы. Поэтому в С "виртуальные" функции используются только там, где это действительно нужно и после долгих размышлений об альтернативных вариантах. С другой стороны, в С++ достаточно написать слово virtual, что несколько развращает. Поэтому возникает желание запихивать виртуальные ф-ции во все дырки. Соответственно, растет и оверхед
|
|
|
|
|
Sep 21 2007, 07:14
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Непомнящий Евгений @ Sep 21 2007, 13:49)  А насчет оверхеда виртуальных функций можно посмотреть вот с какой стороны: чтобы сделать эквивалентное в С и минимизировать ручную работу и ошибки, надо хорошо продумать стратегию + возможно реализовать несколько макросов + все равно останется масса ручной работы. Поэтому в С "виртуальные" функции используются только там, где это действительно нужно и после долгих размышлений об альтернативных вариантах. В С++ это тоже точно так же. Если представляешь, как оно реализуется, во что выливается, если это слишком дорогой оверхед (один указатель  ), то тоже не используешь, а ищешь какие-то обходные пути. Все в руках разработчика.  Цитата(Непомнящий Евгений @ Sep 21 2007, 13:49)  С другой стороны, в С++ достаточно написать слово virtual, что несколько развращает. Поэтому возникает желание запихивать виртуальные ф-ции во все дырки. Соответственно, растет и оверхед  Ну-у, вы еще шаблоны забыли - вот где возможность одним движением нагенерить мегатонны кода.  Никто ж не спорит, что надо осмотрительно пользоваться средствами языка. А для этого надо прежде всего их знать. Т.е. изучать. Чем мы, кроме всего прочего, тут и занимаемся.  Цитата(alexander55 @ Sep 21 2007, 13:51)  Я уверен, никто, кто работает с С++, не запутается, а если человек работает с С - то он даже не обратит на это внимания. Ну, не знаю. Лично я, когда в контексте С++ вижу слово "метод", сразу понимаю под ним виртуальную функцию, т.к. это соответсвует терминологии, введенной по этому поводу Б.Страуструпом, а он для меня в этих вопросах авторитет.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 21 2007, 08:46
|
Участник

Группа: Validating
Сообщений: 56
Регистрация: 15-10-06
Пользователь №: 21 335

|
Цитата(dxp @ Sep 21 2007, 11:14)  Ну, не знаю. Лично я, когда в контексте С++ вижу слово "метод", сразу понимаю под ним виртуальную функцию, т.к. это соответсвует терминологии, введенной по этому поводу Б.Страуструпом, а он для меня в этих вопросах авторитет.  Не флейма ради , а инфы для - _где_ он это писал ? Щаз пробежался по книжке - не углядел....
|
|
|
|
|
Sep 21 2007, 09:12
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Maddy @ Sep 21 2007, 15:46)  Не флейма ради , а инфы для - _где_ он это писал ? Щаз пробежался по книжке - не углядел.... ссылку я уже давал однажды, но не помню, в какой теме. Ну, вот еще раз (даю в контексте): Bjarne Stroustrup - The C++ Programming Language 3rd Edition 12.2.6 Virtual Functions [derived.virtual] ... To allow a virtual function declaration to act as an interface to functions defined in derived classes, the argument types specified for a function in a derived class cannot differ from the argu- ment types declared in the base, and only very slight changes are allowed for the return type (§15.6.2). A virtual member function is sometimes called a method.A virtual function must be defined for the class in which it is first declared (unless it is declared to be a pure virtual function; see §12.3). For example: ... В русском переводе оно находится точно в этом же месте. И слово метод там выделено курсивом.  Еще, кажется, мне это встречалось в его же "Дизайн и эволюция С++", но где именно в ней, не помню, а под рукой ее сейчас нет.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 21 2007, 18:26
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(dxp @ Sep 19 2007, 16:21)  C++ - это принципиально иной подход к программированию. При внешней схожести С и С++ очень разные языки. Прежде всего разные тем, что на них думать надо совсем по-разному (если, конечно, от ++ хочется получить то, что они дают, а не остаться в рамках процедурного С). Да вот именно с этим у меня и проблемы пока. Книги перечитывал уже не раз. И с Delfi работаю давно. Вроде всё понимаю и основные понятия объектного программирования чётко знаю, но пока на душу не легло. Как zltigo где-нибудь в графике применить бы смог. Там это понятно. Но создание объекта "фильтр" пока из души не идёт и кажется притянутым за уши. (мне естественно. Я совершенно не утверждаю что это неправильно). Вот, к слову (извините за отступление, но уж если начали) прислал мне один молодой программист текст проги. Я ему слегка завидую, потому что я бы такое не написал не в жизь. Прошу прощение что на дельфях, но я думаю для большинства это не проблема. Главное не реализация а само чуство объекта. Итак может ли мне кто-нибудь наглядно пояснить в чём (в приведенном примере) объектная реализация удобнее (или какие преимущества имеет). Приведу текст. (вырывать кусок не буду по понятным причинам) 1) Объектный Код unit CRCUnit;
interface
type TByteArray = array of Byte;
// Вычислитель CRC8 TCRC8Calc = class private FValue : Byte; public constructor Create; function Evaluate(B : Byte) : Byte; overload; function Evaluate(B : TByteArray) : Byte; overload; property CurrentValue : Byte read FValue write FValue; end;
// Вычислитель CRC16 TCRC16Calc = class private FValue : Word; public constructor Create; function Evaluate(B : Byte) : Word; overload; function Evaluate(B : TByteArray) : Word; overload; function Evaluate(B : TByteArray; Position, Count : Integer) : Word; overload; property CurrentValue : Word read FValue write FValue; end;
implementation
const crc8InitValue = $DE; crc8tab : array[0..255] of byte = ( $00, $5E, $BC, $E2, $61, $3F, $DD, $83, $C2, $9C, $7E, $20, $A3, $FD, $1F, $41, $9D, $C3, $21, $7F, $FC, $A2, $40, $1E, $5F, $01, $E3, $BD, $3E, $60, $82, $DC, $23, $7D, $9F, $C1, $42, $1C, $FE, $A0, $E1, $BF, $5D, $03, $80, $DE, $3C, $62, $BE, $E0, $02, $5C, $DF, $81, $63, $3D, $7C, $22, $C0, $9E, $1D, $43, $A1, $FF, $46, $18, $FA, $A4, $27, $79, $9B, $C5, $84, $DA, $38, $66, $E5, $BB, $59, $07, $DB, $85, $67, $39, $BA, $E4, $06, $58, $19, $47, $A5, $FB, $78, $26, $C4, $9A, $65, $3B, $D9, $87, $04, $5A, $B8, $E6, $A7, $F9, $1B, $45, $C6, $98, $7A, $24, $F8, $A6, $44, $1A, $99, $C7, $25, $7B, $3A, $64, $86, $D8, $5B, $05, $E7, $B9, $8C, $D2, $30, $6E, $ED, $B3, $51, $0F, $4E, $10, $F2, $AC, $2F, $71, $93, $CD, $11, $4F, $AD, $F3, $70, $2E, $CC, $92, $D3, $8D, $6F, $31, $B2, $EC, $0E, $50, $AF, $F1, $13, $4D, $CE, $90, $72, $2C, $6D, $33, $D1, $8F, $0C, $52, $B0, $EE, $32, $6C, $8E, $D0, $53, $0D, $EF, $B1, $F0, $AE, $4C, $12, $91, $CF, $2D, $73, $CA, $94, $76, $28, $AB, $F5, $17, $49, $08, $56, $B4, $EA, $69, $37, $D5, $8B, $57, $09, $EB, $B5, $36, $68, $8A, $D4, $95, $CB, $29, $77, $F4, $AA, $48, $16, $E9, $B7, $55, $0B, $88, $D6, $34, $6A, $2B, $75, $97, $C9, $4A, $14, $F6, $A8, $74, $2A, $C8, $96, $15, $4B, $A9, $F7, $B6, $E8, $0A, $54, $D7, $89, $6B, $35 ); crc16InitValue = $00DE; crc16tab : array[0..255] of Word = ( $0000, $1189, $2312, $329B, $4624, $57AD, $6536, $74BF, $8C48, $9DC1, $AF5A, $BED3, $CA6C, $DBE5, $E97E, $F8F7, $1081, $0108, $3393, $221A, $56A5, $472C, $75B7, $643E, $9CC9, $8D40, $BFDB, $AE52, $DAED, $CB64, $F9FF, $E876, $2102, $308B, $0210, $1399, $6726, $76AF, $4434, $55BD, $AD4A, $BCC3, $8E58, $9FD1, $EB6E, $FAE7, $C87C, $D9F5, $3183, $200A, $1291, $0318, $77A7, $662E, $54B5, $453C, $BDCB, $AC42, $9ED9, $8F50, $FBEF, $EA66, $D8FD, $C974, $4204, $538D, $6116, $709F, $0420, $15A9, $2732, $36BB, $CE4C, $DFC5, $ED5E, $FCD7, $8868, $99E1, $AB7A, $BAF3, $5285, $430C, $7197, $601E, $14A1, $0528, $37B3, $263A, $DECD, $CF44, $FDDF, $EC56, $98E9, $8960, $BBFB, $AA72, $6306, $728F, $4014, $519D, $2522, $34AB, $0630, $17B9, $EF4E, $FEC7, $CC5C, $DDD5, $A96A, $B8E3, $8A78, $9BF1, $7387, $620E, $5095, $411C, $35A3, $242A, $16B1, $0738, $FFCF, $EE46, $DCDD, $CD54, $B9EB, $A862, $9AF9, $8B70, $8408, $9581, $A71A, $B693, $C22C, $D3A5, $E13E, $F0B7, $0840, $19C9, $2B52, $3ADB, $4E64, $5FED, $6D76, $7CFF, $9489, $8500, $B79B, $A612, $D2AD, $C324, $F1BF, $E036, $18C1, $0948, $3BD3, $2A5A, $5EE5, $4F6C, $7DF7, $6C7E, $A50A, $B483, $8618, $9791, $E32E, $F2A7, $C03C, $D1B5, $2942, $38CB, $0A50, $1BD9, $6F66, $7EEF, $4C74, $5DFD, $B58B, $A402, $9699, $8710, $F3AF, $E226, $D0BD, $C134, $39C3, $284A, $1AD1, $0B58, $7FE7, $6E6E, $5CF5, $4D7C, $C60C, $D785, $E51E, $F497, $8028, $91A1, $A33A, $B2B3, $4A44, $5BCD, $6956, $78DF, $0C60, $1DE9, $2F72, $3EFB, $D68D, $C704, $F59F, $E416, $90A9, $8120, $B3BB, $A232, $5AC5, $4B4C, $79D7, $685E, $1CE1, $0D68, $3FF3, $2E7A, $E70E, $F687, $C41C, $D595, $A12A, $B0A3, $8238, $93B1, $6B46, $7ACF, $4854, $59DD, $2D62, $3CEB, $0E70, $1FF9, $F78F, $E606, $D49D, $C514, $B1AB, $A022, $92B9, $8330, $7BC7, $6A4E, $58D5, $495C, $3DE3, $2C6A, $1EF1, $0F78 );
//============================================================================== { TCRC8Calc }
constructor TCRC8Calc.Create; begin FValue := crc8InitValue; end; //------------------------------------------------------------------------------
function TCRC8Calc.Evaluate(B : Byte) : Byte; begin FValue := crc8tab[FValue xor B]; Result := FValue; end; //------------------------------------------------------------------------------
function TCRC8Calc.Evaluate(B : TByteArray) : Byte; var i : Integer; begin for i := Low(B) to High(B) do Evaluate(B[i]); Result := FValue; end; //============================================================================== { TCRC16Calc }
constructor TCRC16Calc.Create; begin FValue := crc16InitValue; end; //------------------------------------------------------------------------------
function TCRC16Calc.Evaluate(B : Byte) : Word; begin FValue := crc16tab[Byte(FValue) xor B] xor Byte(FValue shr 8); Result := FValue; end; //------------------------------------------------------------------------------
function TCRC16Calc.Evaluate(B : TByteArray) : Word; var i : Integer; begin for i := Low(B) to High(B) do Evaluate(B[i]); Result := FValue; end; //------------------------------------------------------------------------------
function TCRC16Calc.Evaluate(B : TByteArray; Position, Count : Integer) : Word; var i : Integer; begin for i := 0 to Count - 1 do Evaluate(B[i + Position]); Result := FValue; end; //============================================================================== end. Стандартное приводить не буду - оно очевидно
|
|
|
|
|
Sep 21 2007, 18:54
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(SasaVitebsk @ Sep 21 2007, 22:26)  Прошу прощение что на дельфях, но я думаю для большинства это не проблема. На дельфи никогда не писал, но паскаль вроде знал неплохо... Цитата Главное не реализация а само чуство объекта. Вызывает сомнение "чуство объекта" у автора. Цитата Итак может ли мне кто-нибудь наглядно пояснить в чём (в приведенном примере) объектная реализация удобнее (или какие преимущества имеет). Ничем, собственно классы здесь притянуты за уши. Все функции члены которые ссылаются на глобалные массивы и глобальные начальные переменные должны будут переписаны в производном классе если он будет иметь другой полином... А если этот класс не предполагает наследования, нафига там функции члены определены как перегружаемые ? P.S. Если чего напутал в дельфях, прошу прощения...
|
|
|
|
|
Sep 21 2007, 20:44
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(dxp @ Sep 21 2007, 09:50)  Под джиттером, связанным с прерываниями, в МК обычно понимают разброс латентности перехода к прерываниям. Какая связь с объктами классов, да еще и вызываемых из прерываний (т.е. когда переход к прерыванию уже произошел), мне не понятно. джиттер это не толко разброс min/max тактов MCU при входе в прерывание, для конкретной задачи куда более важным является разброс в min/max тактов между возникновением события и реакцией на него. В общем случае, этот разброс для проги на С++ ,будет больше..., а в частных случаях, если не пользоваться C++ функциональностью(то есть пишем на C++ как на С), результат будет точно таким же как в С. Тока тогда нужно говорить примерно так: Пишу проги С++... на С.
|
|
|
|
|
Sep 22 2007, 16:52
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(singlskv @ Sep 22 2007, 03:44)  джиттер это не толко разброс min/max тактов MCU при входе в прерывание, для конкретной задачи куда более важным является разброс в min/max тактов между возникновением события и реакцией на него. В общем случае, этот разброс для проги на С++ ,будет больше..., а в частных случаях, если не пользоваться C++ функциональностью(то есть пишем на C++ как на С), результат будет точно таким же как в С. Тока тогда нужно говорить примерно так: Пишу проги С++... на С. Хорошо, если умозрительно не удается прийти к общему знаменателю, давайте посмотрим на конкретном примере. Покажите пример, как, скажем, С++ные классы увеличивают время реакции на событие? По сравнению с реализацией на голом С. Цитата(SasaVitebsk @ Sep 22 2007, 01:26)  Да вот именно с этим у меня и проблемы пока. Книги перечитывал уже не раз. И с Delfi работаю давно. Вроде всё понимаю и основные понятия объектного программирования чётко знаю, но пока на душу не легло. Как zltigo где-нибудь в графике применить бы смог. Там это понятно. Но создание объекта "фильтр" пока из души не идёт и кажется притянутым за уши. (мне естественно. Я совершенно не утверждаю что это неправильно). Вот, к слову (извините за отступление, но уж если начали) прислал мне один молодой программист текст проги. Я ему слегка завидую, потому что я бы такое не написал не в жизь. Прошу прощение что на дельфях, но я думаю для большинства это не проблема. Главное не реализация а само чуство объекта. Итак может ли мне кто-нибудь наглядно пояснить в чём (в приведенном примере) объектная реализация удобнее (или какие преимущества имеет). Я не буду оригинальным, просто повторю, что говорят авторитетные дядьки вроде Г.Буча и Б.Страуструпа. Самое главное при объектном подходе - это сопоставлять классы и объекты объектам реального мира. Мир в восприятии человека представляется дискретным - человек выделяет в нем более-менее законченные целостные объекты, понятия, которыми он оперирует, строя модели. Так вот объектные (и объектно-ориентированные) языки позволяют на уровне средств языка оперировать типами, отображаемыми на объекты реального мира. Просто старайтесь вычленить в своей программе и прежде всего в той предметной области, которую описывает программа, эти самые законченные (на достаточном уровне абстракции, конечно) объекты и понятия, а после этого уже можно спокойно описывать эти объекты у себя в программе. Этот подход позволяет при разработке программы сразу думать на уровне объектов, а не разрозненных переменных, связи между которыми при отсутствии тех же классов разработчику приходится держать в голове. Понятно, что думать на уровне объектов реального мира намного проще, чем на уровне гораздо большего количества неких в разной мере абстрактных переменных встроенных типов. Попробуйте думать над программой на уровне объектов реального мира, это совсем не сложно, тогда реализация ляжет на классы почти сама собой.  Например, упомянутый вами фильтр является вполне законченным и целостным объектом реального мира, даже не вникая в его суть. У него есть вход, есть выход, есть (опционально) настроечные параметры-функции. Исходя из этого, даже не вникая во внутренности, можно написать: Код typedef TFilterIn ...; // входной объект для фильтра typedef TFilterOut ...; // выходной объект фильтра
class TFilter { public: TFilter(); // конструктор по умолчанию, создает объект фильтра с параметрами по умолчанию TFilter(...); // 1-й конструктор с параметрами - создает объект фильтра с какими-то спец. свойствами ... TFilter(...); N- й конструктор с параметрами - создает объект фильтра с какими-то спец. свойствами
void in(TFilterIn x); // принимает объект для фильтрации TFilterOut out(); // отдает результат фильтрации void execute(); // выполняет собственно фильтрацию
private: ... } Конечно, это псевдокод, в реале все может быть гораздо скромнее (не иметь обилия конструкторов) или наоборот гораздо обширнее (скажем, иметь пачку функций для настройки параметров фильтра). В частности, вместо трех функций in(), out(), execute() скорее всего можно оставить одну: Код TFilterOut execute(TFilterIn); Объекты типов TFilterIn и TFilterOut могут быть просто указателями на массивы данных, а могут тоже быть объектами классов, если удобно представлять эти данные в виде законченных объектов. Это уже зависит от предметной области и предпочтений разработчика. Можно даже вместо обычных функций перегрузить операторы, чтобы использование фильтра выглядело так: Код TFilter Filter; TFilterIn fi = ...; ... TFilterOut fo = Filter << fi; Словом, это уже частности, разнообразию реализаций несть числа. Главное, что я хочу подчеркнуть - даже не зная тонкостей реализации, можно вот так вот быстренько накидать каркас объекта. А это уже немало, по имеющейся "рыбе" дальше писать реализацию намного проще. Зачастую, когда начинаешь работать над новой вещью, порой не знаешь, с какого конца за нее браться. А тут подход почти формальный. Развивая вышесказанное, следует отметить, что С++ позволяет легко сместить акцент на проектирование программы. Если хорошо представляете себе предметную область, в контексте которой разрабатывается программа, то можно взять лист бумаги (хотя лучше это делать в каком-нить редакторе вроде Visio  ) и нарисовать на нем структурную схему, в которой квадратиками обозначить все имеющиеся прототипы объектов реального мира, реализуемых в программе - это будут классы, а связи (стрелки) между квадратиками - это не что иное, как открытые (public) функции-члены этих классов, т.е. их интерфейс. Далее можно уже просто спокойно по этой схеме набивать "скелет" программы, т.к. он фактически на этой структурной схеме представлен в графическом виде. Таким образом, подход к проектированию программы во значительной мере является формализованным, что весьма облегчает процесс ее разработки. Безусловно, все это можно (и нужно) делать и при использовании С и даже ассемблера, но делать там это значительно труднее, т.к. языки не поддерживают напрямую концепцию объектов, и там придется прикладывать усилия для того, чтобы логически держать разрозненные переменные встроенных типов и функции, с ними связанные, вместе. При некотором объеме программы делать это станет фактически невозможным, хотя чем больше программа, тем более актуальным становится объектный подход.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Sep 22 2007, 17:49
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(dxp @ Sep 22 2007, 20:52)  , давайте посмотрим на конкретном примере. Давайте, код на Gcc для AVR: Код // регистровые переменные для работы прерывания системного таймера
register BYTE ADCL_ asm("r2"); register BYTE ADCH_ asm("r3"); register BYTE ADMUX_ asm("r4"); register BYTE ADCSRA_ asm("r5"); register BYTE SYSTICKSTART_ asm("r6"); register BYTE PINB_ asm("r7"); register BYTE PINC_ asm("r8"); register BYTE PIND_ asm("r9");
//------------------------------------------------------------------- // Прерывание системного таймера // используются только регистровые переменные // никакие регистры не сохраняются // SREG не сохраняется //-------------------------------------------------------------------
void TIMER2_COMP_vect(void) __attribute__((signal)) __attribute__((naked)); void TIMER2_COMP_vect() { ADCL_ = ADCL; // читаем результат последнего преобразования ADCH_ = ADCH; ADMUX = ADMUX_; // новый канал ADCSRA = ADCSRA_; // запускаем новое преобразование // информируем о начале нового цикла SYSTICKSTART_= ADCSRA_; // записью значения ADCSRA в SYSTICKSTART_ // сбрасывается в 0 в основном цикле PINB_ = PINB; // читаем порты PINC_ = PINC; PIND_ = PIND; __asm__ __volatile__ ("reti" ::); // выходим } 8 команд + вход и выход, джиттер 1 такт Конечно это не голый C, но для микроконтртроллеров он и не бывает без всяких примочек типа прагм, указаний где лежат данные, и т.д. Цитата Безусловно, все это можно (и нужно) делать и при использовании С и даже ассемблера, но делать там это значительно труднее, т.к. языки не поддерживают напрямую концепцию объектов, и там придется прикладывать усилия для того, чтобы логически держать разрозненные переменные встроенных типов и функции, с ними связанные, вместе. При некотором объеме программы делать это станет фактически невозможным, хотя чем больше программа, тем более актуальным становится объектный подход. Интересно, по Вашему линух это достаточно большая программа для того что бы ее уже необходимо было писать на С++ ? Почему авторы предпочли писать линух на С ?
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|