Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
23-28.docx
Скачиваний:
3
Добавлен:
25.09.2019
Размер:
120.46 Кб
Скачать

Перечисления (enum)

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

enum [ имя_типа ] { список_констант };

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

enum Err {ERR__READ, ERR__WRITE, ERR_CONVERT}; Err error; switch (error){ case ERR_READ: /* операторы */ break; case ERR_WRITE: /* операторы */ break; case ERR_CONVERT: /* операторы */ break; }

Константам ERR_READ, ERR_WRITE, ERR_CONVERT присваиваются значения 0, 1 и 2 соответственно.

Другой пример:

enum {two = 2, three, four, ten = 10, eleven, fifty = ten + 40};

Константам three и four присваиваются значения 3 и 4, константе eleven — 11.

Имена перечисляемых констант должны быть уникальными, а значения могут совпадать. Преимущество применения перечисления перед описанием именованных констант и директивой #define состоит в том, что связанные константы нагляднее; кроме того, компилятор при инициализации констант может выполнять проверку типов.

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

Факториалы:

/*

Программа FRCURVE.

Эта программа производит замену либо одного горизонтального

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

фрактальной кривой с любой заданной формой

*/

#include <conio.h>

#include <graphics.h>

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

int X_max, Y_max, foregrcolor, backgrcolor, colorsum;

static int Xcur, Ycur;

float x_max, y_max, horfact, vertfact;

void boundaries_uc(void)

{

int w, h;

getaspectratio(&w, &h);

y_max = x_max * (float)Y_max * h/((float)X_max * w);

horfact = X_max/x_max;

vertfact = Y_max/y_max;

}

void initgr(void)

{

int grdriver = DETECT, grmode;

detectgraph(&grdriver, &grmode);

initgraph(&grdriver, &grmode, "");

if ( graphresult() != grOk )

printf("\nГрафика не инициализирована!\n");

foregrcolor = getcolor();

backgrcolor = getbkcolor();

colorsum = foregrcolor + backgrcolor;

X_max = getmaxx();

Y_max = getmaxy();

x_max = 10.0;

boundaries_uc();

}

int IX(float x)

{

return (int)(x * horfact + 0.5);

}

int IY(float y)

{

return Y_max - (int)(y * vertfact + 0.5);

}

void move(float x, float y)

{

Xcur = IX(x);

Ycur = IY(y);

moveto(Xcur, Ycur);

}

void draw(float x, float y)

{

int X0 = Xcur, Y0 = Ycur;

Xcur = IX(x);

Ycur = IY(y);

line(X0, Y0, Xcur, Ycur);

moveto(Xcur, Ycur);

}

void endgr(void)

{

getch();

closegraph();

}

int nmodel = 0;

float xx[30], yy[30];

void side(float xA, float yA, float xB, float yB, int n)

{

int i;

float x, y, x1, y1, dx = xB - xA, dy = yB - yA;

if ( n == 0 )

{

move(xA, yA);

draw(xB, yB);

}

else {

x1 = xA;

y1 = yA;

for (i = 1; i <= nmodel; i++)

{

x = x1;

y = y1;

x1 = xA + dx * xx[i] - dy * yy[i];

y1 = yA + dy * xx[i] + dx * yy[i];

side(x, y, x1, y1, n - 1);

}

}

}

void main(void)

{

clrscr();

int n, k, i;

float pi, theta, r, x, y, x1, y1, xC, yC, sizefactor, xmargin, phi;

printf("\nВведите 1, если в качестве базы берется горизонтальный отрезок.\nДля базы в виде правильного k-угольника введите число k (например, 4): ");

scanf("%d", &k);

printf("\nГлубина рекурсии (например, 4): ");

scanf("%d", &n);

printf("\nСколько опорных точек между (0, 0) и (1, 0)? (Например, 3): ");

scanf("%d", &nmodel);

/*

Параметр nmodel определяет количество отрезков прямой

между концевыми точками (0, 0) и (1, 0) базового отрезка.

*/

nmodel++;

printf("\nВведите пары координат (x, y) опорных точек, исключая точки (0, 0) и (1, 0).\nНапример,\n0.45 0\n0.5 0.45\n0.55 0\n\n");

for (i = 1; i < nmodel; i++)

scanf("%f %f", xx + i, yy + i);

printf("\nКоэффициент размера (1.0 - нормальный размер): ");

scanf("%f", &sizefactor);

/*

Остальные элементы массива инициализируются нулями

*/

xx[nmodel] = 1.0;

initgr();

if ( k < 3 )

{

xmargin = 0.5 * (x_max - sizefactor * (x_max - 1));

side(xmargin, 0.5 * y_max, x_max - xmargin, 0.5 * y_max, n);

}

else {

xC = x_max/2;

yC = y_max/2;

r = 0.9 * yC * sizefactor;

pi = 4 * atan(1.0);

theta = 2 * pi/k;

phi = -0.5 * theta;

x1 = xC + r * cos(phi);

y1 = yC + r * sin(phi);

for (i = 0; i < k; i++)

{

x = x1;

y = y1;

phi += theta;

x1 = xC + r * cos(phi);

y1 = yC + r * sin(phi);

side(x, y, x1, y1, n);

}

}

endgr();

}

/*

Программа SQFRACT.

Вычерчивание фрактала на основе квадратов.

*/

#include <conio.h>

#include <graphics.h>

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

int X_max, Y_max, foregrcolor, backgrcolor, colorsum;

static int Xcur, Ycur;

float x_max, y_max, horfact, vertfact;

void boundaries_uc(void)

{

int w, h;

getaspectratio(&w, &h);

y_max = x_max * (float)Y_max * h/((float)X_max * w);

horfact = X_max/x_max;

vertfact = Y_max/y_max;

}

void initgr(void)

{

int grdriver = DETECT, grmode;

detectgraph(&grdriver, &grmode);

initgraph(&grdriver, &grmode, "");

if ( graphresult() != grOk )

printf("\nГрафика не инициализирована!\n");

foregrcolor = getcolor();

backgrcolor = getbkcolor();

colorsum = foregrcolor + backgrcolor;

X_max = getmaxx();

Y_max = getmaxy();

x_max = 10.0;

boundaries_uc();

}

int IX(float x)

{

return (int)(x * horfact + 0.5);

}

int IY(float y)

{

return Y_max - (int)(y * vertfact + 0.5);

}

void move(float x, float y)

{

Xcur = IX(x);

Ycur = IY(y);

moveto(Xcur, Ycur);

}

void draw(float x, float y)

{

int X0 = Xcur, Y0 = Ycur;

Xcur = IX(x);

Ycur = IY(y);

line(X0, Y0, Xcur, Ycur);

moveto(Xcur, Ycur);

}

void endgr(void)

{

getch();

closegraph();

}

float f, fact;

void side(float xA, float yA, float xB, float yB, int n)

{

float xP, yP, xQ, yQ, xR, yR, xS, yS, fdx, fdy;

if ( n == 0 )

draw(xB, yB);

else {

fdx = fact * (xB - xA);

fdy = fact * (yB - yA);

xP = xA + fdx;

yP = yA + fdy;

xS = xB - fdx;

yS = yB - fdy;

xQ = xP + (yS - yP);

yQ = yP - (xS - xP);

xR = xQ + (xS - xP);

yR = yQ + (yS - yP);

draw(xP, yP);

side(xP, yP, xQ, yQ, n - 1);

side(xQ, yQ, xR, yR, n - 1);

side(xR, yR, xS, yS, n - 1);

draw(xB, yB);

}

}

void main()

{

clrscr();

int n, i;

float p = 1, r, R, xC, yC;

printf("Введите глубину рекурсии (например, 5): ");

scanf("%d", &n);

printf("Коэффициент уменьшения (например, 0.4): ");

scanf("%f", &f);

for(i = 0; i < n; i++)

p *= f;

fact = 0.5 * (1 - f);

initgr();

R = y_max/2.2 * (1 - f)/(1 - p);

r = R/(1 + f);

xC = x_max/2;

yC = y_max/2;

move(xC - r, yC - r);

side(xC - r, yC - r, xC + r, yC - r, n);

side(xC + r, yC - r, xC + r, yC + r, n);

side(xC + r, yC + r, xC - r, yC + r, n);

side(xC - r, yC + r, xC - r, yC - r, n);

endgr();

}