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

Программирование для начинающих #29


Служба Рассылок Subscribe.Ru

Программирование для начинающих

Выпуск 29

25 NOV 2001

 
 
 
Ведущий рассылки: Вячеслав Мацнев
e-mail: stac@stacmv.net
Good day, dear subscribers!

В этом выпуске читайте:

ОТСЕБЯТИНА .::. К вопросу о хорошем стиле

К вопросу о хорошем стиле мы возвращаемся, когда задаемся другим вопросом: для чего или для кого мы пишем программы?

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

Иногда мы пишем программы для компьютера, а иногда мы пишем программы для людей и эти программы не предназначены для работы на компьютере.

Сюда можно отнести различные домашние задания по курсу информатики или программирования в различных учебных заведениях. ДЗ по нашему курсу "Программирование для начинающих" (http://stacmv.boom.ru/edu_dz_idx.html) тоже относятся к этой категории.

Программы, которые студенты курса пишут в рамках выполнения ДЗ предназначены для чтения человеком (я - человек). На компьютере они, конечно, должны работать правильно, но специально для этого не предназначены.

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

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

Поверьте читать код нелегко, даже свой. А читать его приходится часто. Почему? Чтобы исправить ошибки или просто добавить новые функциональные особенности (features) или "фичи" в программу.

Читать чужой код приходится в целях самообразования, а также модернизации и исправления ошибок. Существует множество программ, распространяемых по лицензии GPL. Исходный код таких программ всегда доступен и разрешена его модификация. Также на работе где-либо может понадобиться модификация программ написанных вашим предшественником или сторонним наемным программистом.

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

Чтобы программы было легко читать их надо писать, руководствуясь некоторыми правилами, совокупность которых называется стилем программирования.

Иногда эти правила могут быть четко определены, вплоть до того, что они могут быть оформлены в виде документа. Но часто это некоторые негласные правила, соблюдение которых остается на совести, что ли, программиста.

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

Например, программисты Microsoft и программисты, использующие продукты этой конторы дают такие имена переменных, которые, кроме всего прочего, указывают на тип переменной (intNumber, strName). Так делают не только "микрософтовцы", потому что это часто бывает очень удобно при чтении кода: использование переменной и ее объявление может быть в разных частях текста программы, и если бы имя ничего не говорило о типе, то пришлось отвлекаться на определение типа переменной.

Некоторые правила могут относиться к конкретному языку, т.е. соблюдаться программистами на одном языке и не соблюдаться остальными.

Я имею в виду так называемые идиомы. Идиомы существуют в языках программирования также как и в обычных языках. Это устоявшиеся приемы для выражения определенной мысли или идеи.

Например, приветствуя друг друга, мы обычно говорим "Добрый день", "доброе утро" или "добрый вечер". Но выражение "доброй ночи" используется в основном при прощании.

В английском языке для приветствия есть свои идиомы: "good morning", "morning", "good evening", но не "good day". Я поздоровался с вами, используя последнее выражение, что наверняка выдает во мне иностранца (не британца). Естественно лучше использовать общепринятые (среди британцев) выражения при использовании английского языка.

В языках программирования идиомы это устоявшиеся приемы, используемые опытными программистами для написания типичных фрагментов кода, таких как опрос клавиатуры, перебор элементов массива и пр.

Если вы владеете этими приемами, то сможете легко понимать код программистов, тоже владеющих этими приемами, а другим будет проще понимать ваш код (другим и вам самим, спустя некоторое время после его написания).

Мне не известно, есть ли где-нибудь сборники устоявшихся приемов для конкретных языков. Поэтому я советую вам внимательно следить за примерами программ, публикуемых в рассылке. Я не претендую на ведущую роль в разработке идиом для Бейсика, однако, если вы освоите те приемы, которые применяю я в тех же примерах, то наше с вами взаимодействие станет более эффективным. Вы станете лучше и быстрее понимать мои примеры, а я стану лучше и быстрее понимать ваши программы, написанные в рамках ДЗ.

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

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

Бесконечный цикл можно реализовать множеством различных способов. Вот некоторые из них:

1)
  FOR i=0 TO 2
  ... тело цикла ...
  i=0
  NEXT I

2) DO UNTIL ("a"="b") ... тело цикла ... LOOP

