Отправляет email-рассылки с помощью сервиса Sendsay

Программирование и др.

  Все выпуски  

Программирование в Linux с нуля - Выпуск 5


Информационный Канал Subscribe.Ru

Программирование в Linux c нуля. Выпуск 5


Сайт рассылки: LinuxProgrammer Site (http://linuxprogrammer.by.ru)
Автор рассылки: Nikolay N. Ivanov (nn_ivanov@mail.ru)

1. Авторское предисловие


Здравствуйте, уважаемые подписчики. Новый год вдохновил меня на глобальные переделки во всем проекте. При изменениях я старался максимально руководствоваться вашими отзывами и предложениями.

1) Я полностью переделал сайт, отказавшись от скриптов (не считая счетчики), CSS и других "наворотов". Еще много недоделок, но это вопрос времени. Сайт написан вручную на HTML и прекрасно отображается в lynx, а это о многом говорит. Проект сайта пестрит повторениями, но это единственный способ достижения максимальной простоты.

2) То же самое я сделал с рассылкой. Теперь упор делается на простоту и содержание, а не на оформление.

3) Рассылка переведена в раздел "Серебряные", за что спасибо Subscribe.Ru.

4) Раздел 2 (Информация для подписавшихся) больше в рассылке не появится, зато (учитывая ваши пожелания) его содержимое будет опубликовано на сайте в разделе "Рассылка".

5) Бывший раздел 4 (Вопросы и ответы) возможно вскоре перестанет работать в рамках рассылки и перерастет в Linux-FAQ сайта. Это позволит акцентировать большее внимание на разделе "Программирование в Linux".

Хотелось бы услышать ваши мнения по поводу данных изменений.

2. Программирование в Linux

2.1. Разбор домашнего задания

Домашнее задание 4.1:

Что в языке C++ делает функцию уникальной? Варианты ответов:
1) Только имя
2) Имя и тип аргументов
3) Имя, тип аргументов и количество аргументов
4) Имя, тип аргументов, количество аргументов и порядок следования типов аргументов
5) Имя, тип аргументов, количество аргументов, порядок следования типов аргументов, тип возвращаемого значения

Является ли выбранный вами ответ правильным для языка C?


Разбор домашнего задания.

Правильный вариант ответа на первый вопрос - 4. Я не просто так задал это домашнее задание. Очень скоро мы начнем использовать это явление языка C++. А явление это называется перегрузкой функций.

Рассмотрим пять прототипов функций языка C++:

1) int func (char, double);
2) int func (double, char);
3) int func (char);
4) int func (int);
5) double func (int);

Первые четыре прототипа различаются между собой по типу, количеству и порядку следования аргументов. А пятая функция конфликтует с четвертой, поскольку имеет с ней общее имя, тип аргументов, количество аргументов, и порядок следования аргументов. Отбросив пятый прототип можно смело сказать, что все четыре функции "уживутся" вместе в одной области имен языка C++. То есть мы можем определить все четыре функции, задать для каждой из них свои механизмы работы, и вызов той или иной функции с именем func будет зависеть от передаваемых фактических аргументов. В таком случае мы говорим, что функция func перегружена.

Однако здесь не обошлось без подводных камней. Тип char в компьютере представляется в виде целого числа. Поэтому вызов

a = func (10);

может использовать как третий так и четвертый вариант перегруженной функции func. Проблема легко решается использованием приведения типов (type promotion), однако важно вовремя увидеть надвигающееся грозовое облако, чтобы потом не просиживать ночами под отладчиком.

Что касается языка C. Здесь нет понятия перегрузки функций, поэтому любые две функции с одинаковыми именами, находящиеся в одной области видимости будут конфликтовать друг с другом и программа не скомпилируется. Вспомните "парочку" abs() и fabs() и все неудобства, связанные с их использованием. Чтобы лучше вспоминалось, вот вам домашнее задание.


Реализуйте на языке C++ функцию с именем xabs, возвращающую абсолютное значение числа. Перегрузите функцию для целого аргумента и для аргумента с плавающей десятичной точкой. Для реализации используйте abs() и fabs().
Домашнее задание 5.1

2.2. Использование утилиты make

Профессиональный программист должен уметь обеспечить себя таким инструментарием, который позволяет сосредотачиваться не на формальностях, а непосредственно на программе. Однако современные средства разработки настолько зацикливаются на этом условии, что забывают про самое главное: программист должен понимать все, что происходит с его проектом, а не полагаться на автоматику. Утилиту make в этом плане можно смело назвать гениальным творением рук человеческих. Дело в том, что эта утилита существенно облегчая процесс разработки позволяет в то же время программисту четко понимать, что он делает.

