Россия, Москва |
Введение в программирование скриптов на C
Управление потоком вычислений
С представляет собой универсальный язык программирования со всеми присущими подобным языкам атрибутами. Он родился в период увлечения структурным программированием, поэтому в нем есть операторы, которые позволяют построить программу без использования goto.
Из всех механизмов управления ветвлением программы и передач управления мы рассмотрим несколько:
- оператор if ;
- оператор goto ;
- оператор while ;
- оператор for ;
- оператор switch ;
- оператор break.
В целом этого набора должно хватить для программирования CGI-скриптов.
Оператор if
Условное исполнение части кода программы в С определяется оператором if. В общем случае он имеет синтаксис:
if(условие) оператор; [else оператор;]
или
if(условие) { тело_блока } [else { тело_блока }]
В этой записи "условие" — это логическое выражение, которое возвращает значения "истина" или "ложь", например, "x>y". Оператор в данном контексте — это простой оператор С, например, "x=1". Блок — это совокупность простых операторов и/или блоков. Самый простой пример применения if — определение метода доступа к CGI-скрипту:
char *query; int n; ... if(strcmp(getenv("REQUEST_METHOD"),"GET")) { query = getenv("QUERY_STRING"); } else { n = atoi(getenv("CONTENT_LENGTH")); query = (char *) malloc(n+1); memset(query,'\000',n+1); fread(query,n,1,STDIN); }
В данном случае в качестве условия используется функция сравнения двух строк. Если результат сравнения – "истина", то исполняется первый блок (запрос из переменной окружения QUERY_STRING ), если результат сравнения – "ложь", то считываем запрос из стандартного ввода скрипта.
Оператор goto
Сколько было возражений против использования goto, но он до сих пор существует в большинстве языков программирования. В простых программах, по большому счету, без него можно обойтись, но в ряде случаев он необходим. Оператор goto — это принудительный переход на другой фрагмент кода программы. Например, при разных алгоритмах обработки выхода из цикла:
... for(i=0;i<n;i++) { buf[i]=getc(); if(buf=='\n') goto STRING; } printf("В потоке ввода одна строка\n"); STRING:printf( "Одна строка считана из потока ввода\n"); ...
В данном случае переход осуществляется при обнаружении символа конца строки во входном потоке.
Оператор while
Оператор while позволяет исполнять тело цикла до тех пор, пока верно условие. Например, при распечатке переменных окружения:
#include <stdlib.h> #include <stdio.h> void main(argc,argv,env) int argc; char *argv[]; char *env[]; { int i; i=0; while(env[i]) { printf("%d:%s\n",i,env[i]); i++; } }
В данном случае программа распечатывает переменные окружения до тех пор, пока указатель env[i] не примет пустое значение.
Оператор for
Оператор for — это детализация общего случая оператора цикла. Он состоит из блока инициализации переменной цикла, условия исполнения тела цикла и блока операторов конца цикла. Самой простой и наиболее распространенной его формой является случай одной переменной цикла:
for(i=0;i<n;i++) { /* тело цикла */ }
При программировании CGI-скриптов с оператором цикла можно познакомиться при распечатке аргументов командной строки в запросах типа ISINDEX:
#include <stdlib.h> #include <stdio.h> main(argc,argv,env) int argc; char *argv[]; char *env[]; { int i; printf("Content-type: text/plain\n\n"); for(i=0;i<argc;i++) { printf("argv[%d]=%s\n",i,argv[i]); } }
В данном случае переменная цикла пробегает значения от 0 до значения переменной argc, которая содержит число аргументов командной строки.
Оператор switch
Оператор switch — это переключатель на несколько положений, если пользоваться терминологией электротехники. Аргумент может принимать некоторые значения, например целочисленные или символьные, а выполняться будет тот фрагмент кода, который описан для этого значения:
switch(x) { case 'a': x='A'; break; ... case 'z': x='Z'; break; }
Данный фрагмент кода позволяет все строчные буквы превратить в заглавные.
Оператор break
Оператор break применяется для досрочного завершения цикла, в котором он указан. В некотором смысле он заменяет оператор goto. В примере с оператором switch оператор break использовался для выхода этого оператора из блока. Если бы break там не применялся, то операторы блока исполнялись бы последовательно с точки входа в блок до конца блока.
Оператор continue
Оператор continue применяется для пропуска операторов цикла, непосредственно следующих за оператором continue до конца цикла. В программировании CGI-скриптов оператор можно применять для обхода операторов вывода по условию, например, по IP-адресу удаленного хоста:
while(buf = fgets()) { if(!strncmp("144.206.160.32", getenv("REMOTE_ADDR"),14)) continue; ... }
В данном случае дополнительные операторы будут выполняться только для пользователей компьютера с IP-адресом 144.206.160.32.