Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#15| Dragon God
Demon's Souls |#14| Flamelurker
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Богатырев А. Весь текст 120.46 Kb

Руководство полного идиота по программированию на C

Предыдущая страница Следующая страница
1 2 3  4 5 6 7 8 9 10 11
        for(nline=0; nline <  LINES; nline++){

            if((nline % 2) == 0)    /* четное ? */
                    drawOneLine(LINES - nline - 1, nline*2 + 1, '+', 1, nline);
            else    drawOneLine(LINES - nline - 1, nline*2 + 1, '*', 9, nline);
        }

        /* А почему именно 1 или именно 9 ?
         * А все что попало, лишь бы не 0.
         * Можно 3, 333, 666, -13445, итп
         *
         * Вопрос: что будет, если тут написать 0 ?
         */
}
     09.c

/* Следующая задача будет касаться того,
   чтобы каждая строка треугольника печаталась
   в виде:
        *+*+*+*.....*+*

   Тут нам уже придется модифицировать функцию рисования строки.
*/

#include

int LINES = 25; /* всего строк. */

void drawOneLine(int nspaces, int nsymbols){
        int i;

        for(i=0; i < nspaces; i++)
                putchar(' ');

        /* в цикле мы будем проверять на четность НОМЕР
           печатаемого символа.
         */
        for(i=0; i < nsymbols; i++){
                if((i % 2) == 0)
                        putchar('*');
                else    putchar('+');
        }
        putchar('\n');
}

void main(){
        int nline;      /* номер строки */

        for(nline=0; nline <  LINES; nline++) {
                drawOneLine(LINES - nline - 1, nline*2 + 1);
        }
}
     10.c

/* Задача нарисовать РОМБ:
        *
       ***
      *****
       ***
        *
*/

#include

int LINES = 10; /* всего строк в половине ромба. */

void drawOneLine(int nspaces, int nsymbols){
        int i;

        for(i=0; i < nspaces; i++)
                putchar(' ');

        for(i=0; i < nsymbols; i++)
                putchar('+');
        putchar('\n');
}

void main(){
        int nline;      /* номер строки */

        for(nline=0; nline <  LINES; nline++)
                drawOneLine(LINES - nline - 1, nline*2 + 1);

        /* Мы нарисовали треугольник.
           Теперь нам нужен перевернутый треугольник.
           Пишем цикл по убыванию индекса.
           С данного места номера строк отсчитываются в обратном порядке:
           от LINES-2 до 0
         */

        for(nline=LINES-2; nline >= 0; nline--)
                drawOneLine(LINES - nline - 1, nline*2 + 1);
}
     11.c

/* А теперь рисуем ромб, используя математические формулы. */

#include

void draw(int nspaces, int nstars, char symbol){
        int i;

        for(i=0; i < nspaces; i++)
                putchar(' ');
        for(i=0; i < nstars; i++)
                putchar(symbol);
        putchar('\n');
}

void main(){
        int LINES = 21;
        int MIDDLELINE = LINES/2 + 1;   /* середина ромба */
        int nline;

        for(nline=0; nline < MIDDLELINE; nline++)
                draw(MIDDLELINE - nline -1, nline*2+1, 'A');

        /* У следующего цикла for() нет инициализации
           начального значения индекса.
           Начальное nline наследуется из предыдущего цикла,
           таким, каким оно осталось после его окончания, то есть
           равным MIDDLELINE.
         */

        for( ; nline < LINES; nline++)
                draw(nline - MIDDLELINE + 1, (LINES - 1 - nline) * 2 + 1, 'V');
}
      * 12_ARRAYS.txt *

     МАССИВЫ

Массив - это несколько пронумерованных переменных,
         объединенных общим именем.
         Все переменные имеют ОДИН И ТОТ ЖЕ ТИП.

Рассмотрим ПОЛКУ с N ящиками,
пусть имя полки - var.
Тогда кажждый ящик-ячейка имеет имя
        var[0]
        var[1]
        ...
        var[N-1]

Нумерация идет с НУЛЯ.

          --------
         /  var  /
        /       /
        -------------------------------------------  ------------------
        |           |           |           |            |            |
        |           |           |           | ....   ... |            |
        |           |           |           |            |            |
        -------------------------------------------  ------------------
         / var[0] /   / var[1] /   / var[2] /             / var[N-1] /
         ---------    ---------    ---------              -----------

Массив объявляется так:

        int var[N];

здесь N - его размер, число ячеек.

Это описание как бы объявляет N переменных типа int с именами
        var[0] ... var[N-1];

В операторах для обращения к n-ому ящичку (где 0 <= n < N)
используется имя ящика

        var[n]

где n - целое значение (или значение целой переменной,
или целочисленного выражения), "индекс в массиве".
Эта операция [] называется "индексация массива".
Индексация - есть ВЫБОР одного из N ящиков при помощи указания целого номера.
        var    - массив (N ячеек)
        n      - выражение (формула), выдающая целое значение в интервале 0..N-1
        var[n] - взят один из элементов массива. Один из всех.
        n      - номер ящика - называется еще и "индексом" этой переменной в массиве.

Пример:

        int var[5];                                     /* 1 */

        var[0] = 2;                                     /* 2 */
        var[1] = 3 + var[0];                            /* 3 */
        var[2] = var[0] * var[1];                       /* 4 */
        var[3] = (var[0] + 4) * var[1];                 /* 5 */

        printf("var третье есть %d\n", var[3]);

В ходе этой программы элементы массива меняются таким образом:

          var[0]    var[1]     var[2]     var[3]    var[4]
          ------------------------------------------------
/* 1 */   мусор     мусор      мусор      мусор     мусор
/* 2 */   2         мусор      мусор      мусор     мусор
/* 3 */   2         5          мусор      мусор     мусор
/* 4 */   2         5          10         мусор     мусор
/* 5 */   2         5          10         30        мусор

Как видим, каждый оператор изменяет лишь ОДНУ ячейку массива за раз.

Массив - набор переменных, которые не ИМЕНОВАНЫ разными именами,
вроде var0, var1, var2, ...
а ПРОНУМЕРОВАНЫ под одним именем:
var[0], var[1], var[2], ...

Индекс - часть ИМЕНИ ПЕРЕМЕННОЙ.

На самом деле индексация - это
        1) выбор элемента в массиве
        2) справа от присваиваний и в выражениях - еще и разыменование,
           то есть взятие вместо имени переменной - значения, в ней хранящегося.
---------------------------------------------------------------------------

Если в переменную не было занесено значение,
а мы используем эту переменную,
то в ней лежит МУСОР (любое, непредсказуемое значение).

        printf("var4 есть %d\n", var[4]);

напечатает все что угодно.

Поэтому переменные надо всегда инициализировать
(давать им начальное значение).

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

Локальные переменные не инициализируются автоматически, и содержат МУСОР.
---------------------------------------------------------------------------

Массивы НЕЛЬЗЯ присваивать целиком, язык Си этого не умеет.

        int a[5];
        int b[5];

        a = b;  /* ошибка */

Также нельзя присвоить значение сразу всем элементам (ячейкам) массива:

        a = 0;  /* ошибка */

не делает того, что нами ожидалось, а является ошибкой.
Для обнуления всех ячеек следует использовать цикл:

        int i;

        for(i=0; i < 5; i++)    /* для каждого i присвоить a[i] = 0; */
                a[i] = 0;

---------------------------------------------------------------------------

СВЯЗЬ МАССИВОВ И ЦИКЛОВ
=======================
Вследствие этого массивы приходится копировать (и инициализировать)
поэлементно, в цикле перебирая все (или часть) ячейки массива.

        int i;

        for(i=0; i < 5; i++)
                a[i] = b[i];

В данном случае индекс цикла служит также и индексом в массиве.

        Индексы в массиве идут с НУЛЯ.

Пример инициализации:

        int index, array[5];

        for(index=0; index < 5; index++)
                array[index] = index * 2 + 1;

или

        int index, array[5];

        index = 0;
        while(index < 5){
                array[index] = index * 2 + 1;
                index++;
        }

        /* В массиве будет: { 1, 3, 5, 7, 9 } */

ИНДЕКС
        для массивов -
                номер "ящика/ячейки" в массиве.

        для циклов -
                номер повторения цикла, счетчик.
                Мы должны изменять его САМИ.

Обычно массивы и циклы совмещаются так:
индекс цикла есть индекс в массиве;
то есть индекс цикла используется для перебора всех
элементов массива:

        int a[N], i;

        for(i=0; i < N; i++)
                ...a[i]...
---------------------------------------------------------------------------

Примеры:

        int a[5];

        a[0] = 17;
        a[0] += 4;
        a[0]++;
---------------------------------------------------------------------------

Пример: числа Фибоначчи.
Задаются математическими формулами:

        f[1]   = 1
        f[2]   = 1
        f[n+2] = f[n+1] + f[n]

Вот программа:
---------------------------------------------------------------------------

#include       /* магическая строка */
#define N 20            /* сколько первых чисел посчитать */

void main(){
        int fibs[N], index;

        fibs[0] = 1;    /* индексы отсчитываются с нуля!!! */
        fibs[1] = 1;

        /* Тут показано, что индекс элемента массива может вычисляться */

        for(index=2; index < N; index++)
                fibs[index] = fibs[index-1] + fibs[index-2];

        /* Распечатка в обратном порядке */
        for(index = N-1; index >= 0; index--)
                printf("%d-ое число Фибоначчи есть %d\n",
                        index+1,                   fibs[index]);
}

Здесь мы видим новый для нас оператор #define
Он задает текстуальную ЗАМЕНУ слова N на слово 20,
в данном случае просто являясь эквивалентом

        const int N = 20;

К несчастью размер массива не может быть задан при помощи переменной,
а вот при помощи имени, определенного в #define - может.

     СТРОКИ

Строки есть массивы БУКВ - типа char,
оканчивающиеся спецсимволом \0

        char string[20];

        string[0] = 'П';
        string[1] = 'р';
        string[2] = 'и';
        string[3] = 'в';
        string[4] = 'е';
        string[5] = 'т';
        string[6] = '\0';

        printf("%s\n", string);

%s - формат для печати СТРОК.
Никакие другие массивы не могут быть напечатаны
целиком одним оператором.

        char string[20];

        string[0] = 'П';
        string[1] = 'р';
        string[2] = 'и';
        string[3] = 'в';
        string[4] = 'е';
        string[5] = 'т';
        string[6] = '\n';       /* Перевод строки - тоже буква */
        string[7] = '\0';

        printf("%s", string);

или даже просто

        printf(string);

Такие массивы можно записать в виде строки букв в ""

        char string[20] = "Привет\n";

Оставшиеся неиспользованными символы массива от string[8] до string[19]
содержат МУСОР.

ПОЧЕМУ ДЛЯ СТРОК ИЗОБРЕЛИ СИМВОЛ "ПРИЗНАК КОНЦА"?
=================================================
Строка - это ЧАСТЬ массива букв.
В разное время число букв в строке может быть различным,
лишь бы не превышало размер массива (тогда случится сбой программы).
Значит, следует где-то хранить текущую длину строки (число использованных
символов). Есть три решения:
(1)     В отдельной переменной. Ее следует передавать во все
        функции обработки данной строки (причем она может изменяться).

        char str[32];     /* массив для строки */
        int  slen;        /* брать первые slen букв в этом массиве */
        ...
        func(str, &slen); /* ДВА аргумента для передачи ОДНОЙ строки */
        ...

        Этот подход работоспособен, но строка разбивается на два
        объекта: сам массив и переменную для его длины. Неудобно.
Предыдущая страница Следующая страница
1 2 3  4 5 6 7 8 9 10 11
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (6)

Реклама