В качестве примера возьмем программу нахождения среднего арифметического квадратов двух чисел из предыдущего выпуска рассылки. Компиляция и сборка этой программы включает в себя четыре этапа. Использование "ручной" компиляции и сборки каждый раз, когда мы изменяем исходные файлы, значительно замедляет процесс разработки. В понедельник я сдаю в эксплуатацию программу (среднего масштаба), процесс компиляции и сборки которой проходит в 24 этапа. Существуют проекты, в которых количество этапов компиляции и сборки исчисляется сотнями. Утилита make элегантно решает эту проблему. Если изложенный ниже материал слишком сложен для вашего восприятия, начните с практической части. На самом деле здесь нет ничего сложного. Просто эту тему тяжело объяснять доступным языком.

Утилита make вызывается из командой строки следующим образом:

|$ make [опции] [имя_цели]

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

По умолчанию make ищет в текущем каталоге файл с именем Makefile. Для каждого проекта создается свой Makefile. В этом файле даются инструкции для сборки проекта. Makefile составляется "вручную". Он содержит описания следующих конструкций:

1) Целевые модули
2) Зависимости
3) Правила сборки

Рассмотрим на текущем проекте, что есть что. Итак, целевые модули - это то, что нужно получить (включая промежуточные этапы). Мы должны получить исполняемый файл main. Вот первый целевой модуль. Для получения исполняемого файла main необходимы объектные файлы sqr.o, mid.o и main.o. Изначально у нас их нет, значит это тоже целевые модули (только промежуточные). Теперь посмотрим, что от чего зависит. Чтобы получить исполняемый файл main, нам нужны файлы main.o, sqr.o и mid.o. Следовательно, целевой модуль main зависит от перечисленных файлов. Чтобы получить файл main.o, необходимо иметь файл main.cpp (он не является целевым модулем, поскольку существует изначально) и файл head.h, включаемый при помощи директивы #include в файл main.cpp. Аналогично для sqr.o нужны sqr.cpp и head.h. По такому же принципу для mid.o нужны mid.cpp и head.h. Вот мы и определили зависимости. Что касается правил, так это обычные команды, которые будут вызываться в командной строке для получения целевых модулей.

Если при вызове утилиты make не указан целевой модуль, то в качестве цели берется первый целевой модуль, указанный в Makefile. Использование зависимостей позволяет автоматически вызывать правила сборки всех целей, от которых зависит текущий целевой модуль. То есть вызывая make для цели main, в силу существования зависимостей будут выполнены правила сборки для модулей sqr.o, mid.o и main.o, от которых зависит модуль main.

Теперь посмотрим, как это все прописывается в Makefile. Здесь синтаксис простой:

ИМЯ_ЦЕЛЕВОГО_МОДУЛЯ: ЗАВИСИМОСТИ
ПРАВИЛА_СБОРКИ


В качестве имени целевого модуля обычно пишут имя получаемого файла, хотя можно указать любое другое имя. После двоеточия через пробел указываются зависимости. Зависимостями могут быть имена файлов (исходные файлы, заголовочные файлы и т. п) и имена целевых модулей. В последующих строках прописываются правила сборки. Каждому правилу должна предшествовать табуляция.

Вот как будет выглядеть Makefile для нашего проекта:

# Makefile for SQR-project

main: main.o sqr.o mid.o
    g++ -o main main.o sqr.o mid.o

main.o: main.cpp head.h
    g++ -c main.cpp

sqr.o: sqr.cpp head.h
    g++ -c sqr.cpp

mid.o: mid.cpp head.h
    g++ -c mid.cpp


Наша главная цель (исполняемый файл main) стоит на первом месте в Makefile, поэтому вызов make можно осуществлять без параметров.

Из примера видно, что комментарии в Makefile однострочные (заканчиваются символом переноса строки) и начинаются с символа # (диез, он же хэш, он же кранч, он же шарп, он же сетка, он же решетка :-)).

Возможно вам поначалу покажется, что ничего удивительного утилита make не делает. Однако продолжая погружаться в мир Linux-программирования вы поймете, что это гениальная и незаменимая вещь.

В последующих выпусках рассылки мы рассмотрим утилиту make и синтаксис Makefile'ов более подробно.

3. Вопросы и ответы


Вопрос 3.3
Прислал: Igor (ebeb@front.ru)

Здравствуйте!

Хотелось бы хорошего описания (с примерами 8)) функций printf и scanf или как там её 8)

Ответ 4.
Прислал: Sergey Beloshitsky (snowman@ukrpost.com.ua)

Еще, например, если хочеш вывести дробное число то можеш написать %.3f - выведет число с тремя знаками после запятой, просто написал, потому, что сам в свое время удивлялся почему это double нормально не выводится по %d

Спасибо за внимание.
Nikolay


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное