Искусство программирования на Си (984073), страница 10
Текст из файла (страница 10)
Наиболее вероятным результатом будет вылача приветствия всему миру: на станлартное выводное устройство, но нет абсолютной гарантии, что фактически будет сделано именно это. Для этого есть две причины. Первая состоит в том, что функция некорректно специфицирует !наш () как возврашаюшую тип чо(б; в языке С функция шаш () должна возврашать тип ш(. Второй причиной является тот факт, что функция рпп(Г была вызвана без полного прототипа для ее введения в область видимости. Итак, эта программа может хорошо работать на вашем компьютере.
Но это не означает, что она булет работать на том компьютере, на котором вы ее скомпилируете. Это не означает также, что программа будет работать на другом компиляторе, даже если он предназначен для той же самой операционной системы. Фактически это даже не означает, что программа будет ра- Если вы хотите избавиться от случайных символов между обрашениями к зсап(, можете сделать это следуюшим образом: рг1псе (" Введите возраст: ") г (11ваЬ [вкбоке)1 всал1( Вб , аа9е); /' Лолучевве возраста от пользователя */ рг(ве( ( Введвте размер обуваз ); 111нзЬ (всбопс)! звала (" Ъби, авноевззе) г /* Обратите внимание ва лэщмрузмвгй пробел */ (Как вы видите, я принял возможность продемонстрировать, что вы можете переносимо собрать ввол на той же строке, что и предыдуший вывод, разумно использ)я ф)'нкцию (йцзЬ ().) Фактически лучше не использовать функцию зсап( О лля интерактивного получения данных.
Она предназначена лля чтения форматированных данных из з(б[п, и человечества не нашло лучшего источника форматированных ланных. Использовать зсап(() намного лучше, чо16 Иахе81г1вчбррегпаве(сЬаг 'в) ( мЬз 1е [ ив ) ( вв = сопррег([пвв(чав сЬаг)'в)1 ++з; ) ) динудирование строки Ниже показан обычный прием, используемый для об- мена значениями двух целых чисел без участия времен- ной промехсуточной переменной: Этот прием может выглядеть очень мило, но пользоваться им корректно невозмозкно. А вот еше один часто используемый способ: конов С.
Лучшее и более ясное решение получается с использованием временной переменной.) Мною лично засвидетельствованы два наиболее драматическия результата неопределенного поведения, и оба они были связаны с отведением недостаточной памяти з массиве сйаг для завершающего нулевого символа строки. Первый случай произошел в 1989 году, и его жертвой был мой брат Стив. Однажды он привлек мое внимание к экрану с отображенным на нем сообщением, в котором его совЕршенно неожиданно просили подтвврдить, что он желает форматировать свой жесткий диск. Он был счастливчик — его спросили. Год ипи около того спустя мой коллега (его звали Кевин) оказался не таким везучим. Первым знаком неопределенного поведения его программы было то, что его компьютер стал "зависать".
Вторым знаком было то, что он не перезагружался( После этого ему пришлось потратить много времени, чтобы устранить неполадки, используя диагнезстические гибкие диски, поставляемые производителем. Пересмотренный язык С Часть 1 Войны гтандарггюе яро гЗюимироаонит аринина а ути леремириа $ РОО (оо = (О); Глава 2 С против С++ сЬаг 'Р; сЬаг ч(1 = Ье11о гаг 11 ргьпея("Ъеззп", аяое.а) Макросы вьпс1пде <вельо.ь> 1пг аагп [еп10) Когда мы обращается к типу ш(, мы можем применять те же рассуждения.
Значение 1)з)Т МАХ должно быть равным по крайней мере 32767 (а значение НУ)Т М1Х соответственно должно быть не более- 32767), как мы знаем 1п( имеет длину по крайней мере !6 битов. В более старых операционных системах (н никогда — в операционных системах, находящихся в режиме эмуляции для поддержки программного обеспечения от более старых систем) тип ш( обычно, но не как правило, имеет ллину 16 битов. Ни в одной операционной системе (и( не может иметь длину 32 бита. Однако было бы не совсем правильно жестко фиксировать эти величины. В этом мире обязательно найдется по крайней мере олин компьютер (типа Сгау), который использует 8 битов лля типа сйаг и 64 бита для вйог(, 64 бита для (п( и 64 бита для типа )опй.
Моя точка зрения состоит в том, что этот код р = (сваг е)а(оо; Гсг(Р = ь(оо.а, ! = 0; Ч(1! г= 10, з++ ++) 'Р = ч(11! еще далекого от того, чтобы быль укасным, стандартом не предусмотрено абсолютно никаких гарантий, что он напечатает ойе)1о". Вы долзкны особенно остерегаться заполнения структуры, когда осуществляется обмен данными между двумя компьютерами, которые вполне могут использовать различные стратегии выравнивания данных.
С и С++ являются различными языками и предназначены для различных людей. С вЂ” это процедурный язык, в то время как Се+ — язык объектно-ориентированный. Те знания, которые делают вас хорошим С-программистом, могут оказаться препятствием в обучении эффективному программированию на С++. Аналогично С++- программисты иногда находят затруднительным переход на язык С. Достигнуть мастерства в использовании обоих языков можно, но это значительно труднее, чем вам может показаться. Спорить о том, какой из этих языков лучше, конечно, бесполезно.
Языки различны и имеют различные достоинства и слабые места. Те, кто твердят, что С++ лучше чем С, неправы. (Я не являюсь противником С+~-; я большой фанат редактора Се+ Вц!!<1ег, который сочетает скорость раз- 1пс ва1п(оо10) ( сЬаг *р = ва11ос(1024)Г 11(Р) ( всгсру(Р, "Ве11о ыог14.") реглер( Ьв(п , р); Ггее(р); геспгп 0; ) является вполне законным С-кодом, но под управлением С++ вы получите диагностическое сообщение, поскольку конверсия то(4 * в функции шайес вернет значение к типу сЬаг '.
Так что дам вам один мудрый совет: при использовании таких комбинированных компиляторов уделите особое внимание определенному по умолчанию расширению файлов. ( работки %!пз)озоз и высокую эффективность программ Оптичизацил г Глава 3 Оптимизация В ЭТОИ ГЛАВЕ Майкл аи Важность измерений х- " „;„' ", ' О;;:Ь"' хс," ' ',,' ', ...,.З":,Аоста 'Ы,С'".'„,, " '"' ют,',.', ";" * '' ' ХХ; ';~ ,г" ю х) ° ".
';, '; "„.'"".' ' " ( з .;,;„'.,;;. г;,'. ," -,, -.:-".. ";ч г,"-'ьт ф",',:-,' ,з' '"', т" ',,'.~"',,"',.'и,,'-,,-'з г'.,* ,;"; „': ";",'-:.-,-'„':=,,-", с б,:-',-'!;:,':,,"::;;:. =)"„"„,.!"'",. г," 'ь( ,-',:"-,.':==а.'~::.Гв,"„'",:-';-".,",) -;и ьг)зь:~",:,'.л:,~з,:К ы;,' ...„, г, .„:,, "..." '..." г,1~ ~ -'. --".:"ГГ";"",,'-.,-".'.-.::.;з;;:.,:,,~„',:-:: й:;гх'-*. х„"ч гт.'.;,",:".сбз .а "ь:"...'Ач '; .„,)х" я';'.,'.,:;;,! „";-."'~, ':."зэ , ",;,":": ад,;-,'~:.',~',"."', К т::-г ьт,.г ".'.л,,,:::;:;":,";3'г с.';"": зт.'-:, ',;, ьи '"~;.в",,".'.ВГ,-":." ": '.=.„,,;-„""т г,"!..',.:: -",г..., 1~ ,',,;,:;,".,,;;",=.--' - Рх к" »"- „:;-;";"--".":,." ",:ь( ~;,,'.,'~ '.;;".';-";:, ';-*ах и яа - „" ~;ьг;;*:.-;$'„,':...",ь',,"„',.'„"-.-'"„,-,"::-,~; Ё'.,".,""'.:-*" ".' Ъз ' ", ,;;.";с",е,хк Р,, и,""~т с; ' ж,;;~.цэ~,::,оз'~-' :-:„з ...*.""'-: ',"тз о..'г '": ' '!~ "" и э 'ь( а ",д," ьь, - ' ",,''.,)а ', , л,.'-:;,тл~.;з"',"",:„"" „'„Р„*'т.':.
~з) й ,":.-"Ь,;",)зх...,„,","-".;-.'."','-".. -.'-;хе", "' '.';,ч„':,'„,.'з '."„%" лс~~; %'-.": " ",.л ...," -;-,""""~„,; ~"'., ' )ч ',к,, ', 'х' .".;.,"" '~. а 3-", -;";:..,":. -,'~ г),, " '; ' ''г ' '";„", зьх К ' ",,"' ь)з ье) -*,.(. ц'," ' ' ',' '" г ' ~',":,'-,,,~,',х:;~,.:,ь СТ .
'' з' ч :...),;:г.ь::,)':";: ~,""" „'.;: ° Привлекательность оптимизации ° Размышления об эффективности ° Профайлинг ° Алгоритмические стратегии оптимизации ° Кооперативная и параллельная оптимизация ° Когда оптимизация не нужна С тех пор как появились вычислительные машины ведется непрестанная работа по повышению их быст внимание принималось даже время суток работы на вычислительной машине. индексация массива и переадресация прямо отображаются в простые машинные инструкции на этих регистрах.
Конечно, когда вы используете более сложные типы, такие как списки и многомерные массивы или библиотеку более хитроумных функций, таких как йзогГ, вы более не мо:кете ожидать, что будет поддерживаться однозначное отобрахение конструкций языка С на машинный уровень. Но вы обнаружите, что в С переход от простых типов и операций к более сложным типам и операциям осушествляется очень постепенно, и всякий раз, когда это возможно, особое значение придается эффективности. Стандартная библиотека С и включенные в нее файлы содержат несколько свойств лля повышения производительности: ° Функции библиотеки зтббо используют буферизированный ввод и вывод. Многие функции, записываюшие информацию в эти буферы, могут использоваться в качестве макросов (такие, как рвтс и йе(с), пиляции.
Только РОКТКА(ч в свое время получал подобное внимание со стороны авторов компиляторов, Конечно, поскольку вычислительные машины баз данных и выходные буферы разделены и используются совместно, другие языки тохе выигрывают от такого внимания, но некоторые конструкции (такие, как неформатированный ввод/вывод и машинно-ориентированная оптимизация функций рыит и гяешсру) просто не могут быть доступны из других языков. В конечном счете скорость является строго количественно измеримой величиной. Каждый виток автогонок, каждый марафонский пробег и кажлый заезд бобслея находятся под беспристрастной опекой секундомера.
Но возможности секундомера очень ограничены — он измеряет только время вашего прихода на финишную черту. Мы, программисты, благословенны изобретением инструментов прсфилирования (ргоГ1!(пй). Мы мохем Окяякяязаияя фифа Глава З $ЙВ язик С Базовые операции в абсолютных единицах занимают исчезающе малое время, но, сравнивая их друг с дру1ом, мы видим, например, что деление целых чисел требует в 7 раз больше времени, чем их сложение. Среди операций с экстремальными значениями времени выполнения выделяется очень медлительная функция торец, а функция эуэ(еш выполняется просто неимоверно долго! О-НОТВЦИЯ Иерархия паняти и ее влияние на эффективность Первая подсистема, которой мы коснемся, — это иерархия памяти.