Разделы презентаций


Язык программирования С Тема Типы данных, операции и

Содержание

Лекция 26.09.11г.Обзор вопросов прошлой лекцииСтроковые константыКонстанты перечислимого типаОбъявления переменныхОперации, виды операцийАрифметические операцииОперации отношенияЛогические операцииОперации инкремента и декрементаПоразрядные (битовые) операции

Слайды и текст этой презентации

Слайд 1Язык программирования С
Тема «Типы данных, операции и выражения»
(продолжение)
Лекция 26.09.11г.

Язык программирования СТема «Типы данных, операции и выражения»(продолжение)Лекция 26.09.11г.

Слайд 2Лекция 26.09.11г.
Обзор вопросов прошлой лекции
Строковые константы
Константы перечислимого типа
Объявления переменных
Операции, виды

операций
Арифметические операции
Операции отношения
Логические операции
Операции инкремента и декремента
Поразрядные (битовые) операции

Лекция 26.09.11г.Обзор вопросов прошлой лекцииСтроковые константыКонстанты перечислимого типаОбъявления переменныхОперации, виды операцийАрифметические операцииОперации отношенияЛогические операцииОперации инкремента и декрементаПоразрядные

Слайд 3Лекция 26.09.11г.
Операции с присваиванием
В языке С операция присваивания немного отличается

от аналогичной операции в других языках:
Присваивание a = b действительно

является операцией (а не оператором), т.е. после завершения этой операции получается некоторое значение (в данном примере – значение переменной b), которое может быть использовано для последующих вычислений. Следовательно, присваивание может применяться внутри выражений, наряду с другими операциями.