3) DO ... тело цикла ... LOOP UNTIL 0

4) DO WHILE 7>2 ... тело цикла ... LOOP

5) DO ... тело цикла ... LOOP WHILE 1

Я показал лишь пять примеров. Вы понимаете, что меня параметры условий завершения циклов (буквы и цифры), можно получить тысячи, а то и миллионы способов реализации бесконечного цикла.

Встретив в программе один из таких циклов, придется потратить кучу времени на то, чтобы понять, что, скажем, "a"="b" и 7>2 не несут определенной смысловой нагрузки, а всего лишь определяют условие, которое никогда не будет выполнено (в первом случае) и условие, которое выполнено всегда (во втором).

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

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

Вообще, любой необычный или, скажем, нетрадиционно написанный фрагмент программы может свидетельствовать о трех вещах: 1)его написал начинающий, еще не опытный программист, не знакомый с устоявшимися приемами; 2)фрагмент потенциально содержит ошибку (слово "потенциально" здесь означает, что ошибка проявляется уже сейчас, либо проявится позже при модернизации программы); 3) фрагмент реализует один из основных алгоритмов данной программы, оптимизирован для каких-то целей и т.п., и, следовательно, его необычный вид обусловлен действительно серьезными причинами.

Кстати номер 2. В цикле FOR использована переменная i. Это тоже является идиомой. Если программист использует другое имя для переменной цикла, то либо он начинающий, либо имя переменной имеет какой-то особый смысл. Например, x может использоваться для обозначения горизонтальной координаты, code - для обозначения некоторого кода. Если смысл переменной цикла в данном контексте не важен, то рекомендуется использовать i.

Кстати номер 3, использование определенных имен для определенных переменных тоже можно считать идиоматичным. Например, i, j, k, n, x, y, z - это наверняка числа, а ch, str - символ и строка соответственно.

x, y, z используются для обозначения координат, i, j для нумерации элементов массивов (векторов и матриц). n часто используется для обозначения общего числа элементов, тогда как i обозначает текущий элемент.

  n=10
  FOR i=0 TO n
  ...
  NEXT i

Другой типичный фрагмент кода это опрос клавиатуры с целью определения нажатой в данный момент клавиши.

Переменная, которая хранит символ соответствующий нажатой клавиши, чаще всего называется (читай "переменную ... лучше называть") ch$ или ch (если она определена AS STRING). К слову, программисты на Паскале тоже предпочитают назвать эту переменную ch, тогда как программисты на Си больше любят c("цэ" или "си"). Объясняется это очень просто: слово "символ" по-английски пишется как "character".

Опрос клавиатуры может преследовать одну из следующих целей:

* определение клавиши, нажатой в данный момент;
* ожидание нажатия наперед заданной клавиши (при этом выполнение программы может быть приостановлено).

Первый вариант наиболее часто используется для управления программой. В этом случае запускается бесконечный цикл, в котором осуществляется опрос клавиатуры и принятие решения о выполнении какого-либо действия на основе нажатой клавиши. Вот пример реализации такого фрагмента кода:

  DIM ch AS STRING
  DO
    ch=INKEY$
    IF ch=CHR$(27) THEN EXIT DO 'нажата ESC.
    SELECT CASE ch
      CASE "1"
        CALL procedure1
      CASE "2"
        CALL procedure2
    END SELECT
  LOOP WHILE 1

Ожидание клавиши тоже реализуется с помощью цикла:

  DIM ch AS STRING
  ...
  PRINT "Нажмите кнопку 'R'"
  DO
    ch=INKEY$
    ch=LCASE$(ch)
  LOOP UNTIL ch="r"

Конечно, реализация аналогичных фрагментов может немного меняться от программы к программе, отличия эти должны быть незначительными. Например, такая реализация ожидания нажатия клавиши неприемлема:

PRINT "Нажмите кнопку 'R'"
l1: g$=INKEY$
    GOTO l3
l2: GOTO l1
    ....
    ....
    ....
l3: IF g$="R" THEN GOTO l4
    IF g$<>"R" THEN GOTO l2
l4: ...

Знаете, проверяя ваши домашние задания, мне приходится сталкиваться с подобными "перлами". Именно поэтому я и начал сегодня этот разговор.

