Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Директивы и макросы препроцессора

10K
15 февраля 2007 года
Omega Red
49 / / 15.10.2006
Разработайте несколько вариантов программы вычисления произведения двух матриц с использованием директив препроцессора:
А) для целочисленных значений;
В) для вещественных значений;
С) с использованием указателей.
При тестировании программы, продемонстрировать работу всех вариантов без удаления кода соответствующего варианта с помощью директивы мультиветвления препроцессора.

Значит сделал я это умножение двух матриц, но так и не понял, что значит "не удаляя кода" и "мультиветвление препроцессора". Ведь данные всё равно придётся переписывать в коде...
Код:
#include <iostream.h>
#include <stdlib.h>

#define SUM(x, y, z) ((x) += (y)*(z))
void main()
{
    int isz1, jsz1, isz2, jsz2, i, j, k;
    do
    {
        cout<<"Vvedite koli4estvo strok 1-oy mtricy:"<<endl;
        cin>>isz1;
        cout<<"Koli4estvo stolbcov 1-oy mtricy:"<<endl;
        cin>>jsz1;
        cout<<"Strok 2-oy mtricy"<<endl;
        cin>>isz2;
        if (jsz1 != isz2)
            cout<<"Takie matricy ne peremnozhayutsya!"<<endl;
    }while (jsz1 != isz2);
    cout<<"Stolbcov 2-oy matricy"<<endl;
    cin>>jsz2;

    int **a, **b, **c, s = 0;

    a = new int * [isz1];
    for (i = 0; i < isz1; i++)
        a = new int [jsz1];

    b = new int * [isz2];
    for (i = 0; i < isz2; i++)
        b = new int [jsz2];

    c = new int * [isz1];
    for (i = 0; i < isz1; i++)
        c = new int [jsz2];

    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz1; j++)
        {
            a[j] = rand() % 3 + 1;
            cout<<a[j]<<' ';
        }
        cout<<endl;
    }
cout<<endl;
    for (i = 0; i < isz2; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            b[j] = rand() % 3 + 1;
            cout<<b[j]<<' ';
        }
        cout<<endl;
    }

    for (i = 0; i < isz1; i++)
    {
        for (k = 0; k < jsz2; k++)
        {
            for (j = 0; j < jsz1; j++)
            {
                SUM(s, a[j], b[j][k]);
            }
            c[k] = s;
            s = 0;
        }
    }

    cout<<endl;
    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            cout<<c[j]<<' ';
        }
        cout<<endl;
    }
}
9
15 февраля 2007 года
Lerkin
3.0K / / 25.03.2003
Про некоторые директивы попробую разъяснить на примере. Исключительно для твоих целей!
Код:
...
// макро для ветвления
#define INT_VAR
...

// определение типа переменной var
#if defined(INT_VAR) // если определено INT_VAR
int var;
#elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
float var
#elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
double var;
#endif
// если ничего не определено, то компиляция выдаст ошибку

...

// в зависимости от определенного выше макро,
// var может быть int, float или double
var = 1;
...


Короче, если в директиве #define оставить INT_VAR, то переменная [FONT="Courier New"]var [/FONT]будет определяться компилятором как имеющая тип int. Если поставить там FLOAT_VAR, то [FONT="Courier New"]var [/FONT]будет типа float. И если DOUBLE_VAR, то - double.
Вообщем, между директив ветвления можно писать разные варианты выполнения кода.

P.S. Директив больше, чем я указал, но - из меня очень фиговый объяснялка.:o Посмотри в любом учебнике по С.
309
16 февраля 2007 года
el scorpio
1.1K / / 19.09.2006
 
Код:
// определение типа переменной var
#if defined(INT_VAR) // если определено INT_VAR
    int var;
#elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
    float var;
#elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
    double var;
#else
    #error Не определён тип переменной. Объявите одну из директив.
#endif

Теперь если, ни одна из директив не объявлена, то при компиляции ошибка возникнет не в при первом использовании var, а в строке с директивой error
10K
16 февраля 2007 года
Omega Red
49 / / 15.10.2006
И вместо float var использовать эту строку?
float **a, **b, **c, s = 0;

Ладно, как-нибудь попробую. И ещё вопрос небольшой по этой задаче. Матрицу нужно считать с файла. Как лучше чтобы в файле матрциа располагалась, Вот так:
2 3 4
5 6 7
3 2 2
Или вот так:
2
3
4
5
6
7
3
2
2

Во втором случае проще прочитать с файла, а в первом можно поределить размеры матрицы...
10K
16 февраля 2007 года
Omega Red
49 / / 15.10.2006
Сделал я задачу значит для int и float.
Код:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

#define isz1 3
#define jsz1 3
#define isz2 3
#define jsz2 3
#define FLOAT_VAR

// определение типа переменной var
#if defined(INT_VAR) // если определено INT_VAR
int a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
float a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
double a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#else
    #error Не определён тип переменной. Объявите одну из директив.
#endif

#define SUM(x, y, z) ((x) += (y)*(z))

int i, j, k;

void getMatrixFromFile();
void multMatrix();
void printMatrix();

void main()
{
    getMatrixFromFile();
    multMatrix();
    printMatrix();
}

