Void main ()
{floata,bx,hx,c,d,hy,z;
intn,m;
//ввод исходных данных
…
//проверка исходных данных на правильность
A<b, c<d, n>0, m>0
{hx=(b-a)/n;
hy=(d-c)/m;
//вывод заголовка и шапки таблицы
…
//Организовать циклы вычисления
for (x=a; x<=b; x+=hx)
for (y=c; y<=d; y+=hy)
{
z=fun(x,y);
printf(“\n||%4,1f|| %5.2f || %8.2f ||”,x,y,z); }
//оформление конца таблицы
}
elseprintf(“\nневерные данные”);
getch();
}
Информация с ВП-2
1-я задача общее условие
Не используя массивы разработать алгоритм и программу работы с последовательностью целых. Признак конца ввода выбрать самостоятельно.
Конкретная задача: найти сумму положительных элементов последовательности чисел.
Признаком окончания ввода будем использовать
ReturnValue
Scanf();
intscanf(“Управление строкой”,…);
возвращаемое значение =0 если ввод значения не осуществлен.
Или >=1 если произведен ввод. Номер последнего аргумента списка ввода.
#
#
Void main()
{int a, s=0;
clrscr();
printf(“Введи элементы последовательности (конец ввода символ #)\n”);
while (scanf(“%d”,&a))
{if (a>0) s+=a; }
Printf(“\nСумма положительных элементов=%d”,s);
Getch();
}
a%5==0 то число кратно 5.
Найти минимальную разность соседних элементов последовательности
#
#
Void main()
{int a, b, min=INTMAX;
clrscr();
printf(“Введи элементы последовательности (конец ввода символ #)\n”);
scanf(“%d”,&b);
while (scanf(“%d”,&a))
{if (min>(a-b)) min=a-b; b=a; }
printf(“\nМинимальная разность соседних элементов=%d”,s);
getch();
}
2-е задание
Разработать программу для реализации операций для указанных действий unsignedlong
Создать 2 вида программы для чисел заданных в 10тичной системе.
Или создать в 8ричной или 16ричной.
Из целого числа получить новое путём уменьшения каждой цифры на единицу, кроме нуля.
#
#
Void main()
{unsigned long a, b, c, p=1;
clrscr();
printf(“Введичисло=”);
scanf(“%lu”,&a);
b=0;
while (a)
{c=a%10; //выделение последней цифры
if (c) b+=(c-1)*p;
p*=10;
a/=10;
}
printf(“новоечисло=%lu”,b);
getch();
}
В восьмеричной системе
#
#
voidmain()
{unsigned long a, b=0, c, с1,d=0x7;
intk=1;
printf(“Введи целое 8-е число”);
scanf(“%lo”,&a);
while(a);
{c=a&d; //ввод последней 8-й цифры (3 разряда)
if (c) c--;
c<<(k-1)*3;
b=b¦c; k++;
a=a>>3;
}
В 16ричной системе
#
#
voidmain()
{unsigned long a, b=0, c, с1,d=0xF;
ingk=1;
printf(“Введи целое 16-е число”);
scanf(“%lo”,&a);
while(a);
{c=a&d; //ввод последней 16-й цифры (4 разряда)
if (c) c--;
c1<<(k-1)*4;
b=b¦c1; k++;
a=a>>4;
}
Массивы
Массив - фиксированная последовательность величин одного и того же типа!
Описание массива в C
Тип имя [кол-во элементов по 1-й размерности][кол-вол чисел по 2 размерности][=инициализация]
Тип – любой.
Количество элементов может быть любым intA[10];
FloatB[2][3];
Charc[2][2][10]
Размещение элемента в памяти производится в порядке более быстрого изменения последнего индекса.
Индексы элементов изменяются от нуля до количества размерности-1.
Инициализация
intA[10]={2,-1,6} – произведена инициализация первых 3-х элементов.
В двумерном массиве каждая строка задаётся в фигурных скобках.
intB[3]={{1,2,3},{-6,44,0}};
Доступкаждый индекс в отдельных квадратных скобках.
A[i], B[i][j], C[i],[j],[k].
Реализация основных действий над массивами
Одномерный массив
Ввод:
intn=5, A[5];
for(int i=0; i<n, i++)
{printf(“\n A[%d]=”,i);
scanf(“%d”,&A[i]);
}
cout>>”\nA[“>>i>>”]=”;
cin<<A[i];
Вывод:
for (int i=0; i<n; i++)
{printf(“\nA[%d]=%d”,i,A[i]);}
Двумерный массив:
Ввод:
Intn=3, B[3][3];
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{printf(“\n B[%d][%d]=”,i,j);
scanf(“%d”,&B[i],[j];}
Вывод:
for (int i=0; i<n; i++)
{for (int j=0; j<n; j++)
printf(“%5d”,B[i][j]);
printf(“\n”);
}
∑ s=0; for (int i=0; i<n; i++) s+=A[i];
Нахождение минимального элемента массива
1-й алгоритм
min=A[0];
for (int i=0; i<n; i++)
if (min>A[i]) min=A[i];
2-йалгоритм
min=INTMAX;
for (int i=0; i<n; i++)
if (min>A[i]) min=A[i];
3-йалгоритм
for (int i=0; i<n; i++)
if (A[k}<A[i]) k=i;
Сортировка
for (int k=0; k<n-1; k++)
{y=A[k];
nmin=k;
for (int i=k+1; i<n; i++)
if (y>A[i]){y=A[i]; nmin=i;}
A[nmin]=A[k];
A[k]=y;
}
for (int i=0; i<n-1; i++)
for (in j=i+1; j<n; j++)
if (A[i]>A[j])
{y=A[i];
A[i]=A[j];
A[j]=y;
}
Если количество максимальных элементов в векторе больше 3-х, то найти количество элементов расположенных между первым и последним максимальными элементами.
max=A[0];intz,k,pm,kol;
for (int i=0; i<n; i++)
if (max<A[i]) {max=A[i]; z=i;}
for (int i=0; i<n; i++)
if (max=a[i]) {k=k+1; pm=i;}
if (k>3) kol=pm-z-1;
Если количество элементов делящих на 3 больше 3 то упорядочить их в порядке возрастания.
int k, B[n],C[n], k=0, dp,y;
for (int i=0; i<n; i++)
if A[i]%3=0 {B[k]=A[i]; C[k]=i; k++}
if (k>3)
{for (int i=0; i<n-1; i++)
for (in j=i+1; j<n; j++)
if (B[i]>B[j])
{y=B[i];
B[i]=B[j];
B[j]=y;
}
}
Двухмерные массивы
Для использования алгоритмов сортировок одномерных массивов в матрицах необходимо добавить внешний цикл по новой переменной и если нужно сортировать строки, то в записи элементов добавить первый индекс с новой переменной – для строк, а для столбцов во втором индексе.
Указатели
Компилятор при обработке описания inta=5 выделяет память под переменную a и заносит туда значение 5. В программе все обращения к переменной aзаменяются компилятором на адрес области памяти в которой хранится значение переменной. В C++ есть возможность определения собственных переменных для хранения адресов оперативной памяти. Такие переменные называют указателями.
Указатель – переменная в которой хранится адрес другой переменной.
Описание указателя: тип *имя
Тип определяется типом переменной, адрес которой будет хранится в указателе.
Существует 3 вида указателей: на переменную, на функцию и на тип void.
Указатель на функцию
тип (*имя_указателя_на_функцию)([список аргументов])
int (*f ) (float x, float y);
Указатель на тип Void
Void *имя
такой указатель используется, если неизвестен тип переменной адрес которой будет хранится в указателе. При использовании такого указателя нужно использовать операцию определения типа.
(int *) a;
Основные направления использование указателей:
1)указатели предоставляют способ позволяющий функциям модифицировать передаваемые аргументы.
2)для поддержки системы динамического выделения и удаления памяти.
3)для создания и работы списков , очереди, стеки, графы, деревья и т.д.
Различают 2 формы указателей:
1)Указатель константа - Constтип *имя
2)Указатель переменная – тип *имя
Операции связанные с указателями
1) Операция взятия адреса переменной &
intx, *y=&x;
Ограничения на операции взятия адреса.
Нельзя определить адрес константы.
Нельзя определить адрес переменной описанной, как регистровая.
2)Разименование или разодресация. Выбор значения переменной, адрес которой находится в указателе *.
intx=5, *y=&x, z;
z=x; или z=*y; - результат один и тот же.
Действия над указателями +, -, ++,--, >,<,>=,<=,==, !=, * на число.
Операции сравнения для работы с указателями необходимо убедится, чтобы адрес был в указателе.
Если указатель nullили 0 то он пуст.
if (a!=null) или (a!=0) {работа с указателем}
else {Указатель не определен}
Инициализация указателей.
При определении указателя надо стреметися произвести его инициализацию. Т.к. не имеющий адреса указателя – источник ошибок.
Способы:
1)тип *имя = значение адреса или тип *имя (значение адреса)
int a, *x=&a; или *x (&a)
2)с помощью другого указателя
intp, *y=&p;
int *d=y;
3)с помощью имени массива
intB[10];
int *p=B;
4)Указателю можно присвоить явное значение в виде шестнадцатеричной константы.
0xyyyyyyyy
char *k=(char)0xB8000000 – операция приведения типа.
5)Указателю можно присвоить нулевое значение
int *c=NULL;
int *c=0;
6)инициализация указателя может быть произведена с помощью выделения памяти.
int *p=newint;
7)Инициализация указателя на функцию.
void (*Fun)(int);
в программе имеется функция
voidf1(intx)
{тело функции}
Тогда указателюFunможет быть присвоено значение f1;
Fun=f1;
Имя функции константа указатель на точку входа в функцию.
Указатели и массивы
Одномерные массивы
Имена одномерных массивов являются указателями на нулевые элементы массивов.
inta[10];
a==&a[0];
Имя массива – указатель константа.
К элементам массива можно обратится через имя массива с соответствующим именем.
a[0]=*a
a[1]=*(a+1)
a[i]=*(a+i)
a[9]=*(a+9)
int *y=a;
int a[10];
int *y;
int s=0;
for (y=a; y<a+10; y++)
s+=*y;
int a[20];
int min, *p, n=20;
min=*a;
for (p=a; p<a+n; p++)
if (*p<min) min=*p;
Двухмерные массивы
Для двухмерного массива его имя является указателем константой на массив указателей констант определяющих адреса нулевых элементов соответствующих строк. intB[2][3]
B=&B[0][0], &B[0][0], B[0][1],B[0][2]
B[1], &B[1][0], B[1][1],B[1][2]
Доступ к элементам двухмерного массиваможет быть осуществлен несколькими способами.
1)B[i][j]
*(*(B+i)+j), где массив указателя, i–адрес строки, j– адрес элемента.
2) *(B[i]+j)
float F1(float x, float y, int p)
{текстфункции}
floatx,z, w;
int k;
….
w=F1(x,z,&k);
….
*p=*p+2;
Функция – логически самостоятельная именованная часть программы, которая может принимать аргументы и возвращать какое-либо значение в точку вызова.
С функцией связано объявление (описание) и определение (задание).
Определение (задание) функции
[тип]имя_функции([список формальных аргументов])
Тело
{//описание локальных переменных
//Операторы реализующие алгоритм работы функции, среди которых может быть несколько операторов return.
}
Где, тип определяет тип возвращаемого значения передаваемого с помощью оператора return.
Если тип отсутствует то по умолчанию считается, что функция имеет тип int.
Если функция не возвращает в точку вызова значения, то тип функции будет void.
Имя функции является константой указателем на функцию.
Список формальных аргументов определяет аргументы значения которых должны поступить в функцию при её вызове.
Если список аргументов отсутствует, то остаются круглые скобки.
voidF1(void)
{….}
или
voidF1()
{….}
Описание (объявление) функции называется прототипом.
И имеет вид [тип] имя_функции([список формальных аргументов]);
Прототипы записываются в программу когда программа состоит из большого количества функций. Если прототипы присутствуют, то размещение функций может быть произведено в любом порядке.
Иначе необходимо продумывать место размещения функции.
Вызов функции может быть сделан в любом выражении.
При обращении к функции записывается имя функции и список фактических аргументов если он нужен.
Способы передачи информации между функциями
1)с помощью глобального описания данных
Глобальное описание данных размещается вне функции. Функции размещенные ниже такого описания имеют доступ к этим переменным если эти переменные не переобъявлены в переменной.
Если не используются указатели то передача ведется в одном напралении из вызывающей переменной в вызываемую. Если фактические и формальные аргументы – указатели то вызываемая функция работает с данными описанными в вызывающей функции.
2)фактических и формальных аргументов
3)смешанный
4)возврат значения в точку вызова
Формальные аргументы |
Фактические аргументы |
1)Переменная |
переменная |
|
Константа |
|
Выражение |
2)Массив |
Массив |
3)указатель |
Указатель |
Указатель на переменную |
Указатель на переменную или адрес переменной |
Указатель на массив |
Имя массива соответствующей размерности |
|
Соответствующий указатель на массив |
Указатель на функцию |
Указатель на функцию |
|
Имя функции уществующей в программе |
Имеются следующие прототипы функций
intF1(intn, floatA[][10]);
прототипвторойфункции
void F2(int n, int(*f)(int m, float B[]10]),double z);
Вызовфункций
float C[6][10];
int k;
double w;
y=F1(k,C);
F2(k,F1,w);
Динамическое выделение памяти
Выделение памяти во время работы программа под переменные и массивы.
1)с помощью функций языка C
malloc(), callloc() выделение памяти
free() – освобождение памяти.
Описание этих файлов находится в alloc.h
Прототипфункцииmalloc
void * malloc(unsignedk);
Выполнение
Функуцияmallocвозращает адрес выделенной памяти размером в Kбайт
int *a=(int*)malloc(20);
char *d;
d=(char *)malloc(100); - массив символов в 100 элементов
double *b=(double *)malloc(8); - 1 переменная
void * calloc (unsigned, unsigned m);
Функция callocвозвращает адрес выделенной области памяти для размещения nэлементов по mбайт каждый.
int *a = (int *)calloc(10,2);
int *b= (int *)calloc (n, sizeof(int));
char *d;
d=(char*)calloc(100,1);
double *b=(double *)calloc(1,8);
В случае невозможности выделения памяти возвращается значение null.
Освобождение памяти
1)Voidfree(void *)
free(a);
free(b);
free(d);
2)C++
new
указатель = newтип [количество]
int *a=new int[10];
int *b=new int[n];
char *d;
d=new char[100];
double *b=new double;
delete – удалениепамяти
delete указатель на переменную;
deleteb;
delete [] указатель на массив;
Выделение памяти под двухмерные массивы
int **A;
выделим память размерностью n*m
A=newint* [n]; //выделение памяти под массив указателей на строк
for (int i=0; i<n; i++)
A[i]=newint [m];
//Выделение памяти под каждую из m строк
Освобождение
for(int i=0; i<n; i++) delete []A[i];
delete []A;
доступA[i][j] или *(*(A+i)+j) или*(A[i]+j)
Пример использования рабочих указателей
Определить количество элементов делящихся на 7
Оформимввидефункции
intkolich(intn, int *A);
{
intkol=0;
for(int i=0; i<n; i++)
if (A[i]%7==0) kol++;
returnkol;
}
intkolich(intn, int *A);
{
intkol=0, *a;
for(a=A; a<A; a++)
if (*a%7==0) kol++;
returnkol;
}