вторник, 8 апреля 2014 г.

Упражнение 2.2.

Напишите цикл, эквивалентный приведенному выше fоr-циклу, не пользуясь операторами && и ||.

Под приведенным выше fоr-циклом подразумевается:
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
$ vim char_array_3.c
#include <stdio.h>
#define MAXLINE 1000    /* максимальный размер вводимой строки */

int getstr(char line[], int maxline);
void copy(char to[], char from[]);

int main(void)
{
    int len;    /* длина текущей строки */
    int max;    /* длина максимальной из просмотренных строк */
    char line[MAXLINE]; /* текущая строка */
    char longest[MAXLINE];      /* самая длинная строка */

    max = 0;
    /* есть ли еще строка */
    while ((len = getstr(line, MAXLINE)) > 0 )
        if (len > max) /* данная строка длиннее самой длинной из предыдущих*/
        {
            max = len;  /* запоминаем длину самой длинной строки */
            copy(longest, line);        /* запоминаем самую длинную строку */
        }
    if (max > 0)        /* была ли хоть одна строка? */
        printf("%s", longest);
    return 0;
}

/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
    int c, i, temp;
    i = 0;

    /* for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) */
    while (i < lim - 1) /* есть ли место для символа в массиве s,
    если это условие не выполняется, останавливаем вычисления*/
    {
        if ((c = getchar()) != '\n') /* чтение символа с проверкой конца строки */
        {
            if (c != EOF) /* сравнение символа с EOF */
            {
                s[i] = c;
                ++i;
            }
            else if (c == EOF)
            {
                temp = i; /* присваиваем временной переменной текущий индекс */
                i = lim; /* принудительный выход из цикла while */

            }
        }
        else if (c == '\n') /* ... а если была нажата клавиша Enter */
        {
            s[i] = c;
            ++i;
            temp = i; /* присваиваем временной переменной temp текущий индекс массива */
            i = lim; /* для принудительного выхода из цикла */
        }
    }
    s[temp] = '\0';        /* в конец строки дописывам "0" */
    return temp;   /* функция возвращает длину строки */
}

/* copy: копирует из 'from' в 'to'; to достаточно большой */
void copy(char to[], char from[])
{
    int i;

    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}
$ cc -g -O0 -Wall -o a.out char_array_3.c
Компиляция прошла без ошибок и предупреждений.
$ ./a.out
До сих пор мы пользовались готовыми функциями вроде main, getchar и putchar, теперь настала пора нам самим написать несколько функций.
Механизм использования функции в Си удобен, легок и эффективен.
Нередко вы будете встречать короткие функции, вызываемые лишь единожды; они оформлены в виде функции с одной-единственной целью — получить более ясную программу.
<Ctrl>+<D>

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

2 комментария:

  1. Исходный цикл:
    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
    Цикл без использования && и ||:
    for (i = 0; (i < lim - 1) == ((c = getchar()) != EOF) == (c != '\n') == 1; ++i)

    ОтветитьУдалить