#include
#include
int main() {
int a = 12, b, c;
printf("result = %d \n", c=(b=a)-5);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Операции с присваиваниемВ языке С операция присваивания немного отличается от аналогичной операции в других языках:Присваивание a

Слайд 4Лекция 26.09.11г.
Операции с присваиванием (продолжение)
Кроме обычного присваивания существует ещё 10

модификаций, в которых присваивание совмещается с какой-либо бинарной операцией, например,

k += 2 эквивалентно k = k + 2, или ещё: x >>= 1 эквивалентно x = x >> 1 и т.д. Полный перечень бинарных операций, совмещаемых с присваиванием:
+ - * / % << >> & ^ |

#include
#include
// Подсчет количества единичных битов в двух байтах
int main() {
unsigned short x = 0x1234;
int b;
for (b=0; x!=0; x >>= 1)
if (x & 01) b++;
printf("the number of bits = %d \n", b);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Операции с присваиванием (продолжение)Кроме обычного присваивания существует ещё 10 модификаций, в которых присваивание совмещается с какой-либо

Слайд 5Лекция 26.09.11г.
Тернарная условная операция
Во многих алгоритмах часто встречается конструкция вида:
if

( условие) x=;
else x=;
Иными словами, переменная x получает значение одного

из двух выражений, в зависимости от истинности условия.
В языке С для компактной записи подобного фрагмента существует специальная тернарная условная операция:
x = условие ? <выраж1> : <выраж2>

#include
#include
#define N 57
int main() {
int i, x[N];
for (i=0; i for (i=0; i printf("%6d%c", x[i], (i%8==7 || i==N-1) ? '\n' : ' ');
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Тернарная условная операцияВо многих алгоритмах часто встречается конструкция вида:if ( условие) x=;else x=;Иными словами, переменная x

Слайд 6Лекция 26.09.11г.
Приоритет и ассоциирование операций
Всего операций: 47

Лекция 26.09.11г.Приоритет и ассоциирование операцийВсего операций: 47

Слайд 7Лекция 26.09.11г.
Приоритет и ассоциирование операций
Операции, находящиеся в одной строке таблицы

, принадлежат одной группе: имеют одинаковый приоритет и одинаковый порядок

выполнения (слева направо или наоборот).
Все 47 операций распределены по 15 группам, группа 1 имеет наивысший приоритет, а группа 15 наинизший приоритет.
1-я группа: () - вызов функции, [] – доступ к элементу массива, -> - обращение к элементу структуры через указатель, . - обращение к элементу структуры через имя структуры.
2-я группа (унарные операции): + - - унарные «плюс» и «минус», * - «разыменование» указателя, т.е. обращение к объекту, на который он указывает, & - получение адреса объекта, (тип) – приведение типа операнда, sizeof – определение размера объекта.

15-я группа: , - операция «запятая» - это бинарная операция имеющая вид: выражение1 , выражение2. Действие операции заключается в последовательном вычислении выражений, а её результатом является значение второго выражения.
Лекция 26.09.11г.Приоритет и ассоциирование операцийОперации, находящиеся в одной строке таблицы , принадлежат одной группе: имеют одинаковый приоритет

Слайд 8Лекция 26.09.11г.
Иллюстрация к операциям
#include
#include
int main() {
int i,

s, x[] = {1, 3, 5, 7, 9};
for(i =

0, s = 0; i < sizeof(x)/sizeof(x[0]); s+=x[i++]);
printf("s = %d\n", s);
system("PAUSE");
return 0;
}

кол-во элем. массива

операция «запятая»

Лекция 26.09.11г.Иллюстрация к операциям#include #include int main() { int i, s, x[] = {1, 3, 5, 7,

Слайд 9Лекция 26.09.11г.
Иллюстрация к приоритету операций
#include
#include
int main() {
int

x = 4, y = 6, k = 5, i

= 1;
y*=x+=--k<<++i;
printf("y = %d, x = %d, k = %d, i = %d\n", y, x, k, i);
system("PAUSE");
return 0;
}

Чему равно значение переменной y после вычисления выражения:
y*=x+=--k<<++i

1

2

3

4

5

Лекция 26.09.11г.Иллюстрация к приоритету операций#include #include int main() { int x = 4, y = 6, k

Слайд 10Лекция 26.09.11г.
Преобразование (приведение) типов
Приведение типа (type conversion) — преобразование значения

одного типа в значение другого типа.
Выделяют явное и неявное

приведения типов.
при явном приведении с помощью унарной операции (тип) указывается тип, к которому необходимо преобразовать значение выражения, расположенного справа от этой операции;
при неявном приведении преобразование происходит автоматически, по правилам, заложенным в языке программирования.

int main() {
int x = 32768, y = 65535;
short sx = 32768, sy = 65535; char c1 = 32768, c2 = 65535;
unsigned z = 0xffffffff;
float fz = 0xffffffff;
printf("%d %d %d %f %d\n", x, (short)x, sx, (float)x, c1);
printf("%d %d %d %f %d\n", y, (short)y, sy, (float)y, c2);
printf("%u %f %f %f\n", z, (float)z, (double)z, fz);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Преобразование (приведение) типовПриведение типа (type conversion) — преобразование значения одного типа в значение другого типа. Выделяют

Слайд 11Лекция 26.09.11г.
Преобразование (приведение) типов
Корректными преобразования типов, не вызывающими искажения значений

или потери точности, являются приведения более «узких» типов к более

«широким».
Если же значение более «широкого» типа приводится к более «узкому» типу, возможно искажение значения или потеря точности, о чем выдает предупреждение (warning) компилятор.
Явные преобразования типов всегда происходят по «инициативе» программиста, а инициатором неявных преобразований выступает компилятор в тех случаях, когда при выполнении операции ожидается один тип, а фактически присутствует другой тип.
Замечание. В некоторых случаях неявное преобразование бывает просто неосуществимым «по определению». Например, в выражении 3.0%2.0 значения 3.0 и 2.0 не преобразуется автоматически к целому типу, т.к. операция % применима только к целочисленным значениям и поэтому компилятор выдаст сообщение об ошибке (error).
Лекция 26.09.11г.Преобразование (приведение) типовКорректными преобразования типов, не вызывающими искажения значений или потери точности, являются приведения более «узких»

Слайд 12Тема
«Управляющие конструкции языка С»
Лекция 26.09.11г.

Тема «Управляющие конструкции языка С»Лекция 26.09.11г.

Слайд 13Лекция 26.09.11г.
Простые операторы и блоки
Если в конце любого выражения поставить

символ ; (точка с запятой), получим элементарную «строительную конструкцию» программы

– простой оператор:
z = foo(x+y); x+=y; 2=4*5; …

Простые операторы в программе могут располагаться последовательно, друг за другом:
temp = x+y; z = foo(temp);

Последовательность простых операторов можно заключить в фигурные скобки { и }. В этом случае получится составной оператор, или, иначе – блок, который синтаксически эквивалентен простому оператору и компилируется как самостоятельная конструкция. После закрывающей скобки точка с запятой не ставится.

Блок может быть пустым: {}
Лекция 26.09.11г.Простые операторы и блокиЕсли в конце любого выражения поставить символ ; (точка с запятой), получим элементарную

Слайд 14Лекция 26.09.11г.
Простые операторы и блоки
Внутри блока можно размещать объявления переменных:
{

int temp = x+y;
z = foo(temp);
}

Такие переменные будут локальными; они будут создаваться при входе в блок и исчезать при выходе из блока. За пределами блока локальные переменные невидимы.

Блоки могут быть вложенными (глубина вложенности не ограничивается)
{
int temp = x+y;
z = foo(temp);
{
float temp2 = x∗y;
z += bar(temp2);
}
}
Лекция 26.09.11г.Простые операторы и блокиВнутри блока можно размещать объявления переменных:{  int temp = x+y;  z

Слайд 15Лекция 26.09.11г.
Операторы простого выбора
В простейшем случае требуется выбрать для выполнения

определенный оператор, если некоторое условие истинно (т.е. его значение отлично

от 0). Это записывается так:
if (условие) оператор
Например: if (x%2) y += x/2;
Т.е. если x – нечетно, то y увеличивается, в противном случае ничего не делается.
Если при выполнении условия нужно выполнить последовательность операторов, необходимо использовать блок

В другом случае требуется выбрать для выполнения один из двух операторов, в зависимости от некоторого условия:
if (условие) оператор1 else оператор2
Например: if (a>b) c=a; else c=b;

Лекция 26.09.11г.Операторы простого выбораВ простейшем случае требуется выбрать для выполнения определенный оператор, если некоторое условие истинно (т.е.

Слайд 16Лекция 26.09.11г.
Вложенные операторы выбора
a>b
d = a
≠0
=0
Если в качестве исполняемого оператора

в операторе выбора используется другой оператор выбора, возникает ситуация вложенности

операторов выбора.
Пример: найти: d = max(a, b, c)

d = b

d = c

a>c

d = c

b>c

≠0

=0

=0

≠0

#include
#include
int main() {
int a = 4, b = 15, c = 7, d;
if (a>b)
if (a>c) d = a;
else d = c;
else
if (b>c) d = b;
else d = c;
printf("max = %d\n", d);
system("PAUSE");
return 0;
}

оператор1

оператор2

Лекция 26.09.11г.Вложенные операторы выбораa>bd = a≠0=0Если в качестве исполняемого оператора в операторе выбора используется другой оператор выбора,

Слайд 17Лекция 26.09.11г.
Вложенные операторы выбора
a>b
d = a
≠0
=0
Модифицируем алгоритм:
d = b
a>c
d =

c
b>c
≠0
=0
≠0
#include
#include
int main() {
int a = 4, b

= 15, c = 7, d = c;
if (a>b)
if (a>c) d = a;
else
if (b>c) d = b;
printf("max = %d\n", d);
system("PAUSE");
return 0;
}

=0

Неверно!


if (a>b)
{if (a>c) d = a;}
else
if (b>c) d = b;

Нужно так!


Слайд 18Лекция 26.09.11г.
Множественный выбор
Фрагмент алгоритма программы «Калькулятор»:

if (c==‘+’) r =

a + b;
else if (c==‘+’) r = a +

b;
else if (c==‘-’) r = a - b;
else if (c==‘*’) r = a * b;
else if (c==‘/’) r = a / b;
else printf(“error!\n");

Лекция 26.09.11г.Множественный выборФрагмент алгоритма программы «Калькулятор»:… if (c==‘+’) r = a + b; else if (c==‘+’) r

Слайд 19Лекция 26.09.11г.
Оператор множественного выбора switch
Для алгоритмов с множественным выбором существует

специальный оператор:

switch(c){
case '+': r = a

+ b; break;
case '-': r = a - b; break;
case '*': r = a * b; break;
case '/': r = a / b; break;
default: printf(“error!\n");
}

Лекция 26.09.11г.Оператор множественного выбора switchДля алгоритмов с множественным выбором существует специальный оператор:… switch(c){   case '+':

Слайд 20Лекция 26.09.11г.
Важное замечание!
При отсутствии операторов break реализуется совсем другой алгоритм:
c==‘+’
r

= a+b
=0
≠0
=0
≠0
=0
c==‘-’
c==‘*’
c==‘/’
r = a-b
r = a*b
r = a/b
Ошибка!
≠0
≠0
=0

switch(c){

case '+': r = a + b;
case '-': r = a - b;
case '*': r = a * b;
case '/': r = a / b;
default: printf(“error!\n");
}

Лекция 26.09.11г.Важное замечание!При отсутствии операторов break реализуется совсем другой алгоритм:c==‘+’r = a+b=0≠0=0≠0=0c==‘-’c==‘*’c==‘/’r = a-br = a*br =

Слайд 21Лекция 26.09.11г.
Оператор множественного выбора switch
Общий вид оператора switch:
switch (выражение) {

case констант-выраж1: операторы
case констант-выраж2: операторы

default: операторы
}
Действие оператора: вычисляется значение выражения и это значение последовательно сравнивается со значениями константных выражений в блоках case. Если произошло совпадение значений, выполняются операторы соответствующего блока case. Как правило, последним оператором в каждом блоке case является оператор break («прервать») и поэтому по завершению выбранного case-блока вычислительный процесс выходит за пределы оператора switch. Если совпадения значений не произошло ни для одного из case-блоков, то выполняются операторы блока default (если он есть) или вычислительный процесс сразу выходит за пределы оператора switch.
Лекция 26.09.11г.Оператор множественного выбора switchОбщий вид оператора switch:switch (выражение) {  case констант-выраж1: операторы  case констант-выраж2:

Слайд 22Лекция 26.09.11г.
Иллюстрация оператора switch
#include
#include
int main() {
int c,

i, nwhite, nother, ndigit[10];
nwhite = nother = 0;
for

(i = 0; i < 10; i++) ndigit[i] = 0;
while ((c = getchar()) != '$') {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ndigit[c-'0']++; break;
case ' ': case '\n': case '\t':
nwhite++; break;
default: nother++; break;
}
}
printf("digits =");
for (i = 0; i < 10; i++) printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n", nwhite, nother);
system("PAUSE");
return 0;
}
Лекция 26.09.11г.Иллюстрация оператора switch#include #include int main() { int c, i, nwhite, nother, ndigit[10]; nwhite = nother

Слайд 23Лекция 26.09.11г.
Операторы повторения (цикла)
Во многих алгоритмах встречается элементарная конструкция, приведенная

на блок-схеме. Она соответствует многократному (циклическому) повторению оператора (или нескольких

операторов в блоке), пока некоторое выражение не станет равным нулю (получит значение «ложь»).
Это записывается так:
while(выражение)
оператор
Такая конструкция называется циклом с предусловием.

#include
#include
int main() {
int i = 0;
char s[] = "qwerty";
while (s[i++]) ;
printf("number of characters(%s) = %d\n", s, --i);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Операторы повторения (цикла)Во многих алгоритмах встречается элементарная конструкция, приведенная на блок-схеме. Она соответствует многократному (циклическому) повторению

Слайд 24Лекция 26.09.11г.
Операторы повторения (цикла)
В языке С существует еще одна форма

цикла с предусловием, более сложная по сравнению с простейшей формой

while. В этой форме дополнительно участвуют еще два выражения, одно из которых вычисляется однократно, до проверки условия, а второе – многократно, после всех операторов, выполняемых в цикле.
Это записывается так:
for(выраж1; выраж2; выраж3)
оператор
В круглых скобках любое из выражений можно опустить, но точки с запятой обязательно должны присутствовать. Если опущено выраж2, то оно считается =1. Поэтому конструкция:
for(;;); является бесконечным циклом (как, впрочем, и конструкция while(1);
Лекция 26.09.11г.Операторы повторения (цикла)В языке С существует еще одна форма цикла с предусловием, более сложная по сравнению

Слайд 25Лекция 26.09.11г.
Пример цикла
Следующая программа преобразует символьное изображение числа, записанное в

строке s, в само число.
#include
#include
#include
int main() {

int i, n, sign;
char s[] = " -347ab";
for (i = 0; isspace(s[i]); i++) ; /* skip white space */
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-') i++; /* skip sign */
for (n = 0; isdigit(s[i]); i++) n = 10 * n + (s[i] - '0');
n*=sign;
printf("s = %s\nn = %d\n", s, n);
system("PAUSE");
return 0;
}
Лекция 26.09.11г.Пример циклаСледующая программа преобразует символьное изображение числа, записанное в строке s, в само число.#include #include #include

Слайд 26Лекция 26.09.11г.
Еще один пример цикла
Следующая программа обращает порядок символов в

строке s.
#include
#include
int main() {
int i, j;
char

s[] = "qwertyuiop", c;
printf("before: %s\n", s);
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
printf("after: %s\n", s);
system("PAUSE");
return 0;
}
Лекция 26.09.11г.Еще один пример циклаСледующая программа обращает порядок символов в строке s.#include #include int main() { int

Слайд 27Лекция 26.09.11г.
Оператор цикла с постусловием
В некоторых случаях тело цикла должно

быть выполнено хотя бы один раз, вне зависимости от истинности

выражения. Это может быть реализовано, если проверка значения выражения будет располагаться после тела цикла.
Это записывается так:
do
оператор
while(выражение);
Такая конструкция называется циклом с постусловием.
Цикл с постусловием применяется на практике значительно реже, чем цикл с предусловием.
Лекция 26.09.11г.Оператор цикла с постусловиемВ некоторых случаях тело цикла должно быть выполнено хотя бы один раз, вне

Слайд 28Лекция 26.09.11г.
Пример цикла с постусловием
#include
#include
int main() {
int

i = 0, j, sign, n = -347;
char s[10],

c;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0) s[i++] = '-';
s[i] = '\0';
printf("inverse: %s\n", s);
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
printf("result: %s\n", s);
system("PAUSE");
return 0;
}

Эта программа преобразует число n в его символьное изображение, записанное в строке s.

Обращение строки s

Лекция 26.09.11г.Пример цикла с постусловием#include #include int main() { int i = 0, j, sign, n =

Слайд 29Лекция 26.09.11г.
Оператор break
Иногда возникает необходимость прервать выполнение тела цикла

и «досрочно» выйти за пределы цикла. Это можно сделать, разместив

в теле цикла оператор break. Это оператор вызывает «безусловный переход» в точку программы, расположенную непосредственно за циклом. Оператор break может использоваться в любом операторе цикла, а также в операторе множественного выбора switch.
Пример: программа удаляет «незначащие» символы в конце строки s.

#include
#include
int main() {
int n;
char s[] = "qwerty \t\t \n\n";
printf("before:\n");
printf("number of characters(%s) = %d\n", s, strlen(s));
for (n = strlen(s)-1; n >= 0; n--)
if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n') break;
s[n+1] = '\0';
printf("after:\n");
printf("number of characters(%s) = %d\n", s, strlen(s));
system("PAUSE");
return 0;
}


Слайд 30Лекция 26.09.11г.
Оператор continue
Этот оператор похож на break, но, в отличие

от break, досрочно прекращает выполнение текущей итерации цикла, а не

всего оператора цикла. Для циклов while и do это означает переход к проверке условия, а для цикла for – вычисление выражения3, а уже затем переход к проверке условия.
Пример: подсчитать количество положительных элементов массива и найти их среднее арифметическое.

#include
#include
int main() {
int x[] = {-1, 4, 0, -3, -7, 5, 11, -2}, i, n;
double s;
for(i = 0, n = 0, s = 0.0; i < sizeof(x) / sizeof(x[0]); i++) {
if(x[i] <= 0) continue;
s += x[i]; n++;
}
if(n) s /= n;
printf("number of positive elements = %d\n", n);
printf("mean value = %f\n", s);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Оператор continueЭтот оператор похож на break, но, в отличие от break, досрочно прекращает выполнение текущей итерации

Слайд 31Лекция 26.09.11г.
Оператор перехода goto и метки
Оператор goto метка вызывает безусловный

переход к оператору (в той же самой функции) перед которым

записана метка (обычное имя, заканчивающееся символом : - двоеточие).
Пример: проверить, имеют ли два массива хотя бы один общий элемент.

#include
#include
int main() {
int a[] = {-1, 4, 0, -3, -7, 5, 11, -2}, i;
int b[] = {7, -12, 8, 9, 11, -2}, j;
int n = sizeof(a) / sizeof(a[0]);
int m = sizeof(b) / sizeof(b[0]);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (a[i] == b[j]) goto found;
printf("no common elements\n");
goto final;
found:
printf("common elements: a[%d] == b[%d]\n", i, j);
final: system("PAUSE");
return 0;
}

Лекция 26.09.11г.Оператор перехода goto и меткиОператор goto метка вызывает безусловный переход к оператору (в той же самой

Слайд 32Лекция 26.09.11г.
Оператор перехода (продолжение)
Оператор goto является «нежелательным» оператором, т.к. «запутывает»

логическую структуру программы, однако бывают ситуации, когда программа без goto

получается более громоздкой, чем с goto.
Пример: предыдущая программа без goto.

#include
#include
int main() {
int a[] = {-1, 4, 0, -3, -7, 5, 11, -2}, i;
int b[] = {7, -12, 8, 9, 11, -2}, j, found = 0;
int n = sizeof(a) / sizeof(a[0]);
int m = sizeof(b) / sizeof(b[0]);
for (i = 0; i < n && !found; i++)
for (j = 0; j < m && !found; j++)
if (a[i] == b[j]) found = 1;
if (found)
printf("common elements: a[%d] == b[%d]\n", i, j);
else
printf("no common elements\n");
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Оператор перехода (продолжение)Оператор goto является «нежелательным» оператором, т.к. «запутывает» логическую структуру программы, однако бывают ситуации, когда

Слайд 33Тема
«Функции и структура программы»
Лекция 26.09.11г.

Тема «Функции и структура программы»Лекция 26.09.11г.

Слайд 34Лекция 26.09.11г.
Функции и модульность программы
Модульность в языках программирования — принцип,

согласно которому программное средство - ПС (программа, библиотека, web-приложение и

др.) разделяется на отдельные сущности, называемые модулями. Модульность позволяет упростить задачи проектирования ПС и распределения процесса разработки ПС между группами разработчиков, а также позволяет реализовать методологию повторного использования кода.
При разбиении ПС на модули для каждого модуля указывается реализуемая им функциональность, а также связи с другими модулями. Роль модулей могут играть структуры данных, библиотеки функций, классы, сервисы и др. программные единицы, реализующие некоторую функциональность и предоставляющие интерфейс к ней.
В языке С модульность поддерживается функциями, препроцессоными командами, многофайловой структурой программы и заголовочными файлами.
Лекция 26.09.11г.Функции и модульность программыМодульность в языках программирования — принцип, согласно которому программное средство - ПС (программа,

Слайд 35Лекция 26.09.11г.
Функции и модульность программы
Функции разбивают большие вычислительные задачи на

более мелкие и позволяют инкапсулировать («упрятать» в оболочку) детали реализации

некоторой функциональности, предоставив пользователям («клиентам») формат обращения к этой функциональности (интерфейс). Это делает программу в целом более ясной и облегчает внесение в нее изменений.
Пример: функция, преобразующая символьное изображение числа, записанное в строке, в само число.

#include
int atoi_ (char s[]) {
int i, n, sign;
for (i = 0; isspace(s[i]); i++) ;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (n = 0; isdigit(s[i]); i++)
n = 10 * n + (s[i] - '0');
return sign * n;
}

#include
#include
int atoi_ (char[]);
int main() {
int n = atoi_(" -347ab");
printf("n = %d\n", n);
system("PAUSE");
return 0;
}

интерфейс

реализация

Лекция 26.09.11г.Функции и модульность программыФункции разбивают большие вычислительные задачи на более мелкие и позволяют инкапсулировать («упрятать» в

Слайд 36Лекция 26.09.11г.
Определение функции
Для того, чтобы использовать функцию, ее необходимо определить.,

т.е. описать её интерфейс (т.е. объяснить, как функцией можно воспользоваться)

и привести программный код, раскрывающий, как функция работает (т.е. записать реализацию функции на языке программирования).
Определение любой функции имеет следующую форму:
тип_возвращ_знач имя_функции(список_объявлений_арг) {
объявления и операторы
}
Различные части этого определения могут отсутствовать, но обязательными являются: имя_функции, пара круглых скобок и пара фигурных скобок, т.е. «минимальная» функция определяется так: fun(){} Это – «пустышка», которая не принимает никаких аргументов и ничего не делает (имеет пустое «тело»). Подобные функции могут использоваться в качестве «заглушек» при разработке программ.

Если при объявлении функции не указан тип возвращаемого значения, то по умолчанию подразумевается тип int.
Лекция 26.09.11г.Определение функцииДля того, чтобы использовать функцию, ее необходимо определить., т.е. описать её интерфейс (т.е. объяснить, как

Слайд 37Лекция 26.09.11г.
Функции и программы
Любая программа является набором определений типов, переменных

и функций. Функции обмениваются данными посредством передачи аргументов и возвращения

значений, а также через внешние переменные.
Функции могут следовать друг за другом в файле исходного кода в любом порядке, и текст программы можно разбивать на любое количество файлов, но при этом запрещается делить текст функции между файлами.
В результате своей работы функция может возвратить в вызывающую ее функцию результат – некоторое значение, тип которого объявлен перед именем функции. Для этого в теле функции должен присутствовать хотя бы один оператор возврата вида: return выражение;
Вызывающая функция может игнорировать (т.е. не использовать) возвращаемое значение.
Существует еще одна форма оператора возврата: return; В этом случае в вызывающую функцию ничего не передается. Тело функции может не содержать оператора возврата return ; при этом возврат из функции происходит при достижении конца блока (закрывающей скобки } ).
Лекция 26.09.11г.Функции и программыЛюбая программа является набором определений типов, переменных и функций. Функции обмениваются данными посредством передачи

Слайд 38Лекция 26.09.11г.
Пример программы с модульной структурой
Разработать программу решения линейных диофантовых

уравнений с двумя неизвестными:
ax + by = c ,


где - a, b, c, x, y – целые числа ; a и b - не нули.
К подобному уравнению сводится решение известной олимпиадной задачи: «Предположительно известно, что некоторый ценный предмет (золотой самородок) весит 20 граммов. Требуется убедиться в этом, взвесив его на обычных рычажных весах, но в нашем распоряжении имеются только гири двух типов – на 2 и на 7 граммов, по 5 штук каждого типа. Можно ли в этих условиях произвести взвешивание? Сколько гирь одного и другого типа нужно взять? Сколько существует вариантов взвешивания?»
Очевидно, что для получения ответа нужно, как минимум, решить уравнение:
2x + 7y = 20
Точнее говоря, найти множество решений …
Лекция 26.09.11г.Пример программы с модульной структуройРазработать программу решения линейных диофантовых уравнений с двумя неизвестными: ax + by

Слайд 39Лекция 26.09.11г.
Алгоритм решения диофантова уравнения
Алгоритм D. Даны три целых числа:

a, b, c (a и b - не нули). Требуется

найти два целых числа x и y таких, что ax + by = c .
D1. [Нахождение наибольшего общего делителя a и b.] Пользуясь алгоритмом Евклида, найти g - наибольший общий делитель a и b.
D2. [Проверка существования решения.] Если с % g ≠ 0, то решения не существует и выполнение алгоритма прекращается.
DЗ. [Решение вспомогательного уравнения au + bv = g.] Пользуясь расширенным алгоритмом Евклида, найти u и v .
D4. [Получение результата.] Результатом решения исходного уравнения будут множества значений:
x = u*(c/g) – (b/g)*t,
y = v*(c/g) + (a/g)*t,
где t=0, ±1, ±2, …♦

Алгоритм Евклида был рассмотрен ранее. Рассмотрим расширенный алгоритм Евклида (алгоритм EE).
Лекция 26.09.11г.Алгоритм решения диофантова уравненияАлгоритм D. Даны три целых числа: a, b, c (a и b -

Слайд 40Лекция 26.09.11г.
Расширенный алгоритм Евклида
Алгоритм EE. Даны два целых числа: a,

b (a и b - не нули). Требуется найти два

целых числа x и y таких, что ax + by = g (где g - наибольший общий делитель a и b).
EE1. [Установка начальных значений.] Положить x1=0, x2=1, y1=1, y2=0.
EE2. [Цикл с предусловием.] Если b = 0, то решение найдено и перейти к EE4.
EEЗ. [Тело цикла.] Вычислить: q=a/b, r=a-q*b, a=b, b=r, x=x2-q*x1, y=y2-q*y1, x2=x1, x1=x, y2=y1, y1=y . Перейти к шагу EE2.
EE4. [Получение результата.] Положить g=a, x=x2, y=y2 ♦

#include
#include
int main() {
int a, b, q, r, x1 = 0, x2 = 1, y1 = 1, y2 = 0;
int a0, b0, x, y, g;
printf("Input a: "); scanf("%d", &a); a0 = a;
printf("Input b: "); scanf("%d", &b); b0 = b;
while (b) {q = a / b;
r=a-q*b; a=b; b=r; x=x2-q*x1; y=y2-q*y1;
x2=x1; x1=x; y2=y1; y1=y;
}
g=a; x=x2; y=y2;
printf("Result: %d*(%d)+%d*(%d)=%d\n", a0,x,b0,y,g);
system("PAUSE");
return 0;
}

Лекция 26.09.11г.Расширенный алгоритм ЕвклидаАлгоритм EE. Даны два целых числа: a, b (a и b - не нули).

Слайд 41Лекция 26.09.11г.
Создание отдельных модулей
Оформим теперь оба алгоритма (E и EE)

в виде функций языка С.
Алгоритм Е (модифицированный):
int euclid(int a, int

b) {
while (a && b)
if(a>=b) a%=b; else b%=a;
return a + b;
}

Алгоритм ЕЕ:

extern int x, y;
int e_euclid(int a, int b) {
int q, r, x1 = 0, x2 = 1, y1 = 1, y2 = 0;
while (b) {
q = a / b;
r=a-q*b; a=b; b=r;
x=x2-q*x1; y=y2-q*y1;
x2=x1; x1=x; y2=y1; y1=y;
}
x=x2; y=y2;
return a;
}

Замечание по поводу использования внешних переменных x и y.

Лекция 26.09.11г.Создание отдельных модулейОформим теперь оба алгоритма (E и EE) в виде функций языка С.Алгоритм Е (модифицированный):int

Слайд 42Лекция 26.09.11г.
Создание отдельных модулей
Обе функции: euclid(a,b) и e_euclid(a,b) можно записать

в отдельные файлы и компилировать независимо. В этом случае основная

программа, которая и решает поставленную задачу, также размещается в отдельном файле и уже не содержит определений функций euclid(a,b) и e_euclid(a,b), а только лишь их объявления.
Лекция 26.09.11г.Создание отдельных модулейОбе функции: euclid(a,b) и e_euclid(a,b) можно записать в отдельные файлы и компилировать независимо. В

Слайд 43Лекция 26.09.11г.
Пример программы с модульной структурой
#include
#include
#include
int x,

y;
int euclid(int, int);
int e_euclid(int, int);
int main() {
int a,

b, c, g, u, v, t;
int x_max, y_max;
printf("Input a, b, c: "); scanf("%d%d%d", &a, &b, &c);
printf("Input x_max, y_max: "); scanf("%d%d", &x_max, &y_max);
if (c % euclid(a, b)) printf("***no solution\n");
else {
g = e_euclid(a, b);
for(t = -25; t <= 25; t++) {
if (fabs(u = x*(c/g) - t*(b/g)) > x_max) continue;
if (fabs(v = y*(c/g) + t*(a/g)) > y_max) continue;
printf("result: %d*(%d)+%d*(%d)=%d\n", a, u, b, v, c);
}
}
system("PAUSE");
return 0;
}

объявления функций

внешние переменные

вызовы функций


Слайд 44Лекция 26.09.11г.
Об использовании внешних переменных
Алгоритм ЕЕ (без внешних переменных):
int e_euclid(int

a, int b, int *x, int *y) {
int q,

r, x1 = 0, x2 = 1, y1 = 1, y2 = 0;
while (b) {
q = a / b;
r = a-q*b; a = b; b = r;
*x = x2-q*x1; *y = y2-q*y1;
x2=x1; x1=*x; y2=y1; y1=*y;
}
*x = x2; *y = y2;
return a;
}
Лекция 26.09.11г.Об использовании внешних переменныхАлгоритм ЕЕ (без внешних переменных):int e_euclid(int a, int b, int *x, int *y)

Слайд 45Лекция 26.09.11г.
Модифицированная программа
#include
#include
#include
int euclid(int, int);
int e_euclid(int, int,

int*, int*);
int main() {
int a, b, c, g,

u, v, t;
int x, y, x_max, y_max;
printf("Input a, b, c: "); scanf("%d%d%d", &a, &b, &c);
printf("Input x_max, y_max: "); scanf("%d%d", &x_max, &y_max);
if (c % euclid(a, b)) printf("***no solution\n");
else {
g = e_euclid(a, b, &x, &y);
for(t = -25; t <= 25; t++) {
if (fabs(u = x*(c/g) - t*(b/g)) > x_max) continue;
if (fabs(v = y*(c/g) + t*(a/g)) > y_max) continue;
printf("result: %d*(%d)+%d*(%d)=%d\n", a, u, b, v, c);
}
}
system("PAUSE");
return 0;
}

объявления функций

вызовы функций


Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика