Dale
|
|
« : 12-10-2010 08:56 » |
|
Попался на глаза очень компактный и в то же время содержательный тест на знание языка С. Может пригодиться тем, кто проводит собеседование с кандидатами на работу: http://chipenable.ru/index.php/programming-c/68-c-test-the-0x10-best-questions-for-would-be-embedded-programmers.htmlКонечно, сейчас на С пишут все меньше, но все же может оказаться полезным. Не обращайте внимания на якобы ориентацию на встраиваемые системы, там они вскользь упоминаются в единственном вопросе. Никакой привязки к конкретной реализации языка нет.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Вад
|
|
« Ответ #1 : 12-10-2010 11:07 » |
|
3. Каково назначение директивы препроцессора #error? Этот вопрос очень полезен, если требуется отличить нормальных парней от ботаников. Обычно только ботаники читают приложения к руководствам по Си, чтобы узнать о таких вещах. А я его в деле как-то увидел, собирая чужой проект, и только потому знаю, зачем оно Так что мимо цели.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #2 : 13-10-2010 17:26 » |
|
Тест очень понравился.
Вопрос 14 считаю не совсем правильно описанным: нельзя допускать запроса выделения нуля байт - это явная ошибка, которую нужно обработать и поведение malloc() будет уже не важно.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #3 : 14-10-2010 21:08 » |
|
Насчет #error дядька конечно погорячился. Я сам юзал его целых 2 раза в жизни. Было такое, что писал целенаправленно под новую версию одной либы. Старую в этом коде не поддерживал. Вот #error весьма кстати был. Надо ведь, чтоб человек, который решит скомпилить этот код под старую версию, во-первых обломался (еще спасибо скажет), во-вторых без лишних телодвижений мог понять почему у него скомпилиться не получилось
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #4 : 15-10-2010 04:33 » |
|
resource, и тем не мение это очень специфичная задача и не каждый день с ней сталкиваешься, я так не разу не писал
|
|
|
Записан
|
Странно всё это....
|
|
|
Dale
|
|
« Ответ #5 : 15-10-2010 06:25 » |
|
На самом деле действительно нужная штука, если макрос делает что-то обобщенное. На С++ можно позволить себе роскошь игнорировать макросы практически полностью, а вот на С вряд ли это получится. Другое дело, что кроме написания firmware эти навыки сегодня мало востребованы.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 15-10-2010 06:43 » |
|
На С++ можно позволить себе роскошь игнорировать макросы практически полностью,
да не особо-то Иногда требуется
|
|
|
Записан
|
|
|
|
Dale
|
|
« Ответ #7 : 15-10-2010 06:52 » |
|
Ну разве что для условной компиляции, когда нужно генерировать разные варианты кода в зависимости от обстоятельств. Другого оправданного применения так сразу и не придумаю. Хотя тут я не эксперт, доля С++ за последние годы у меня как-то резко уменьшилась.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 15-10-2010 07:14 » |
|
Ну разве что для условной компиляции, когда нужно генерировать разные варианты кода в зависимости от обстоятельств
об этом вообще молчу, это само собой ) один из примером - строковые константы, используется то свойство C++, "11111" "2222" ~ "111112222" что строку можно с разрывом описывать: #define text "33333"; "11111"text"2222" ~ "11111333332222" этим активно пользуюсь
|
|
|
Записан
|
|
|
|
Dale
|
|
« Ответ #9 : 15-10-2010 07:35 » |
|
Кстати, насчет необходимости условной компиляции в С++ я, пожалуй, погорячился. Вполне достаточно будет обычного условного оператора, вроде const bool DEBUG_PRINT = false; ... if (DEBUG_PRINT) printf(...
Компилятор во время оптимизации выкинет заведомо недостижимый код. Добавлено через 4 минуты и 46 секунд:Что из существенного, на мой взгляд, упустил автор тестов - это квалификатор restrict. Следовало бы хотя бы в один вопрос включить.
|
|
« Последнее редактирование: 15-10-2010 07:40 от Dale »
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 15-10-2010 08:27 » |
|
Кстати, насчет необходимости условной компиляции в С++ я, пожалуй, погорячился. Вполне достаточно будет обычного условного оператора, вроде const bool DEBUG_PRINT = false; ... if (DEBUG_PRINT) printf(...
Компилятор во время оптимизации выкинет заведомо недостижимый код. дело частенько не в столько недостижимости кода, сколько в его невозможности в определённой конфигурации. К примеру, нет класса A в данной конфигурации. Какие тут флаги ? неее, только дефайном содержимое кода , использующего класс, прикрыть
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 15-10-2010 08:29 » |
|
конечно, всё можно сделать, применив шаблон, но это иногда есть жопа, так как это ж всё ещё написать надо, отладить и засунуть в h файл (девайнам же по барабану, а кроме того, им в cpp - самое место, чтобы ограничить видимость)
|
|
|
Записан
|
|
|
|
Dale
|
|
« Ответ #12 : 15-10-2010 08:57 » |
|
Я в данном вопросе полностью солидарен со Страуструпом: Макросы почти никогда не требуются в C++. ("Язык программирования С++. Специальное издание", 1.6.1). Видимо, макросы условной компиляции и есть это самое "почти".
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 15-10-2010 09:44 » |
|
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #14 : 15-10-2010 11:37 » |
|
Видимо, макросы условной компиляции и есть это самое "почти".
Преимущественно, частный случай - классическая защита заголовков: #ifndef MY_HEARER_H_ #define MY_HEARER_H_
//.. #endif //MY_HEARER_H_
Как бы ни делали поддержку прагм, от греха предпочитаю только этот способ
|
|
|
Записан
|
|
|
|
Dale
|
|
« Ответ #15 : 15-10-2010 11:43 » |
|
Преимущественно, частный случай - классическая защита заголовков. Пожалуй, единственное оправданное применение условной компиляции, если не считать всякие отладочные печати.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
RXL
|
|
« Ответ #16 : 15-10-2010 22:27 » |
|
А константы забыли? Или вы маньяки глобальных const-переменных?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dale
|
|
« Ответ #17 : 15-10-2010 23:10 » |
|
Страсть к глобальным объектам в языках, допускающих инкапсуляцию, вообще признак маниакальности, будь то константы или что другое. Недаром в C# и Java их вообще нет в принципе. Другое дело С, где другим способом, кроме препроцессора, константу ввести сложно.
Сами по себе макросы в отрыве от контекста не есть добро или зло. Как тот же пресловутый goto: в языке с развитыми управляющими структурами почти всегда выглядит нелепо, а в программе на Фортране или ассемблере - нормальный рабочий вариант. Так же и здесь: если что-то можно сделать без макроса - лучше обойтись без него; если макрос уместен - почему бы и нет? В С++ почти всегда удается обойтись, в С намного реже.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 16-10-2010 08:43 » |
|
В С++ почти всегда удается обойтись
да, только иногда на обход надо потратить кучу времени. Проще быстро сделать макрос, оставив пометку {int iii;}//переделать, как будет время
(на это компилятор будет выдавать предупреждение) А для студии 2008 можно прямо так {int переделать_как_будет_время;}
|
|
« Последнее редактирование: 16-10-2010 08:44 от Алексей1153++ »
|
Записан
|
|
|
|
Dale
|
|
« Ответ #19 : 16-10-2010 11:13 » |
|
В С++ почти всегда удается обойтись
да, только иногда на обход надо потратить кучу времени. Проще быстро сделать макрос Так о том и речь: ...если макрос уместен - почему бы и нет? Отдельная песня - отладка этого хозяйства. На прошедшей неделе имел такое удовольствие - пытался использовать драйвер ЖК дисплея для AVR из библиотеки GCC. Почему-то он не желал компилироваться, причем, как и ожидалось, в том самом месте, где макрос на макросе и макросом же погоняет. Само собой, диагностика ошибок компилятора не имеет ничего общего с исходником, который претерпевает несколько трансформаций. На то, чтобы найти причину примерно сотни ошибок, а затем сообразить, как переписать ошибочные макросы, ушло примерно 4 вечера.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
|
Dale
|
|
« Ответ #21 : 17-10-2010 08:18 » |
|
А мне этот фрагмент показался немного странным... Как будто сначала, в давние времена, его полностью написали на макросах. Потом, когда С начал поддерживать функции inline, макросы начали заменять встроенными функциями, но на полдороге почему-то бросили. Вот на этом самом месте выдохлись: /** * list_splice_init - join two lists and reinitialise the emptied list. * @list: the new list to add. * @head: the place to add it in the first list. * * The list at @list is reinitialised */ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head); INIT_LIST_HEAD(list); } }
/** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
До него идут сплошь inline, после - макросы.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
RXL
|
|
« Ответ #22 : 17-10-2010 08:51 » |
|
Как оно было можно увидеть, если взять исходник старой версии ядра. Скажем, 2.2.5 - это примерно 1998-1999 годы. Макрос list_entry не может быть представлен функцией, т.к. у него второй аргумент - имя типа структуры, а третий - имя члена структуры. Тут только возможен макрос. Его задача - по указателю на член типа struct list_head * выдать указатель на структуру, его содержащую. struct test_t { int a; int b; struct list_head *list; int c; } test;
struct list_head *list_ptr = &test.list;
// Исходный код. struct test_t *struct_ptr = list_entry(list_ptr, struct test_t, list);
// После препроцессинга. struct test_t *struct_ptr = ((struct test_t *)((char *)(list_ptr)-(unsigned long)(&((struct test_t *)0)->list))); Тоже самое с циклами. Т.е. к особенностям макросов надо отнести отсутствие типизации. В условиях Си решения типа приведенного списка, по моему, весьма удачны. Ведь списки требуются много где, а работу с ними опили один раз, а не для каждой структуры. Кстати, из-за обилия макросов каждая версия ядра собирается определенной версией (диапазоном версий) GCC.
|
|
« Последнее редактирование: 17-10-2010 08:59 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dale
|
|
« Ответ #23 : 17-10-2010 09:04 » |
|
Точно, при беглом просмотре не обратил внимания, что часть параметров - типы, а не объекты.
|
|
|
Записан
|
Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.
Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard
Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #24 : 18-10-2010 07:53 » |
|
Неплохая реализация списков и очередей для C на макросах - sys/queue.h из FreeBSD, легко портируется - пользовался в linux/windows.
|
|
|
Записан
|
|
|
|
|