CFA LogoCFA Logo Computer
Загрузка поиска
Новости Компьютеры Прайс-лист [Новое] Прайс-лист [Б/У] Для ноутбуков Конфигуратор ПК Заказ, Оплата, Доставка Сервис объявления Драйвера Статьи Как нас найти Контакты
Новости
RSS канал новостей
То, что энтузиасты ждали так долго, наконец-то случилось, и компания NVIDIA анонсировала свой новый ...
Официальный анонс графического ускорителя GeForce GTX 1080 Ti состоялся 1 марта, и партнеры NVIDIA ...
Компания ASRock представила мировой общественности материнскую плату H110-STX MXM, которая рассчитана ...
Компания MSI в рамках серии Arsenal Gaming представляет пользователям материнские платы линейки ...
По данным наших коллег, в этом месяце компания Huawei официально представит свой новый смартфон. ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2003 ГОД

Язык, на котором говорят везде

Тихон ТАРНАВСКИЙ

Этот цикл статей будет представлять собой нечто вроде базового учебника и одновременно практического руководства по языку Си. Я постараюсь описать не только конструкцию языка, но и всевозможные прелести и особенности его применения. Надеюсь, это тоже будет вам полезно, по крайней мере именно этого мне самому не хватало при изучении Си. Конструкциями во всех учебниках пичкали сколько влезет, а как толково с ними работать — не объясняли.

Ты проси иль не проси — расскажу тебе про Си

Я ни в коем разе не претендую на «последнюю инстанцию», а рассуждаю со своей, местами крайне субъективной точки зрения. Разделять мои предпочтения или не разделять — дело ваше. Предназначается это руководство не только «не-программистам», решившим стать на путь Си, но и, возможно, тем, кто пишет на чем-нибудь другом, но захочет перейти на Си (может, именно в результате прочтения данного материала). Предвижу саркастические замечания некоторых «неСИльных» программеров в духе «а зачем мне вообще твои Си? Если я на своем родном [Паскале, Вижуал Басике и т.п., нужное подчеркнуть] нормально программулины бацаю». Посему, как и полагается, начнем с вводной части.

0. Зачем вам вообще

Если вы хотите писать софт под Вынь32, то замечу, что сами мелкомягкие сейчас активно продвигают свой VisualStudio, а заглавным его компонентом, по их собственному признанию, есть не VB и не VFoxPro, и даже не VJ#, который собственно, продвигается в основном «в пику» Sun, а именно VC++.

Ну а от Борланда на сегодняшний день кроме C++Билдера остались одни Дельфы, на которых, по-моему, многие сейчас пишут просто потому, что в школе (институте) учили Паскаль, а сейчас лень переучиваться. Да и сам Борланд уже далеко не на гребне. О нем в последнее время слышно все реже.

Ежели вы — линуксоид, то в этом случае вам Си знать просто необходимо: любой софт, начиная с ядра системы, пишется на Си, и большинство его распространяется в исходных кодах. Так что в Линуксах Си — это как воздух. Учитесь им дышать — и вы сможете при желании перекроить под себя хоть всю систему или просто добавить пару своих фич в любимую программу.

Я как компьютерщик родился в старенькой UNIX-подобной системе и свое первое «Hello, world!» сказал именно на сях. И, думаю, для очень многих юниксоидов этот язык — родной. Но я все же постараюсь не привязываться ни к какой конкретной операционке или архитектуре, а дать, так сказать, «интернациональный» подход.

Что творится на этот счет в мире Яблочных Маков, не знаю, но, согласитесь, это темка несколько не для нашей страны, ввиду «неподъемности» таких систем для кошельков большинства наших соотечественников. Да и вряд ли вы под них написать-то что-то сможете, ибо архитектура у них — закрытая, и система — закрытая, и вообще предъявите пропуск, pleezz!..

Что же касается мультиплатформенности, то к примеру те же МелкоМягкие заявили не так давно, что (цитирую новостную ленту МК №34(205)): «в Visual Studio Everett существенно переработан компилятор Visual C++, что позволяет с легкостью портировать исходный код в (и «из» — прим. мое) компиляторы C++ для UNIX-совместимых платформ». Представляете, может, в ближайшем будущем будет так: наваял программу на сях, засунул в два компилятора — получил на выходе два бинарника, один запечен под Винду, второй — под Линукс (или вообще UNIX/Sparc)! Благодать...

То, что «сами» уделяют столько внимания Си++, подчеркивает, что и в мире win-софта Си уже постепенно становится стандартом. Что же до Солнечной Явы, активно продвигаемой как платформенно-независимый язык, то напомню, что Ява — язык некомпилируемый, то бишь как ваша программа пойдет на той или иной «платформе», зависит от всех глюкобагов конкретной виртуальной машины, заточенной под эту платформу. То есть, когда вы пишете на компилируемом языке, вы сами компилируете свою программу под каждую машину и видите, как она на этой машине запускается. В случае же с Явой вам вроде бы гарантируют, что писанный вами софт пойдет на любом железе, в любой ОСи, но даже если вы увидите, как именно ваша программа идет в этой ОСи, все может измениться с выходом новой версии виртуальной машины.

Знатокам других языков могу еще добавить, что каждый язык особенно хорош для каких-то своих задач. Так что разные по функциональности софтины (а то и отдельные части одной и той же) выгодно писать на разных языках. Один ориентирован на работу с данными, другой — на локальные сети, третий — на Инет, четвертый — ... Что-нибудь интерфейсное проще и удобнее написать, скажем, на Яве или на Перле, а что-то критичное по скорости (кстати) — на Си (про Асм я, конечно, молчу, хоть все же чистый Асм — это для маньяков). Так что сейчас выгодно быть полиглотом.

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

Обо всем об этом и о многих других «вкусностях» мы еще с вами поговорим подробнее, но уже не сегодня. А сегодня начнем с азов.

1. С чего начинается родина.

В сях, как и в любом ЯВУ (языке высокого уровня то бишь) — что есть основополагающим для любой программы? Конечно же, типы (хоть я и писал, что без типов можно иногда и вообще обойтись, но это все же скорее исключение).

Сразу оговорюсь, что я (по крайней мере пока) буду писать о «просто Си», так как надо сначала как следует прощупать основу языка, в которой, собственно, сокрыта основная его мощь, а уж затем переходить к плюсовым наворотам, ибо иначе эти самые навороты могут заслонить собою нечто более сильное, хотя и простое.

Итак, типы.

void. «Это тип пустой, он предмет простой, он никуда не денется», перефразируя медведя из известного мультика. И, надо сказать, в Си пустой тип, действительно, «гораздо выше ценится». Во-первых, в сях нет такого понятия как процедура; в роли процедур выступают «пустотипные» функции. Во-вторых, функции без аргументов на самом деле принимают в качестве аргумента тот же самый void. Ну и третье, пожалуй, самое важное — это указатели на void. Это не «указатель на ничего», как могло бы показаться, а наоборот — «указатель на что попало», то есть указуемый объект может быть вообще любого типа! Вообще, указатели в сях — довольно мощная штука, и я им посвящу скорее всего не одну статью — но это, опять-таки, не сегодня (насчет непонятного слова «указатель» и вообще всего непонятного, что будет встречаться в тексте: наберитесь терпения, в следующих выпусках я обязательно все подробно объясню, ибо если объяснять все по ходу, то будет только большая путаница).

Целочисленные типы. Сюда относятся: char (однобайтовый), short, int (от 2 до 4 байт, в зависимости от конкретного компилятора), long (обычно в два раза длиннее, чем int), иногда мне встречался тип long long (вдвое длиннее long’а). Тип short обычно, как и хочется думать, короче, чем int, но длиннее, чем char. За исключением тех компиляторов, где int — двухбайтовый. Действительно, не может же он быть длиннее, чем байт, но короче, чем два... Так что в таких компиляторах short равен двум байтам и, соответственно, вообще не нужен, так как дублирует int.

