Некоторые примеры из семинарских занятий по Си (А.А. Вылиток - Лекции)
Описание файла
Файл "Некоторые примеры из семинарских занятий по Си" внутри архива находится в папке "А.А. Вылиток - Лекции". PDF-файл из архива "А.А. Вылиток - Лекции", который расположен в категории "". Всё это находится в предмете "операционные системы" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
А.А. ВылитокНекоторые примеры из семинарских занятий по СиЗадача. Дана матрица целых чисел размера n m. В каждойстрокевыбирается наименьшее из значений элементов строки, затем среди выбранныхзначений находится наибольшее. Написать программу, определяющую этозначение.Паскаль(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)pRoGraM Maxmin (input,output);const m=5;N=6;type vector=array[0..M-1] of integer;type matrix=array[0..N-1] of vector;var i,k,res: integer;matr:Matrix;function min(var vec:vector):integer;var i,l:integer;beginl:=vec[0];for i:=1 to M-1 doif vec[i]<l then l:=vec[i];min:=lend;(15) begin(16)for i:=0 to N-1 do(17)for k:= 0 to M-1 do(18)read(matr[i][k]);(19)res:=min(matr[0]);(20)for i:=1 to N-1 do(21)begin k:=min(matr[i]);(22)if k > res then res:=k(23)end;(24)writeln(’Maxmin =’, res)(25) end.язык|||||||||||||||||||||||||||(1)(2)(3)(4)(5)(6)(7)(8)(9)Си(10)(11)(12)(13)(14)#include <stdio.h>#define M 5#define N 6typedef int vector[M];typedef vector matrix[N];int i,k,res;matrix matr;int min(vector vec){int i, l;l = vec[0];for (i=1; i<=M-1; ++i)if (vec[i]<l) l=vec[i];return l;}(15)(16)(17)(18)(19)(20)(21)(22)(23)(24)(25)main(){for (i=0; i<= N-1; ++i)for (k=0;k<=M-1; ++k)scanf(”%d”, &matr[i][k]);res = min(matr[0]);for (i=1; i < N; ++i){ k = min(matr[i]);if (k >res) res = k;}printf(”Maxmin=%d\n”, res);}Замечания и комментарии1.2.3.4.5.Лексические различия:- В Паскале строчные и прописные буквы при написании имен и служебных слов не различаются: имя M в 11-йстроке и m во 2-й строке обозначают одну и ту же константу.
В языке Си регистр букв важен: m и M считаютсяразличными именами; for является ключевым словом, означающим начало оператора цикла, а FOR и For таковымине являются.- Присваивание в языке Си обозначается одиночным знаком равенства = (в Паскале :=) ; для обозначениясравнения в Си иcпользуется двухсимвольный знак == Ср. строки 11 в обеих программах.- Операторные скобки (ограничивающие составной оператор ) в Паскале обозначаются словами begin и end, в Сиим соответствуют символы { и }.- Строковые константы ограничиваются двойными кавычками, а не апострофами, как в Паскале. (Символьныеконстанты в Си берутся в апострофы (одинарные кавычки), как в Паскале)При описании переменных в Си, в отличие от Паскаля, сначала указывается имя типа, а затем перечисляются именапеременных ( строка 6).Элементы массивов в языке Си нумеруются целыми числами, начиная с нуля.
Поэтому при описании массивауказывается не диапазон изменения индекса (как в Паскале), а размер массива (строки 4,5).Программа на Паскале может содержать вложенные процедуры и функции. Программа на Си состоит изпоследовательности переменных и функций. Вложенность функций не допускается. Функции могут не возвращатьзначений (такие функции являются аналогами паскалевских процедур).
Выполнение программы на языке Синачинается с первого оператора функции c именем main.В Си с помощью директивы define (строки 2,3) константам можно давать имена.6.7.8.В языке Паскаль процедуры ввода/вывода (read, write) являются предопределенными, т.е. не требуют явногоописания в программе.
В языке Си описания стандартных функций ввода/вывода (scanf, printf) добавляются впрограмму с помощью директивы include (строка 1).Присваивание в языке Си является не оператором, а операцией (результат которой - присвоенное значение ). Этаоперация может быть использована в сложных выражениях. Так, например, строки 21,22 в данном примерепрограммы на Си можно заменить строкой:if ( (k = min(matr[i]) ) > res ) res = k;Точка с запятой «;» в языке Паскаль является «разделителем».
Например, она разделяет два соседних оператора,или два соседних описания. В языке Си смысл точки с запятой иной : она является «завершителем» операторов(кроме составного оператора) и описаний, т.е. является признаком конца оператора или описания. Сравните строки13 и 14 программ на Паскале и Си.Примеры перечислимых типовenum season {winter=1,spring,summer,autumn}; /* season – это тегперечисления */enum season x, y; /* описание переменных перечислимого типа */x=spring; y=x;Пример описания перечислимого типа и оператора switch:typedef enum {red, blue, green=5,yellow} colortype;/* константы перечисления имеют значения соответственно 0, 1, 5, 6 */colortype next_color (colortype color){switch(color) {case red: return blue; /* break не нужен, т.к.
сразу возврат изфункции */case blue: return green;сase green : return yellow;сase yellow : return red;}}Допускается давать одинаковые значения константам одного перечисления, напримерenumunit { bike, car, helicopter=5, truck=1 };В этом перечислении константы car и truck имеют одно и то же значение 1.СтруктурыАналогом паскалевских записейstructstructp.x=1;p.y=2;в языке Си являются структуры:point { int x;/* point – это тег структуры */int y;/* x и y – это поля структуры */}point p; /*описание переменной типа struct point *//* присваивание значений полям структуры p*/Можно задать тип, который будет означать структуру:typedefstruct pointPoint/* Point - имя типа структуры*/Можно задать тип структуры и таким образомtypedef struct { int x;/* тег структуры пропущен */int y;/* x и y – это поля структуры */} Point/* имя типа */Point p1; /*описание переменной типа struct { int x;int y;} */p1.x=4;p1.y=5;Можно совместить описание структуры с тегом и задание нового имени типа:typedef struct point{ int x;int y;} Point/* тег структуры — point *//* x и y – поля структуры *//* имя типа */При таком описании Point является синонимом для struct point.УказателиАналогом паскалевского описания указателяpr: ^ integer;является следующее описание на языке Си:int * pr;Указатели на структуру:struct point p = {0.0,0.0}; /* инициализация структуры p */struct point * pp=&p;/* pp – указатель на структуру p */(*pp).x=1.0;pp->y=2.0; /* эквивалентно (*pp).y=2.0 *//* выражение *pp.x=3; ошибочно, т.к.
воспринимается как*(pp.x)=3 в силу большего приоритета операции точка. */Примеры использования операторовНайти среднее арифметическое s положительных чисел массива mas.double s=0;for (i=0,k=0; i < N; i++){if (mas[i]<=0) continue; /* пропускаем неположительные */s+=mas[i]; /* то же, что s=s+mas[i]; */k++;}if (k!=0) s/=k; /* то же, что s=s/k; */На каждой итерации проверяем положительность очередного элемента массива. Еслиэлемент не положительный, то оператор continue передает управление на следующуюитерацию цикла, которая для цикла for начинается с вычисления выражения в третьейсекции заголовка оператора цикла, затем вычисление и сравнение с нулем результатавыражения из второй секции.
Цикл продолжается, пока не ноль (т.е. ложь).Поиск элемента в неупорядоченном массивеПусть заданы массив из N целых чисел mas и переменная x. Все числа в массивепопарно различны. Присвоить переменнойi номер элемента массива, такого чтоmas[i]==x. Если такого элемента нет присвоить i значение –1.for (i=0; i < N;i++)if (mas[i]==x) break; /* досрочный выход из цикла */if (i==N) i=-1; /* нет такого элемента */Оператор break осуществляет выход из цикла (а также из переключателя switch) — кактолько нужное значение найдено, продолжать цикл нет необходимости.Другое решение:i=N; /* просмотр от конца к началу */while(i--)if (mas[i]==x) break;/* после выхода из цикла i имеет нужное значение */Выражение i-- состоит из операции постфиксного уменьшения, она обладаетпобочным эффектом: значение переменной i уменьшается на 1.
Результат выражения —старое значение i до уменьшения.В языке Си нет логического типа и констант true и false как в Паскале. Вместоэтого используется арифметический целый тип по следующему соглашению: 0 означаетложь, все остальные значения (ненулевые) означают истину. При первой проверкеусловия цикла значение выражения будет равно N, оно отлично от нуля, следовательно,будет выполнено тело цикла. В результате побочного эффекта i получит значение N-1 ина первой итерации цикла переменная x будет сравниваться с последним элементоммассива. Если их значения совпадут, цикл прекращается и в i находится искомый номер,в противном случае осуществится переход на проверку условия цикла. Если i не равно0, то произойдет продвижение по массиву на один элемент влево и сравнение очередногоэлемента с x.
Если i равно 0, то весь массив уже просмотрен, выражение в условиицикла даст значение ноль, что означает ложь, и цикл завершится. При этом в результатепобочного эффекта i получит значение -1, означающее, что искомый элемент невстречается в массиве.Упорядочение массива (сортировка)Дан массив целых чисел размера N ≥1. Упорядочить его элементы по неубыванию.Сортировка методом пузырькаvoid bubble_sort( int mas[], int N) {int i,j, temp;for (i=N-1; i>=0; i--)for (j=0; j<i; j++ )if (mas[j]>mas[j+1]) {temp=mas[j+1];mas[j+1]=mas[j];mas[j]=temp;}}В языке Си размер массива передается не вместе с массивом, а как отдельный параметр,(в параметре, означающем массив, размер вообще можно опускать). Причины этого будутясны после более детального знакомства с массивами и их связью с указателями. Другойвариант — задавать размер глобальной константой, как это было в примере с поискомседловой точки в матрице.Сортировка простым выбором (минимального элемента)void insert_sort(int mas[], int N) {register int i,j, min;for (i=0; i<N; i++){min=i;for (j=i+1; j<N ; j++)if (mas[j]<mas[min]) min=j;j=mas[i];mas[i]=mas[min]; /* минимальный среди mas[i]… mas[N-1] */mas[min]=j;/* переставили в позицию i */}}Ключевое слово register (спецификатор класса памяти) указывает компилятору, чтосоответствующие переменные будут часто использоваться и их желательно разместить сучетом минимизации времени доступа ( например, на регистрах).Противоположным по смыслу является ключевое слово volatile – не размещать нарегистре или в кэше, так как переменная может изменяться независимо от выполняемойпрограммы другими (внешними) процессами (параллельно выполняющимисяпрограммами).Бинарный поиск (поиск в упорядоченном массиве)/* binsearch: найти x в v[0]<=v[1]<=…<=v[n-1] */int low, high, mid;low=0;high=n-1;while ( low <= high){mid = (low+high)/2;if (x<v[mid]) high=mid-1;else if ( x>v[mid]) low=mid+1;else return mid; /* x найден */}return -1; /* x не найден */Примеры разумного использования оператора gotofor (…)for (…) {if (disaster)/* если «бедствие», например, обнаружено неверное данное, */goto error / * уйти на «ошибку» */}…/* обработка ошибки */error: … /* здесь должны быть действия по реакции на ошибку, например, сообщениепользователю о том, что произошло, и подготовка к корректномузавершению программы */В качестве еще одного примера рассмотрим такую задачу: определить, есть ли в массиваха и b совпадающие элементы.