void getMatrixFromFile()
{
    ifstream filein;
    filein.open("matrix1.txt", ios::in);

    if (!filein)
    {
        cerr<<"Cannot open file"<<endl;
        exit(1);
    }

    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz1; j++)
        {
            filein>>a[j];
            cout<<a[j]<<' ';
        }
        cout<<endl;
    }
cout<<endl;

filein.close();

filein.open("matrix2.txt", ios::in);
    if (!filein)
    {
        cerr<<"Cannot open file"<<endl;
        exit(1);
    }

    for (i = 0; i < isz2; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            filein>>b[j];
            cout<<b[j]<<' ';
        }
        cout<<endl;
    }
    cout<<endl;
filein.close();
}

void multMatrix()
{
    for (i = 0; i < isz1; i++)
    {
        for (k = 0; k < jsz2; k++)
        {
            for (j = 0; j < jsz1; j++)
            {
                SUM(s, a[j], b[j][k]);
            }
            c[k] = s;
            s = 0;
        }
    }
}

void printMatrix()
{
    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            cout<<c[j]<<' ';
        }
        cout<<endl;
    }
}


А как сделать мультиветвление с указателями?
Начало я приблизительно знаю
Код:
#define YES_PTRS

#if defined (YES_PTRS)
..... (какой-нибудь код)
#endif

#if defined (NO_PTRS)
   #if defined(INT_VAR) // если определено INT_VAR
   int a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
   #elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
   float a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
   #elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
   double a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
   #else
       #error Не определён тип переменной. Объявите одну из директив.
   #endif
#endif


Но как именно поставить эти указатели?
309
17 февраля 2007 года
el scorpio
1.1K / / 19.09.2006
Как как:
 
Код:
#if defined(INT_VAR) // если определено INT_VAR
    #define PTRTYPE int
  #endif
//......................
PTRTYPE *ptr = new PTRTYPE; // Объявляем указатель и создаём объект данного типа
//.....................
delete ptr; // Удаляем объект
10K
17 февраля 2007 года
Omega Red
49 / / 15.10.2006
Хорошо, как указатели объявлять с помощью директив, я уже понял. Но до сих пор не понял цели третьего задания. Что именно нужно сделать?
Я вот так переделал, только думаю что использование #if в теле функций считается плохим стилем программирования (хотя и использование макрофункций не очень хороший стиль, учат же зачем-то...)
Код:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

#define isz1 3
#define jsz1 3
#define isz2 3
#define jsz2 3

#define FLOAT_VAR
#define YES_PTR

// определение типа переменной var
#if defined(INT_VAR) // если определено INT_VAR
int a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
float a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
double a[isz1][jsz1], b[isz2][jsz2], c[isz1][jsz2], s = 0;
#else
    #error Не определён тип переменной. Объявите одну из директив.
#endif


#if defined YES_PTR
#if defined(INT_VAR) // если определено INT_VAR
#define PTRTYPE int
PTRTYPE *ptr = &s;
#elif defined(FLOAT_VAR)  // иначе, если определено FLOAT_VAR
#define PTRTYPE float
PTRTYPE *ptr = &s;
#elif defined(DOUBLE_VAR)  // иначе, если определено DOUBLE_VAR
#define PTRTYPE double
PTRTYPE *ptr = &s;
#else
    #error Не определён тип переменной. Объявите одну из директив.
#endif
#endif


#define SUM(x, y, z) ((x) += (y)*(z))

int i, j, k;

void getMatrixFromFile();
void multMatrix();
void printMatrix();

void main()
{
    getMatrixFromFile();
    multMatrix();
    printMatrix();
}

void getMatrixFromFile()
{
    ifstream filein;
    filein.open("matrix1.txt", ios::in);

    if (!filein)
    {
        cerr<<"Cannot open file"<<endl;
        exit(1);
    }

    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz1; j++)
        {
            filein>>a[j];
            cout<<a[j]<<' ';
        }
        cout<<endl;
    }
cout<<endl;

filein.close();

filein.open("matrix2.txt", ios::in);
    if (!filein)
    {
        cerr<<"Cannot open file"<<endl;
        exit(1);
    }

    for (i = 0; i < isz2; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            filein>>b[j];
            cout<<b[j]<<' ';
        }
        cout<<endl;
    }
    cout<<endl;
filein.close();
}

void multMatrix()
{
    for (i = 0; i < isz1; i++)
    {
        for (k = 0; k < jsz2; k++)
        {
            for (j = 0; j < jsz1; j++)
            {
                #if defined PTRTYPE
                SUM(*ptr, a[j], b[j][k]);
                #else
                SUM(s, a[j], b[j][k]);
                #endif
            }
            c[k] = s;
            s = 0;
        }
    }
}

void printMatrix()
{
    for (i = 0; i < isz1; i++)
    {
        for (j = 0; j < jsz2; j++)
        {
            cout<<c[j]<<' ';
        }
        cout<<endl;
    }
}
9
17 февраля 2007 года
Lerkin
3.0K / / 25.03.2003
Цитата: Omega Red
... только думаю что использование #if в теле функций считается плохим стилем программирования (хотя и использование макрофункций не очень хороший стиль, учат же зачем-то...)


Отнюдь. В языке С никуда особо не денешься от макросов. Если бы С++, тогда ты использовал бы шаблоны (templates).

upd: Я вот не знаю, как в С с overload... Вроде бы - никак...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог