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

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

  Все выпуски  

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


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

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


1. Предисловие

Здравствуйте, уважаемые подписчики. Поздравляю вас с Рождеством. В этом выпуске мы начнем обучение на конкретных примерах. Для дальнейшего изучения материала вам понадобится следующий инструментарий:
1. Система GNU/Linux. Подойдет любой дистрибутив Linux с ядром 2.x и выше.
2. GNU-компиляторы gcc и g++. Они входят в состав большинства дистрибутивов Linux.
3. GNU-утилита make. Также входит в состав большинства дистрибутивов.
4. Стандартные библиотеки языков C и С++. Обычно поставляются вместе с компиляторами.

Содержание рассылки предполагает, что вы уже знаете элементарные основы языков C и С++, а также имеете навыки работы в ОС Linux. Если перечисленных навыков у вас нет - не беда - пишите мне на nnivanov@mail.ru и я постараюсь найти для вас подходящие учебные материалы. Я понимаю, что читателями рассылки являются люди с разным уровнем подготовки, поэтому всегда спрашивайте, если что-нибудь не понятно, а я попытаюсь ответить всем.

Если что-то из вышеперечисленного у вас отсутствует, пишите мне на nnivanov@mail.ru - что-нибудь придумаем :).

2. Первая программа

Как я и обещал в прошлом выпуске, начнем с программы, которая генерирует пароли. Подобные программы полезны не только для восстановления забытых паролей :), но и для понимания математических основ некоторых алгоритмов. Настоятельно вам советую не копировать листинги программ из выпусков рассылки в текстовый редактор, а набирать примеры вручную, пытаясь понять смысл каждой строки. Я как и любой человек способен на ошибки и опечатки, по сему не верьте всему, что написано. Лучший способ проверить свои сомнения - это осмыслить.

Итак, откройте любой удобный для вас текстовый редактор и наберите следующий текст. Назовите файл main.cpp.


#include <iostream>
#include <cstring>
using namespace std;

#define BUF_SIZE 3 // Длина пароля
#define LATEST_ITEM 1 // Возвращаемое значение функции nextp()
#define TOP_INDEX 2  // Индекс конечного символа в словаре
#define BOTTOM_INDEX 0 // Индекс начального символа в словаре

// Словарь-диапазон используемых символов
const char* dict = "a-z"; 
char buffer [BUF_SIZE];  // Буфер. Содержит текущий пароль

// Генерирует следующий пароль и помещает его в буфер
int nextp (int); 
void outp ();  // Выводит поток паролей
  

int main ()
{
 outp ();
 return 0;
}

void outp ()
{
/* Очистка буфера */
 memset (buffer, dict[BOTTOM_INDEX], BUF_SIZE); 

/* Вывод паролей, пока функция nextp() не возвратит LATEST_ITEM.
 * Аргумент BUF_SIZE функции nextp() означает внешний,
 * а не рекурсивный вызов этой функции. */
 do {
  cout << buffer << '\n';
 } while (!nextp (BUF_SIZE));
}

int nextp (int n)
{
 int i; 
/* Если не рекурсивный вызов... */
 if (n == BUF_SIZE) {
  if (buffer[BUF_SIZE-1] == dict[BOTTOM_INDEX])  
   { buffer[BUF_SIZE-1]++; return 0; }
         else  { return nextp (BUF_SIZE-1); }
 }
 
/* Смена разряда */ 
 if (buffer[n] == dict[TOP_INDEX]) {  
  for (i = n; i < BUF_SIZE; i++) 
   { buffer[i] = dict[BOTTOM_INDEX]; }
  
  if (n != BOTTOM_INDEX) { return nextp (n-1); } 
/* Сгенерирован последний уникальный пароль */  
  else { return LATEST_ITEM; }  
 } 
 
 buffer [n]++;
 return 0;
}

Теперь полученный файл main.cpp, содержащий исходный текст программы надо откомпилировать и запустить. Для этого выполним следующие команды. Символ # здесь и далее будет означать приглашение командной строки.


# g++ -o main main.cpp
# ./main > passwords.txt

В итоге файл passwords.txt будет содержать все сгенерированные программой пароли. Осталось только разобраться, что же мы делали.

3. Теоретические основы

3.1. Компиляция

Посредником между пользователем и компьютером является операционная система (ОС). Основная задача любой операционной системы - выполнение программ. Грубо говоря, программа представляет собой набор команд, записанных в исполняемом коде. Различные операционные системы содержат собственные стандарты для исполняемого кода. Это основная причина того, что, например, программы для Linux не работают в Windows. Операционная система не понимает естественных (человеческих) команд, равно как и языков программирования. Операционная система понимает лишь исполняемый код и подчиняется ему и только ему. Исполняемый код очень сложный и неудобный по своей сути, поэтому он не подходит для написания серьезных программ. Программы пишутся на языках программирования. Чтобы перевести код, написанный на некотором языке программирования в исполняемый код, используют специальные переводчики - компиляторы. Код программы, написанный при помощи языков программирования называют исходным кодом программы. Файлы, содержащие исходный код программы, называют исходными файлами программы. Файлы, содержащие исполняемый код, называют исполняемыми файлами программы.

В нашем конкретном примере main.cpp - исходный файл, содержащий исходный код (текст) программы, написанный на языке C++; main - исполняемый файл, содержащий исполняемый код программы. Компилятор g++ в нашем примере перевел исходный текст программы из файла main.cpp в исполняемый код, записав этот код в файл main.

3.2. Сборка

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

Процесс превращения одного или нескольких объектных файлов в исполняемый файл называется сборкой (линковкой) программы. Сборка осуществляется при помощи специальной программы, называемой сборщиком или линковщиком. В Linux это программа ld. Возникает вопрос: почему же в нашем примере компилятор сразу выдает исполняемый файл? Все дело в том, что компиляторы семейства GCC (GNU Compiler Collection) являются в Linux де-факто стандартными компиляторами основных языков программирования. Хорошо "подружившись" с Linux эти компиляторы позволяют себе при необходимости самостоятельно запускать некоторые столь же плотно укоренившиеся программы. Таким образом компилятор g++ в нашем примере, сам позаботился о вызове ld и сам удалил уже ненужный после линковки объектный файл main.o (объектные файлы, как правило имеют расширение .o). Тем не менее у нас есть способ разложить все по полочкам; для этого воскользуемся опцией -c компилятора g++.


# g++ -c main.cpp
# ls
main.cpp   main.o
# g++ -o main main.o

В данном случае мы компиляцию и сборку отделили друг от друга. Опять же компилятор вызвал вместо нас линковщик. О том, как самостоятельно пользоваться линковщиком мы поговорим позже, когда начнем изучать библиотеки.

Заключение

Сегодняшний материал не содержит чего-то сверхсложного, однако это фундамент для изучения более важных тем. Программа генерирования паролей написана мною за 10 минут, поэтому не судите строго, если я выбрал не самый быстрый алгоритм: это сейчас не важно. Если в ходе изучения материала возникнут вопросы или затруднения - пишите на nnivanov@mail.ru. В следующем выпуске мы детально рассмотрим исходный код приведенной программы и попытаемся расчленить ее на модули.


Всегда ваш, Николай.
Рассылки Subscribe.Ru
*nix project - новости из мира unix-систем! (ежедневная)

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.linuxp
Отписаться

В избранное