Организация символов с помощью FOR
Оператора for является самой популярной структурой для организации циклов. В общем случае его можно представить так:
for( выражение1; выражение2; выражение3) оператор;
В одной строке этот оператор определяет сразу три составляющие, отделяемые друг от друга точкой с запятой:
- а) начальное значение параметра цикла (выражение1);
- б) условие оканчания цикла (выражение2);
- в) закон изменения параметра цикла (выражение3).
Формально этот оператор эквиалентен последовательности операторов:
- выражение1;
- while(выражение2)
- {
- оператор;
- выражение3;
- )
В следующей программе оператор for служит для организации и печати последовательных чисел Фибоначчи, не превосходящих m. Проверка k<=m происходит перед каждым (в том числе и перед первым) выполнением тела цикла. Тело цикла выполняется, если проверочное выражение истинно. Затем следует изменение параметра: k=k+1; этот оператор, кстати, формирует очередное число Фибоначчи, а оператор j=k-j; хранит предыдущее.
- /*числа Фибоначчи*/
- #include <stdio.h>
- main()
- {
- int m, k, j=1;
- printf("введи m\n");
- scanf("%d",&m);
- for(k=1;k<=m;k=k+j)
- {
- printf("%d",k);
- j=k-j;
- }
- }
Как и в операторе while, тело цикла for может состоять из единственного оператора или из нескольких, заключенных в скобки. Следующяя программа (пример 4.5) предназначена для печати гистопрограммы длин читаемых слов (признак конца слова - пробел, запятая или "\n"). Оператор for управляет циклом, состоящим по сути из одного оператора if , так что скобки можно было бы опустить. Для построения гистопрограммы выбран символ, внутреннее представление которого в коде ASCII численно равно 220.
В скобках после ключевого слова for можно размещать выражения. Однако выражение1 и выражение3 не обязаны присваивать начальное значение и изменять параметр цикла, а выражение2 не обязано быть проверкой условия. Но компилятор всегда интерпретирует выражение2 как истинну или ложь (ложь- двоичный нуль, истина - все остальное). Любое из трех может быть опущено, хотя точка с запятой должна остаться. Допускается даже такой вырожденный случай: for(;;);. Он означает бесконечный цикл, так как пропущенное выражение2 всегда трактуется как истина.
- #include <stdio.h>
- main()
- {
- char str[24];
- int i,n=0;
- printf("введи строку:\n");
- while((str[n++]=getchar())!='\n';
- printf("%d\n",n);
- for(i=0;i<n;i++)
- {
- if(str[i]!=' ' && str[i]!=',' && str[i]!= '\n')
- printf("%c",220);
- else
- printf("\n");
- }
- }
В Си есть еще операция " , " (запятая), которая чаще всего используется в операторе for. Пара выражений, разделенных запятой, вычисляются слева направо. В каждой из трех составляющих оператора for можно помещать несколько выражений, разделенных запятыми. Этот прием часто используют, например, для синхронного изменения двух индексов при обработке массивов. В качестве примера приведем функцию substr, которая позволяет из задонной строки s1 выделить подстроку s2 указанной длины L, начиная с k-го по порядку символа (нумерация символов начинается с нуля). Функция принимает также параметр m- общее кол-во символов в исходной строке, чтобы контролировать возможный выход за ее пределы.
- /*выделение подстроки*/
- substr(char s1, char s2, int l, int k, int m)
- {
- int j,i;
- if(l+l>=m)k=m-l-1;
- for(i=1,j=0; i<l+k; i++.j++) s2[j]=s1[i];
- }
- #include <stdio.h>
- main()
- {
- char str[80], str2[80];
- int k,l,m=0;
- printf("ведите строку");
- while((str1[m++]=getchar())!='\n');
- printf("\n");
- /*m сохраняет свое значение*/
- printf("введите l и k\n");
- scanf("%d %d",&l, &k);
- substr(str1,str2,l,k,m);
- printf("%s\n",str2);
- }
Преимущество оператора for - компактность и объединение в одной строке трех операторов управления циклом - особенно заметно проявляется во вложенных циклах. Очередная прогрпмма предназначена для упорядочения целых чисел по возрастанию. Функция sor реализует один из наиболее простых алгоритмов сортировки - метод "пузырька".
- #include <stdio.h>
- main()
- {
- extern int sor();
- int i,n;
- static a[10]={10,1,9,2,8,3,7,4,6,5};
- n=10;
- sor(a,n);
- for(i=0; i<n; i++)
- printf(" %d",a[i]);
- }
- int sor(int x[], int n);
- int i,j,z;
- for(i=0;i<n-1;i++)
- for(j=i+1;j<n;j++)
- if(x[i]>x[j])
- {
- z=x[i];
- x[i]=x[j];
- x[j]=z;
- }
- return;
- }
Еще один пример со вложенными циклами демонстрирует программа. Она использует одну полезную при обработке текстов функцию index. Функция index определяет , входит ли в некоторую строку s1 заданная подстрока s2 и выдает положение (индекс) в строке s1 , начиная с которого строка s2 содержится в s1. Если s2 не входит в s1, то функция возращает '-1'.
- /*индекс строки */
- index(s1,s2)
- char s1[],s2[];
- {
- int i,j,k;
- for(i=0;s1[i]!='\0'; i++)
- {
- for(j=i,k=0;s2[k]!='\0' && s1[j]==s2[k]; j++,k++);
- if(s2[k]=='\0')
- return(i);
- }
- return(-1);
- }
- char str1[]="информатика"
- chra str2[]="форма"
- #include <stdio.h>
- main()
- {
- printf("%d\n",index(str1,str2));
- }