Кстати о компиляторах. Я намеренно говорю «компилятор», а не, как сейчас принято, «среда разработки», ибо в Linux/Unix такое понятие как «среда» зачастую вообще отсутствует. Большинство штатных текстовых редакторов умеют подсвечивать синтаксис, запускать выбранный компилятор и даже устанавливать курсор на строку, в которой компилятор обнаружил ошибку. Так что понятие «среда» часто заменяется связкой редактор-компилятор. Это на самом деле очень удобно, так как не заставляет вас устанавливать свой, встроенный в среду редактор для каждого компилятора. У меня, например, в одном редакторе настроена подсветка синтаксиса и для C/C++, и для Lisp’а, и для perl’а, и для shell’а.

С «плавающей» точкой. Тоже разных размеров; здесь все размеры зависят от компилятора. Самый маленький —float, double (обычно — дважды float), long double, иногда встречаются long float (нечто среднее между double и long double) и long long double (еще более long, чем long double).

Символ — char. Вы где-то это уже видели? Действительно, в сях байтовое целое и символ — это одно и то же (не в Си++ — там появился паскалевский тип byte). Ведь действительно, в памяти эти типы хранятся совершенно одинаково. А при вводе-выводе в сях все равно везде присутствует явное форматирование (грубо говоря, вы каждый раз сами указываете компилятору, какой именно тип вы сейчас собираетесь печатать). Опять же, в Си++ есть ввод-вывод без явного форматирования — так вроде бы быстрее. Хотя я, честно говоря, не понимаю, зачем экономить десятки тактов процессорного времени в век, когда специально пишутся тяжеловесные проги, гораздые нагружать современное железо (тем паче, экономия-то при нынешних мощностях меряется на милли-, а то и микросекунды). А в целочисленности символов есть свои плюсы. Как вам, к примеру, вот такой UpCase: if(x>=’a’ && x<=’z’) x=x+’A’-’a’? Можно бы и еще короче, но не хочу забегать наперед.

Строки как отдельного типа в Си, в принципе, не существует, и в этой ипостаси может выступать символьный массив, хотя на практике все же используется символьный указатель; посему к строкам перейдем позже, когда будем подробнее говорить о массивах и указателях.

Знаковые модификаторы —signed и unsigned. Тут все просто. К примеру, unsigned char принимает значения от 0 до 255, signed char — соответственно от -128 до 127. Если префиксы signed/unsigned не писать, используются настройки по умолчанию. Обычно для char —unsigned, для всех остальных —signed, но в большинстве компиляторов есть опции, позволяющие эти умолчания менять (иногда только для char, иногда для всех).

Кстати, иногда (читай — в некоторых компиляторах) размеры типов зависят от модели памяти. Например, так я видел в одном ДОСовском компиляторе (запамятовал, в каком): модели Tiny и Small — размер типа int равен двум, модели Medium и Large — равен трем, Huge — четырем. В других компиляторах от модели памяти зависит только возможность использовать far-указатели (за пределы сегмента).

Со всеми упомянутыми типами вроде бы никаких премудростей, так что о них мы больше говорить не будем. А вот на следующих двух впоследствии остановимся подробнее.

Массивы. Одномерный массив — это понятно: как и везде, просто последовательность однотипных элементов. Двух-, трех- и т.д.-мерные массивы в сях реализуются за счет вложенности. То бишь, двумерный массив — это массив массивов, трехмерный — массив двумерных и т.д. За счет этого с каждой строкой, скажем, двумерного массива можно обращаться как с отдельным одномерным массивом (для дельфистов-паскалистов: это как если бы вы написали не ‘array [1..n][1..m] of что-нибудь’, а ‘array [1..n] of array [1..m] of что-нибудь’).

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

О массивах, об указателях и о взаимодействии указателей с массивами и с пустым (void) типом мы поговорим подробнее после того как познакомимся с базовыми конструкциями языка.

(Продолжение следует)

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы: *
captcha
Обновить






Рейтинг@Mail.ru
Хостинг на серверах в Украине, США и Германии. © www.sector.biz.ua 2006-2015 design by Vadim Popov