На сегодня мы с этим закончим. Внимательно следите за тем, как я оформляю примеры программ (мое оформление трудно назвать идеальным, но оно достаточно хорошо, чтобы вы на него равнялись на первых порах). Также внимательно следите за тем, что вы пишите, выполняя домашнее задание.

Если у вас появились вопросы по теме нашего разговора, задавайте. А то уж больно редко у нас появляется рубрика "ВОПРОСЫ И ОТВЕТЫ".

ТЕОРИЯ .::. Сложные типы данных - 2. Многомерные массивы

В 22-ом выпуске рассылки мы с вами узнали, что такое массивы и познакомились с тем, как их можно применять на практике (мы написали программы для анализа распределения значений температур).

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

Например, значения температур за год можно обозначить одним именем temp. А в качестве индекса использовать номер дня в году.

temp(1) - температура (пускай, средняя) в первый день, temp(2) - во второй, temp(i) - температура в i-ый день.

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

DIM temp(365)
 ...
PRINT "Средняя температура за год:";
days=365
sum=0
FOR day=1 TO days
  sum=sum+temp(day)
NEXT day
average=sum/days
PRINT average

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

Например, массив из 365 значений температуры притом, что каждое значение будет типа integer, займет в памяти 2*365=730 байт. А массив из нашего пример займет 732 байта (+2 байта на нулевой элемент, который мы не используем, но который занимает память).

Массивы, которые мы рассмотрели, называются одномерными массивами или векторами. "Одномерный" означает, что массив имеет одно измерение, т.е. чтобы обозначить все элементы достаточно одного индекса.

Данные, с которыми приходится иметь дело в жизни, часто имеют более сложную структуру и их не удобно представлять в виде вектора.

Мы только что рассмотрели массив, содержащий значения температур за год. Теперь представьте, что нам нужно изучать, как меняется температура с годами. Т.е. нам нужно хранить значения температуры не за один год, а за несколько (или даже за несколько десятков) лет.

Мы можем создать большой массив-вектор и хранить в нем значения температуры за несколько лет. Путем нехитрых математических вычислений можно определить индекс значения температуры за нужный нам год и день. Такой принцип был использован в примере в выпуске 22 (см. программу 22.1)

Например, индекс 11-го дня 3-го года можно получить так: 365*3+11. Предполагается что первые три года имеют по 365 дней, т.е. не високосные.

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

Так мы будем поступать при программировании на JavaScript, а Бейсик предоставляет нам более удобный способ организации массива массивов (рассмотрим его чуть ниже).

Для адресации любого элемента массива массивов нужно уже два индекса: номер массива (номер элемента в массиве массивов) и номер элемента в массиве.

Это, может быть, звучит не очень понятно. Понимание придет, когда мы рассмотрим пример.

Вернемся к нашим баранам, т.е. к температурам. Чтобы адресовать значение температуры за произвольный день нужно знать номер года (первый индекс) и номер дня в этом году (второй индекс).

Раз нам нужно два индекса, значит, наш массив называется двухмерным. Объявить переменную - двухмерный массив в Бейсике так же легко, как и одномерный:

DIM имя_массива(нач1 TO кон1, нач2 TO кон2)

Где нач и кон - начальные и конечные значения соответствующих индексов. В случае с температурами нам может пригодиться такой массив:

DIM temp(1 TO 10, 1 TO 366)

В этом массиве мы можем хранить температуры за 10 лет (теоретически 10*366=3660 значений, практически - не более 3653, т.к. 365 дней имеют лишь високосные года (каждый четвертый)).

Теперь гораздо проще получить доступ к температуре за 11-й день 3-го года: temp(3,11) и не надо задумываться, являются ли предыдущие годы високосными или нет.

Визуально двухмерные массивы можно представить как таблицы или матрицы (кому что ближе).

С другой стороны можно представить таблицу (с данными одного типа) или матрицу как двухмерный массив.

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

                  Температура за 10 лет
