| 
			| 
					
						| 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. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  |