Приоритет операций и порядок выполнения (ассоциативность)
Приоритет и ассоциативность операций влияют на порядок группирования операндов и порядок вычислений в выражениях С. Например, приоритет выполнения операций необходимо учитывать при составлении сложных арифметических формул.
Операции, приведенные в одной группе таблицы, имеют одинаковый приоритет и ассоциативность. Порядок убывания приоритета сверху вниз.
Таблица 6.2 - Приоритет операций
Приоритет | Знак операции | Тип операции | Ассоциативность (порядок выполнения) |
() [ ] .–> | Первичные | → слева направо | |
– ~ ! * & ++ -- sizeof, приведение типов ( ) | Унарные | ← справа налево | |
* / % | Мультипликативные | → | |
+ - | Аддитивные | → | |
<< >> | Сдвиги | → | |
< > <= > = | Отношение | → | |
= = ! = | Отношение | → | |
& | Поразрядное "и" | → | |
^ | Поразрядное исключающее "или" | → | |
| | Поразрядное включающее "или" | → | |
&& | Логическое "и" | → |
Продолжение таблицы 6.2
Приоритет | Знак операции | Тип операции | Ассоциативность (порядок выполнения) | |||
| | | Логическое "или" | → | ||||
? : | Условная (тернарная) | ← | ||||
= | * = | / = | % = | Простое и составное присваивание | ← | |
+ = | – = | << = | >> = | |||
& = | | = | ^ = | ||||
, | Последовательное вычисление | → |
Если несколько операций одного приоритета встречаются в выражении, то они применяются в соответствии с ассоциативностью.
Примеры. а = b&ÆхFF + 5; // вычисляется как а = b&(Æх FF + 5);
b=а + с >> 1; // как b=(а +с) >> 1;
с = а + + + b/5; //какс=(а + +) + ( b/5);
Мультипликативные, аддитивные и поразрядные операции обладают свойством коммутативности. Компилятор вычисляет выражения с учётом приоритета в любом порядке, даже если есть скобки. Определённый порядок вычисления (,) операндов гарантируют операции: последовательного вычисления, логические «И» (&&)и «ИЛИ» (||), условная операция(? :).
Запятые в вызовах функций не являются операциями последовательного вычисления и не обеспечивают гарантий вычисления слева направо. Логические операции вычисляют минимальное число операндов, необходимых для определения результатов выражения.
func (i + 1, i = j + 2); //. Не гарантирует порядок вычисления фактических
// аргументов
i= 0;// iимеет тип int по умолчанию
a [++ i] = i; // порядок вычисления левого и правого операндов не
// гарантируются a [0] = 0 или a[1]=1
(x - 5) && ++ i // Если x =5, то ++ i не вычисляется
int x, y, z, f();
z = x > y || f(x, y); // Если x > y,то значение z = 1 «Истина», а f( ) –не
// вызывается
// если x £ y, то f() вызывается, тогда z=0,
// eсли f( ) возвращает нулевое значение, или z = 1,
// если f( ) возвращает не нулевое значение
// printf (“%d %d \n“, ++n, p()2, n)
//в функцию может передаваться n или n+1.
Преобразование типов
В выражениях С переменные различных типов в ряде случаев могут использоваться совместно; например, переменные типа char могут присутствовать в выражениях одновременно с переменными типа int.
Пример совместного использования целых и символьных переменных.
char ch='a', ans; //объявление переменныхchиans
printf("значение ch + 3 = %d", ch+3); //вывод значенияch+3
ans = ch % 3;// определение остатка от целочисленного деления
printf("\n\n значение ans = % d\n", ans);
Поскольку char это целый тип, для него применимы все операции, операнды которых могут иметь тип int. Целые по умолчанию - это величины со знаком signed.
С переменными вещественного типа (float, double и др.) применимы все операции, допустимые для целого типаint,за исключением операции остатка от деления (%).
Преобразования типов бывают явные и неявные. Синтаксис операции явного преобразования типа
(<новый_тип>) <операнд>
или
<новый_тип> (<операнд>).
Ряд операций может в зависимости от типов своих операндов вызывать неявное преобразование значения операнда из одного типа в другой (преобразование по умолчанию).
Рассмотрим результаты таких преобразований.
Данные типа charили short intмогут использоваться везде, где используется тип int. Во всех случаях значение преобразуется к целому типу
Арифметические операции над числами с плавающей точкой (floatиdouble) по умолчанию выполняются с двойной точностью.
Преобразования целочисленных значений в вещественные (плавающие) выполняется без осложнений, но возможна потеря точности, если для результата не предусмотрено достаточного количества битов. Преобразование значений с плавающей точкой к целочисленному типу машинно-зависимо. Результат неопределен, если значение не попадает в отведенный диапазон.
Если целое без знака (unsigned)используется вместе с простым целым, то простое целое и результат преобразуются в целое без знака.
Подавляющее большинство операций вызывает преобразование и определяет типы результата в соответствии с вышеприведенными правилами. Приведенная ниже схема преобразований реализуется по умолчанию при вычислении выражений С.
Сначала любые операнды типов char, unsigned char или short преобразуются в int, а любые операнды типа float преобразуются в double.
Затем, если какой-либо операнд имеет тип double, то другой преобразуется к типу double и типом результата будет double.
В случае, если какой-либо операнд имеет тип unsigned long, то другой преобразуется к типу unsigned long и это же будет и типом результата.
В случае, если какой-либо операнд имеет тип long, то другой преобразуется к типу long и это же будет типом результата.
В случае, если операнд имеет тип unsigned, то другой операнд преобразуется к типу unsigned, и это будет типом результата.
Объект типа void* (указатель на пустой)может быть объявлен для указания на объекты неизвестного типа.
Преобразование типа такого указателя задаётся с помощью явной операции преобразования типов.
Указатель может преобразовываться в любой из целых типов, достаточно большой для того, чтобы вместить его.
Указатель на один тип может быть преобразован в указатель на другой тип. При этом возможно преобразование указателя в указатель на объект меньшего размера и обратно без изменений.
Например, функция выделения памяти может принимать размер (в байтах) объекта, для которого выделяется память, и возвращать указателю несоответствующий тип, который может таким образом использоваться.
extern void* allos ();
doube* dp;
dp = (doube*) allos (sizeof (doube));
*dp = 2,6/8,4
Пример
#include <stdio.h>
#include <conio.h>
#include <math.h>
main()
{float r1,r2;
int a,b,b1;
unsigned c,d;
char e,f;
unsigned char g;
float f1,f2;
clrscr();
printf("ввод первого u второго вещественных чисел: ");
scanf("%f %f",&r1,&r2);
//printf("\n");
printf("вывод результатов операций для чисел: %5.2f %5.2f\n",r1,r2);
printf("!r1= %d ",!r1); printf("!r2= %d ",!r2);
printf("r1>r2 %d ",r1>r2); printf("r1<r2 %d\n",r1<r2);
printf("r1||r2 %d ",r1||r2); printf("r1&&r2 %d ",r1&&r2);
printf("r1==r2 %d ",r1==r2); printf("r1>=r2 %d\n",r1>=r2);
printf("r1<=r2 %d ",r1<=r2); printf("r1!=r2 %d\n",r1!=r2);
//Вложенный блок, переменные переобъявлены: int r1,r2; float b;
{int r1,r2;
float b;
printf("ввод первого u второго целого числа: ");
scanf("%d %d",&r1,&r2);
// printf("\n");
printf("вывод результатов операций для целых чисел: %2d %2d\n",r1,r2);
printf("!r1= %d ",!r1); printf("!r2= %d ",!r2);
printf("r1>r2 %d ",r1>r2); printf("r1<r2 %d\n" ,r1<r2);
printf("r1||r2 %d ",r1||r2); printf("r1&&r2 %d ",r1&&r2);
printf("r1==r2 %d ",r1==r2); printf("r1>=r2 %d\n" ,r1>=r2);
printf("r1<=r2 %d ",r1<=r2); printf("r1!=r2 %d ",r1!=r2);
printf("~r1 %d ",~r1); printf("r1|r2 %d\n" ,r1|r2);
printf("r1^r2 %d ",r1^r2); printf("r1&r2 %d ",r1&r2);
printf("r1<<r2 %d ",r1<<r2); printf("r1>>r2 %d\n" ,r1>>r2);
printf("Исходные значения: r1=%d r2=%d\n",r1,r2);
r2=r1++; //Постфиксные операции а1++ а1--
printf("r2=r1++; r1=%d r2=%d\n",r1,r2);
--r1; r2=++r1; //Префиксные операции ++а1 --а1
printf("--r1; r2=++r1; r1=%d r2=%d\n",r1,r2);
r1-=4; r2+=5; //Составное присваивание
printf("r1-=4; r2+=5; r1=%d r2=%d\n",r1,r2);
a=r2-=2,r1+=5; //Составное присваивание
printf("a=r2-=2,r1+=5; r1=%d r2=%d a=%d\n",r1,r2,a);
a=(r1<r2)?r1:r2;//Тернарная операция если r1<r2, то а=r1 иначе а=r2
printf("a=(r1<r2)?r1:r2; a=%d\n",a);
a=r2%r1; //Остаток от деления целых
printf("а=r1%r2; "); printf("а=%d\n",r2%r1);
a=r2/r1; //Деление целых
printf("a=r2/r1; a=%d\n",a);
b=(float)r2/(float)r1; //Деление c преобразованием типов
printf("b=(float)r2/(float)r1; b=%f\n",b);
}
float q=1.3,q1=2.4,raz;
printf("Введите переменные a-(int), \
c-(unsigned), g-(unsigned char)\n");
scanf("%i,%u,%uc",&a,&c,&g);
b = (a & (c<<3));
b1 = (a & 3) << 7;
f = (a & 3) << 7;
f1 = q / (c | 0x3E);
f2 = a / (c | 0x3E);
raz=exp(q+q1)/4;
printf("g=%u, q=%5.2f, q1=%7.2f, b=%i, b1=%i, \
\n",g,q,q1,b,b1);
printf("f=%i, f1=%6.3f, f2=%6.3f, raz=%f\n",f,f1,f2,raz);
getch(); return 0;
}
/* ввод первого u второго вещественных чисел: 56 7
вывод результатов операций для чисел: 56.00 7.00
!r1= 0 !r2= 0 r1>r2 1 r1<r2 0
r1||r2 1 r1&&r2 1 r1==r2 0 r1>=r2 1
r1<=r2 0 r1!=r2 1
ввод первого u второго целого числа: 45 2
вывод результатов операций для целых чисел: 45 2
!r1= 0 !r2= 0 r1>r2 1 r1<r2 0
r1||r2 1 r1&&r2 1 r1==r2 0 r1>=r2 1
r1<=r2 0 r1!=r2 1 ~r1 -46 r1|r2 47
r1^r2 47 r1&r2 0 r1<<r2 180 r1>>r2 11
Исходные значения: r1=45 r2=2
r2=r1++; r1=46 r2=45
--r1; r2=++r1; r1=46 r2=46
r1-=4; r2+=5; r1=42 r2=51
a=r2-=2,r1+=5; r1=47 r2=49 a=49
a=(r1<r2)?r1:r2; a=47
а=r1%r2; а=2
a=r2/r1; a=1
b=(float)r2/(float)r1; b=1.042553
Введите переменные a-(int), c-(unsigned), g-(unsigned char)
-34 6 7
g=122, q =1.30, q1=2.40, b=512, b1=256,
f=0, f1=0.010, f2=519.000, raz=10.111827 */
Ход работы
1 Изучить теоретические сведения.
2 Для использования арифметических, логических и других операций, приведенных в таблице задаться выражениями, содержащими указанные операции. В качестве базы принять лабораторную работу №5.
3 Ознакомившись с приоритетом операций, показать порядок выполнения операций в конкретных выражениях с использованием скобок.
4 Для преобразования типов переменных использовать явное и неявное преобразование типов.
5 Разработать алгоритм и программу, отладить ее на компьютере.
6 Изучить выполнение операций и тип результата.
7 Получить результаты и сделать выводы по работе.
8 Оформить отчет.
9 Подготовиться к защите лабораторной работы, изучив вопросы по данной теме.
Требования к содержанию отчёта приведены в лабораторной работе №1.
Индивидуальное задание к лабораторной работе №6.
Составить программу для вычисления арифметических, логических и битовых выражений. Преобразовать полученные результаты согласно индивидуальному заданию приведенному в таблице 6.3.
Таблица 6.3 - Индивидуальные задания
вариант | арифметическая операция | арифметическая операция | логическая операция | битовая операция | преобразование: явное |
(a + b)*с | (c/ab) | чётное | a << = b | int®short | |
(a*b)-с | a|=b-c | нечётное | a >> = b | long®int | |
(a / b)+++b | a<<=b/c | (a==c)&& (b<a) | a^=b | signed®unsigned | |
++b-(~a) | a%=b | a > b | a%=b+c | double®float | |
(a+b)* sizeof(c) | (a+b)1/c | a < b | a>>=5 | int®char | |
--c*(*&a+b) | (a+b)/5 | a>=b | a&=abs(c) | long double ®double | |
A2+b2+c2 | 15ab-(1/4c) | a!=b | a<<=6 | float ®long | |
5b3-2a+c | c2+8b+10a | a||b | a&=b+c | float®char | |
4a2+5b2 | 3a2+4b-8 | a&&b | a^=b | double®int | |
3ab-4c | A3+b2-8c | !a | a%=(c+10) | double®unsigned long int | |
c2+5a3-b | A2+b2-6c | (a<b)|| (c>5) | a|=20 | float®unsigned | |
2a+4c-b4 | A+2b+3c | a>=b | a&=(b+c) | int®char | |
A2+b2 | 2(a+b)-c4 | (a>=b)|| (b<c) | a^=abs(b-c) | long double ®double | |
(a+b)2 | c2-b3 | кратное а | (a&b)^c | double®float | |
2ac-3cb | 3a-4cb | (c!=b)|| (a==10) | (a|b)>>c | double®unsigned long int | |
5c+2a4 | c5-2ab | (c<=a)&&(b!=a) | (b&&c)|(a--) | signed®unsigned | |
A+b+c | 6a+3b3+c | (b==0)|| (c<=a) | a|=b+c | int®short | |
2a+3b+4c | 4abc | (a==1)|| (b<c) | a|= (c+10) | double®int | |
A2+b3+c4 | A2+(b-c)5/3 | (a<b)&& (a>c) | a|=20 | double®float | |
A+2b+3c | (a+4b)1/3-c2 | (a>=b)|| (a<=10) | (a&b)^c | int®char | |
2(a+b)-c4 | A1/3+(b3-c) | (b<c)&& ( b!=a) | a|=b+c | long double ®double | |
c2-b3 | B3+(a-4c)1/5 | (b<c)|| (a<b) | a&=b+c | double®float | |
3a-4cb | A+2b+3c | (a==1)&&( c!=0) | a&=abs(c-b) | int®char | |
c5-2ab | 2(a+b)-c4 | (c==0)|| (b!=100) | a%=b+c | long double ®double | |
6a+3b3+c | c2-b3 | (b!=0)&& (b<c) | (a&b)^c | int®char | |
4abc | 3a-4cb | (b!=a)|| (b<=c) | a%=b+c | long double ®double | |
A2+(b-c)5/3 | c5-2ab | (c<=12)&&(c>=24) | (b|c)|(a--) | double®unsigned long int | |
(a+4b)1/3-c2 | 6a+3b3+c | ((a-b)<c)|| ((a*c) <100) | a<<=6 | float®unsigned | |
A1/3+(b3-c) | 4abc | (a<10)? (b):(b-c) | (b&c)|(a--) | int®char | |
B3+(a-4c)1/5 | A2+(b-c)5/3 | (b<=10)|| ((a+b)< (b-c)) | a^=abs(b-c) | long double ®double |
Контрольные вопросы для подготовки и самостоятельной работы
1 Какие операции называются унарными, бинарными, тернарными?
2Сколько групп приоритетов принято в С?
3 В какой последовательности выполняются операции с одинаковым приоритетом?
4 Что означает свойство коммутативности?
5 Какие операции гарантируют порядок вычисления своих операндов?
6 Для чего применяют первичные операции?
7 Какой тип операндов допустим для различных операций?
8 Все ли операнды вычисляются в выражениях, содержащих логические операции?
9 Для чего применяют преобразование типов?
10 Назовите правила неявного преобразования типов. В каких случаях возможна потеря информации при преобразовании типов?
11 В каком порядке будет выполняться конструкция f(x)&&g(y) и как будет интерпретироваться результат вызова функций, результат выражения в целом?
12 Объясните примеры, приведенные в теоретической части.
Лабораторная работа №10
Массивы. Селективная обработка массивов
(2 часа)
Цель работы: изучить работу с массивом как с составным типом данных, приёмы ввода и вывода данных, обработку одномерных массивов.
Теоретические сведения
Массив - это набор объектов (элементов) одинакового типа, доступ к которым осуществляется прямо по индексу в массиве. Обращение к массивам в С реализовано с помощью указателей (pointers).
Массив в С можно объявить следующим образом:
[Класс_памяти>] <Тип_данных> <Имя_массива> [<Размер_массива>];
<Размер_массива>может быть задан константным выражением.
Доступ к элементам массива происходит следующим образом:
<Имя_массива>[<Значение_индекса>],т.е., используя имя массива и индекс от 0 до (<Размер_массива> -1), т.е. на единицу меньше, чем <Размер_массива>.
Пример объявления массива:
char name[20];
int grad[125];
float b[30];
Массив имеет имя (name), которое является указателем на тип элементов массива и адресует первый элемент с индексом (Æ). Имя массива фактически является константным указателем, ссылающимся на начальный адрес данных, с которого расположен сам массив и может быть использовано как указатель. Обращение к элементам может осуществляться следующим образом name[0]-1-ый элемент массива, name[1]- 2-ой элемент, name[19]– последний 20-ый элемент.
При трансляции программы компилятор отводит место под объявленный массив статически, т.е. в области данных участок памяти, выделенный для массива, не может быть динамически изменен. Размер выделяемой памяти под массив можно определить по следующей формуле:
(sizeof(тип)*<Размер_массива>)байтов.
Массив размещается последовательно в памяти, т.е. каждая следующая ячейка расположена сразу после предыдущей.
В С не включены стандартные операторы, которые осуществляют работу с массивами, как стандартными типами данных. Чтобы скопировать данные из одного массива в другой необходимо организовать функцию, тело которой должно иметь примерно следующий вид:
for(i=0; i<rasm; i++) mas2[i] = mas1[i];
где rasm- размер массивов, соответствующий указанному в их объявлении
# define rasm 20
int mas2[rasm], mas1[rasm];
Пример
/* ЗАНЯТИЕ N 9
Выполнил студент группы ......... Петров Ю.В.
Применение массивов при работе с переменными
различных типов (int,float), изменение значений
переменных. Примеры приемов работы с массивами */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define N 15
#define M 10
int p[N], x[N], i, j, j1, count=0;
int y[N*2], z[N]={15,37,10,-20,-10,25,27,30,89,67,\
24,-6,22};
int *pi=y; //Два последних элемента z[N] равны 0
float *pf, mf[N];
void main()
{ clrscr(); randomize();
pf=mf;
printf("Исходный массив p[]: \n");
for (i=0;i<N;i++)
{ p[i]=random(81)-40; //Инициализация с помощью функции
printf("%4d",p[i]); //random() в интервале +40...-40
if (p[i]>0) //Выбор элементов >0 в массив х[]
{ x[count]=p[i];
mf[count]=x[count]/5.5;
count++;
}
}
printf("\n");
printf("Исходный массив z[j]: \n");
for (i=0;i<N;i++) printf("%4d",z[i]);
printf("\nРабочий массив x[count]>0 из p[i]: \n");
for (i=0;i<count;i++) printf("%4d",x[i]);
j=0;//Выбор элементов в массив у[] из z[] и р[] по условиям
for (i=0;i<N;i++)
{if (z[i]>=-M && z[i]<=(M+N) && (z[i]%2==0))
{ *pi = z[i]; pi++; j++;}
if (p[i]>=-M && p[i]<=(M+N) && (p[i]%2==0))
{ *(y+j)=p[i]; pi++; j++;}
}
j1=j;
printf("\nРабочий массив y[j] из z[i] и р[i] по условиям \n");
printf(" -M<y[j]<(M+N) и четное:\n");
for (i=0;i<j1;i++) printf("%4d",y[i]);
printf("\nРабочий массив mf[j]=x[j]/5.5 \n");
for (i=0;i<count;i++) printf("%6.4f ",*(pf+i));
//Сортировка массива x[]
for (i=0;i<count;i++)
for (j=i;j<count;j++)
if (x[i]<x[j])
{int c=x[i];x[i]=x[j];x[j]=c;
}
else continue;
//Сортировка массива у[]
for (i=0;i<j1;i++)
for (j=i;j<j1;j++)
if (y[i]<y[j])
{int c=y[i];y[i]=y[j];y[j]=c;
}
else continue;
printf("\nСортированный массив x[]: \n");
for (i=0;i<count;i++)
printf("%4d",x[i]);
printf("\nСортированный массив y[]: \n");
for (i=0;i<j1;i++)
printf("%4d",y[i]);
getch();
}
/*
Исходный массив p[]:
32 37 -34 11 30 8 -11 -38 6 -21 -27 -23 -30 -19 -29
Исходный массив z[j]:
15 37 10 -20 -10 25 27 30 89 67 24 -6 22 0 0
Рабочий массив x[count]>0 из p[i]:
32 37 11 30 8 6
Рабочий массив y[j] из z[i] и р[i] по условиям
-M<y[j]<(M+N) и четное:
10 -10 8 6 24 -6 22 0 0
Рабочий массив mf[j]=x[j]/5.5
5.8182 6.7273 2.0000 5.4545 1.4545 1.0909
Сортированный массив x[]:
37 32 30 11 8 6
Сортированный массив y[]:
24 22 10 8 6 0 0 -6 -10 */
Ход работы
1 Изучить теоретические сведения.
2 В соответствии с индивидуальным заданием разработать алгоритм инициализации массива, селективной обработки массива.
3 Разработать и набрать программу, отладить её на компьютере, изучить работу операторов.
4 Получить результаты.
5 Оформить отчет.
6 Подготовиться к защите лабораторной работы, изучив контрольные вопросы по данной теме.
Требования к содержанию отчёта приведены в лабораторной работе №1
Индивидуальное задание к лабораторной работе №9
Составить программу для обработки массива согласно индивидуальному заданию приведенному в таблице 9.1.
Таблица 9.1 - индивидуальное задание
Вар. | Условие задачи |
Найти сумму четных чисел массива | |
Вычислить произведение отрицательных чисел массива | |
Определить количество нечетных чисел массива | |
Найти сумму отрицательных чисел массива | |
Определить количество отрицательных чисел массива | |
Вычислить произведение положительных чисел массива | |
Найти сумму положительных чисел массива | |
Определить количество четных чисел массива | |
Вычислить произведение четных чисел массива | |
Найти сумму нечетных чисел массива | |
Определить количество кратных 3 чисел массива | |
Вычислить произведение нечетных чисел массива | |
Найти сумму кратных 3 чисел массива | |
Определить количество не кратных 3 чисел массива | |
Вычислить произведение кратных 3 чисел массива | |
Найти сумму не кратных 3 чисел массива | |
Определить количество кратных 4 чисел массива | |
Вычислить произведение не кратных 3 чисел массива | |
Найти сумму кратных 4 чисел массива | |
Определить количество не кратных 4 чисел массива | |
Вычислить произведение кратных 4 чисел массива | |
Найти сумму не кратных 4 чисел массива | |
Определить количество кратных 5 чисел массива | |
Вычислить произведение не кратных 4 чисел массива | |
Найти сумму кратных 5 чисел массива | |
Вычислить среднее арифметическое положительных четных элементов массива | |
Найти среднее геометрическое отрицательных нечетных элементов массива | |
Найти произведение отрицательных не кратных пяти элементов массива | |
Найти среднее арифметическое элементов массива, находящихся в интервале [-10,20] | |
Найти среднее геометрическое элементов массива, находящихся в интервале [5,20] |
Контрольные вопросы для подготовки и самостоятельной работы
1 С какого числа начинается индексация массивов в языке С?
2 Как объявляется 1-но мерный массив?
3 Какие типы языка С можно и нельзя указывать в качестве типа при объявлении массива?
4 В каких случаях размерность массива при объявлении можно не указывать?
5 Какой тип имеет имя массива?
6 Как осуществляется инициализация элементов массива?
7 Как можно инициализировать массив с элементами типа char?
8 Можно ли использовать средство typedef для объявления типа “массив”?
9 Какие альтернативные формы записи элементов массива можно использовать? Приведите примеры.
10 Каковы правила использования индексных выражений?
11 Существуют ли операции работы с массивами?
12 Какие классы памяти можно использовать при объявлении массивов?
Лабораторная работа №11
Формирование рабочих массивов с помощью
операций селекции исходного массива
(2 часа)
Цель работы: изучить и научиться применять обработку массивов по заданным логическим условиям, формирование новых массивов.
Теоретические сведения
Смотри теоретические сведения по предыдущей работе.
Пример
/* ЗАНЯТИЕ N 10
Разработал Петров Ю.В.
Объявить массивы заданной размерности, выполнить их
инициализацию с применением функции random() и явно.
Получить доступ к элементам массивов с использованием
операторов организации цикла. Переписать положительные
элементы массива x[1],x[2],...,x[N] в массив y[t], а
отрицательные - в массив z[p]. Элементы в массивах y[t]
и z[p] располагать подряд, элементы массива y1[t]
рассчитать для положительных x[i] по формуле
y1[t]=y1[t]+2*exp(b*y[t]-y[t]*y[t]),где b=N/5 */
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
# define N 20
main()
{ clrscr();
randomize();
int i,t=0,p=0,b=N/5;
int x[N],y[N],z[N]; //Объявление одномерного массива (вектора)
float y1[N]={2.3,3.4,4.0,5.2,6.6,7.9,8.34,9.8,10.4,11.2,\
10.1,9.9,8.7,7.5}; //Инициализация первых 14, остальные -0
printf("\nВывод элементов исходного массива y1[ ]\n");
for(i=0;i<N;i++)
{printf(" y1[%2d]=%4.1f",i+1,y1[i]);
if ((i+1)%5==0) printf("\n");
}
printf("\nИнициализация одномерного массива x[N]\n");
for(i=0;i<N;i++)
{ x[i]=random(40)-20;
printf(" x[%2d]=%2d ",i+1,x[i]); //Вывод элементов
if ((i+1)%5==0) printf("\n"); //массива x[ ]
if (x[i]>=0) //Выбор положительных значений
{ y[t]=x[i]; //Расчет элементов массива y1[ ]
y1[t]=y1[t]+2*exp(b*y[t]-y[t]*y[t]); t++;
}
else {z[p]=x[i]; p++;} //Выбор отрицательных значений
}
printf("\nВывод элементов массива y[ ]>0\n");
i=0;
while ( i<t )
{ printf(" y[%2d]=%2d ",i+1,y[i]);
if ((i+1)%5==0) printf("\n");
i++;
}
printf("\n");
printf("\nВывод элементов массива y1[ ] после расчета\n");
i=0;
do
{ printf(" y1[%2d]=%3.2f",i+1,y1[i]);
if ((i+1)%5==0) printf("\n");
i++;
} while ( i<t );
printf("\n");
printf("\nВывод элементов массива z[ ]<0\n");
for(i=0;i<p;i++)
{ printf(" z[%2d]=%2d ",i+1,z[i]);
if ((i+1)%5==0) printf("\n");
}
getch();
return 1;
}
/* Вывод элементов исходного массива y1[ ]
y1[ 1]= 2.3 y1[ 2]= 3.4 y1[ 3]= 4.0 y1[ 4]= 5.2 y1[ 5]= 6.6
y1[ 6]= 7.9 y1[ 7]= 8.3 y1[ 8]= 9.8 y1[ 9]=10.4 y1[10]=11.2
y1[11]=10.1 y1[12]= 9.9 y1[13]= 8.7 y1[14]= 7.5 y1[15]= 0.0
y1[16]= 0.0 y1[17]= 0.0 y1[18]= 0.0 y1[19]= 0.0 y1[20]= 0.0
Инициализация одномерного массива x[N]
x[ 1]= 8 x[ 2]= 10 x[ 3]=- 7 x[ 4]= 13 x[ 5]=- 1
x[ 6]=-14 x[ 7]= 5 x[ 8]= 17 x[ 9]=-14 x[10]=-19
x[11]= 13 x[12]= 8 x[13]=-10 x[14]=-16 x[15]= 5
x[16]= 9 x[17]=-11 x[18]=-12 x[19]=-16 x[20]=- 3
Вывод элементов массива y[ ]>0
y[1]= 8 y[2]=10 y[3]=13 y[4]= 5 y[5]=17
y[6]=13 y[7]= 8 y[8]= 5 y[9]= 9
Вывод элементов массива y1[ ] после расчета
y1[1]=2.30 y1[2]=3.40 y1[3]=4.00 y1[4]=5.21 y1[5]=6.60
y1[6]=7.90 y1[7]=8.34 y1[8]=9.81 y1[9]=10.40
Вывод элементов массива z[ ]<0
z[ 1]=- 7 z[ 2]=- 1 z[ 3]=-14 z[ 4]=-14 z[ 5]=-19
z[ 6]=-10 z[ 7]=-16 z[ 8]=-11 z[ 9]=-12 z[10]=-16
z[11]=- 3 */
Ход работы
1 Изучить теоретические сведения
2 В соответствии с индивидуальным заданием, на основе программы предыдущей работы разработать алгоритм, обеспечивающий формирование рабочих массивов по заданным логическим условиям. Операции с массивами вынести в отдельную функцию.
3 Разработать программу, набрать и отладить программу на компьютере.
4 Изучить работу операторов.
5 Получить результаты.
6 Оформить отчет.
7 Подготовиться к защите лабораторной работы, изучив контрольные вопросы по данной теме.
Требования к содержанию отчёта приведены в лабораторной работе №1.
Индивидуальное задание к лабораторной работе №10
Составить программу для обработки массивов согласно индивидуальному заданию приведенному в таблице 10.1.
Таблица 10.1 - Индивидуальное задание
Вар. | Условие задачи |
Дан массив X(15). Сформировать новый массив из четных чисел исходного | |
Дан массив X(25). Сформировать новый массив из нечетных чисел исходного | |
Дан массив D(15). Сформировать новый массив из кратных 3 чисел исходного | |
Дан массив A(10). Сформировать новый массив из отрицательных чисел исходного | |
Дан массив Z(15). Сформировать новый массив из положительных четных чисел исходного | |
Дан массив X(25). Сформировать новый массив из чисел исходного, лежащих в интервале [-3,7] | |
Дан массив Y(10). Сформировать новый массив из нечетных положительных чисел исходного | |
Дан массив D(12). Сформировать новый массив из положительных кратных 3 чисел исходного | |
Дан массив A(8). Сформировать новый массив из отрицательных четных чисел исходного | |
Дан массив C(15). Сформировать новый массив из больших 8 чисел исходного | |
Дан массив B(21). Сформировать новый массив из кратных 4 чисел исходного | |
Дан массив A(12). Сформировать новый массив из отрицательных нечетных чисел исходного | |
Дан массив X(8). Сформировать новый массив из отрицательных не кратных 3 чисел исходного | |
Дан массив G(9). Сформировать новый массив из четных чисел исходного массива, стоящих на нечетных местах | |
Дан массив Y(15). Сформировать новый массив из нечетных, кратных 3 чисел исходного | |
Дан массив A(18). Сформировать новый массив из нечетных, кратных 5 чисел исходного | |
Дан массив Z(10). Сформировать новый массив из четных чисел исходного, лежащих в интервале [1,12] | |
Дан массив A(11). Сформировать новый массив из нечетных чисел исходного, лежащих в интервале [-3,15] | |
Дан массив B(10). Сформировать новый массив из номеров отрицательных четных чисел исходного | |
Дан массив A(8). Сформировать новый массив из номеров отрицательных нечетных чисел исходного | |
Дан массив C(12). Сформировать новый массив из отрицательных чисел исходного, стоящих на четных местах | |
Дан массив F(13). Сформировать новый массив из отрицательных чисел исходного, стоящих на нечетных местах | |
Дан массив H(12). Сформировать новый массив из положительных чисел исходного, стоящих на четных местах | |
Дан массив V(19). Сформировать новый массив из отрицательных чисел исходного, лежащих в диапазоне [-20,-5] | |
Дан массив N(11). Сформировать новый массив из отрицательных кратных 5 чисел исходного | |
Дан массив K(15). Сформировать новый массив из положительных чисел исходного, стоящих на нечетных местах | |
Дан массив Y(11). Сформировать новый массив из отрицательных не кратных 5 чисел исходного | |
Дан массив Z(14). Сформировать новый массив из положительных кратных 5 чисел исходного | |
Дан массив R(13). Сформировать новый массив из отрицательных кратных 10 чисел исходного | |
Дан массив N(11). Сформировать новый массив из отрицательных кратных 8 чисел исходного |
Контрольные вопросы для подготовки и самостоятельной работы
1 Как производится доступ к элементам массива?
2 Какое количество операторов цикла необходимо для обработки главной или побочной диагонали массива?
3 Какие методы сортировки элементов Вы знаете?
4 Можно ли использовать указатель на тип элементов массива в качестве имени массива и что для этого необходимо?
5 Адрес какого элемента содержит имя массива?
6 Какие классы памяти можно использовать при объявлении массива?
7 Какие классы памяти используются по умолчанию?
8 Как размещаются элементы массива в памяти?
9 Как определяется количество байтов, на которое смещается указатель индексного выражения? Зависит ли смещение указателя от типа элементов массива?