*-----*----*----*----*----*----*----*----*----*----*----*----*----*---
| Дни|    |    |    |    |    |    |    |    |    |    |    |    |
|го  |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 | ...
|ды  |    |    |    |    |    |    |    |    |    |    |    |    |
|    |    |    |    |    |    |    |    |    |    |    |    |    |
*-----*----*----*----*----*----*----*----*----*----*----*----*----*----
|  1  | 0  |  1 |  4 |  5 |- 2 |- 2 |- 7 |-12 |-10 |-10 |- 7 |- 8 |
|  2  |-20 |-20 |-22 |-20 |-18 |-20 |-20 |-19 |-20 |-20 |-23 |-20 |
|  3  |-20 |-15 |-15 |-17 |-12 |-12 |-16 |-19 |-20 |-22 |-20 |-18 |
|  4  |- 6 |- 6 |-10 |- 8 |- 4 |  0 |  1 |- 2 |- 1 |- 3 |  0 |  0 |
|  5  |- 4 |- 3 |- 1 |- 1 |  1 |  0 |  2 |  0 |  1 |- 2 |- 4 |- 4 |
 .....................................................................
| 10  |-17 |-17 |-17 |-16 |-17 |-18 |-20 |-22 |-20 |-20 |-18 |-19 |
*-----*----*----*----*----*----*----*----*----*----*----*----*----*----

Вот таблица температур. Первый индекс (годы) - самый левый столбец, второй индекс (дни) - верхняя строка. Судя по таблице, temp(3,11) будет равно -20, а temp(4,7) = 2.

При работе с двухмерными массивами используются вложенные циклы. Например, нам нужно распечатать вышеприведенную таблицу (первые 12 дней первых пяти лет):

years = 5
days = 12

PRINT , , , "Дни" PRINT STRING$(75, "-") PRINT "Годы |", ; FOR day = 1 TO days PRINT USING "#####"; day; NEXT day PRINT STRING$(75, "-")

FOR year = 1 TO years PRINT year; " |", ; FOR day = 1 TO days PRINT USING "#####"; temp(year, day); NEXT day PRINT NEXT year PRINT

Эта программа генерирует таблицу, вроде такой:

                                    Дни
---------------------------------------------------------------------
Годы |      1    2    3    4    5    6    7    8    9   10   11   12
---------------------------------------------------------------------
 1   |      1   -4   -3  -12  -11    3  -20    2    4    1  -19   -8
 2   |      5    3   -9    8    6  -19    8  -10   -5    3  -19   -3
 3   |     -6  -12   -2   -1  -13  -12    4    4   -3    9    7  -14
 4   |      0    9  -13   -4  -17    9    0  -20   -3  -17  -17    3
 5   |    -12  -19  -12   -9  -11    8    9   -8  -12  -16  -16   -1

Не хит дизайнерской моды, конечно, но ... идея, я полагаю, вам понятна.

Вы, должно быть, обратили внимание на странные данные в таблице. Они были сгенерированы случайным образом. Я рассказывал о том, как и зачем это делается в выпуске 22. Особенность генерации двухмерных массивов заключается в том, что используются вложенные циклы. Я использовал такой код (не забудьте, что массив нужно объявить; в примере это не отражено):

FOR i=1 TO years
  FOR j=1 TO days
    temp(i,j)=INT(RND(1)*30)-20
  NEXT j
NEXT i

Вам придется часто работать с таблицами и применять двухмерные массивы. Например, экран можно считать таблицей. Можно запомнить его копию в двухмерном массиве. Или проделать что-нибудь подобное.

Кроме двухмерных массивов бывают еще трехмерные, четырехмерные и т.д., проще говоря, многомерные. Для QuickBasic'а максимальное число размерностей может быть равно 60.

Где могут понадобиться многомерные массивы?

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

Какая температура была 20-го числа 5-го месяца, 3-го года? Или даже лучше, какая температура была 20-го мая 1993 года?

Нам нужен такой массив:

DIM temp(1990 TO 2000, 1 TO 12, 1 TO 31)

Простейший трехмерный массив.

Напечатаем нужное нам значение температуры:

PRINT temp(1993,5,20)

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

Многомерные массивы удобно визуализировать (если в этом есть необходимость) в виде иерархических (древовидных) структур.

В связи с ограниченностью места привожу пример фрагмента такой структуры.

1990------------------------1991------------------------1992
 |                           |                           |
 1-2-3-4-5-6-7-8-9-10-11-12  1-2-3-4-5-6-7-8-9-10-11-12  1-2-3-4-5-6-
 | | | | | | | | | |  |  |
 | | | | | | | | | |  |  1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-
 | | | | | | | | | |  1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-
 | | | | | | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
 | | | | | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-
 | | | | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-
 | | | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-
 | | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-
 | | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-
 | | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-
 | | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-
 | 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-
 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-

На житейском уровне это можно представить так: есть шкафы с номерами 1990 - 2000, в каждом шкафу 12 полок, на каждой полке 28-31 папок или файлов с данными.

Реально, в памяти компьютера, элементы многомерных массивов хранятся последовательно и занимают непрерывную(!) область памяти.

Элементы трехмерного массива из последнего примера будут располагаться в памяти в таком порядке:

temp(1990,1,1), temp(1990,1,2), ..., temp(1990,1,31),temp(1990,2,1), ..., temp(1990,2,31), ..., ..., temp(1990,12,31), temp(1991,1,1), ..., ..., ..., temp(2000,12,1), temp(2000,12,2), ..., temp(2000,12,31).

Т.е. сначала увеличивается самый правый индекс, затем второй справа и т.д. Это напоминает счет: 10,11, ..., 19, 20, 21, ... , когда сначала увеличивается самый правый (младший) разряд, затем остальные справа налево.

Как вы могли догадаться, многомерные массивы занимают довольно много памяти. Наш массив имеет (2000-1990)*12*31 = 3720 элементов. И занимает 3720*2 = 7440 байт или примерно 7,27 Кбайт, с учетом того, что элементы массива имеют тип INTEGER и занимают по 2 байта каждый.

Семь килобайт не такая уж внушительная величина в наши дни, не так ли? Однако нужно помнить, что число элементов массива ограничено сверху, т.е. не может быть бесконечным. Например, если мы захотим создать массив с температурами за 100, то столкнемся с трудностями, т.к. число элементов такого массива будет больше 32768.

Но так или иначе данные требуют памяти для своего хранения. Есть два типа массивов в зависимости от момента выделения под них памяти.

Это статические (static) массивы, память под которые выделяется при компиляции (что соответственно увеличивает размер исполняемого файла) и динамические (dynamic) массивы, память под которые выделяется при работе программы (т.е. программа запрашивает необходимый объем памяти у операционной системы уже в ходе работы).

Динамическое выделение памяти - очень обширная, интересная и, местами, сложная тема. И, что самое главное, тема эта довольно важная, особенно для программистов на Си, которым приходится задумываться о динамическом выделении памяти даже в случае работы над относительно простыми программами.

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

В двух словах скажу, зачем все это надо. Предположим, что наша программа получает какие-то данные из пользовательского файла. Файл этот может иметь переменный размер. Сколько памяти нам нужно выделить, чтобы ее хватило для размещения данных из этого файла?

Ответить на этот вопрос трудно, потому что не известен объем данных, который может содержаться в файле.

В ряде простых случаев можно предположить максимально возможный объем необходимой памяти и создать соответствующий массив.

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

Если кто-то выполнит меньшее количество задач (например, 5), то некоторый объем памяти окажется неиспользованным. Так как этот объем мал, то это не страшно.

Оценки за задачи ставятся конкретному студенту. Значит, мне нужно иметь массив с числом элементов равным числу студентов. В каждый момент времени это число известно, сейчас, например, это число равно 179.

Можно создать массив из 179 элементов. Но завтра число студентов может измениться. И послезавтра. Что же, придется перекомпилировать программу каждый день?

Нет, придется использовать динамический массив - при запуске программы создавать массив с требуемым числом элементов (но не большим 32768).

Но обо всем этом читайте в следующем выпуске, где мы попробуем написать простенькую СУБД.

ЗАКЛЮЧЕНИЕ

Некоторое время назад я говорил, что пора выделить из списка студентов курса "мертвые души". По итогам операции "Зачистка" приостановлено членство в учебной группе следующих студентов: Idris82, L1e2x3u4s5, MyNick1, Neo. Причина: проблемы с адресами электронной почты указанных товарищей, т.е. мне не удалось с ними связаться.

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

-------

В 27-м выпуске была опубликована форма подписки на рассылку "Создание драйверов устройств для Windows и Linux". Недавно я получил письмо от автора этой рассылки, в котором он сообщил, что рассылку пришлось закрыть.


С уважением,
Вячеслав Stac Мацнев mailto:stac@stacmv.net
25.11.01.



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

В избранное