Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: akaGM
Дата сообщения: 15.05.2008 15:43
"сделать меню на аски-символах на Борланд С под ДОС"...

господи, до сих пор этому учат/требуют...
уж лучше бы общие принципы построения/взаимодействия с интерфейсом преподавали...
Автор: regan32
Дата сообщения: 15.05.2008 16:07
akaGM

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



Цитата:
regan32
Цитата:...это мне не подходит мне надо в borlande

Чушь порешь. TurboVision и есть продукт Borland

ты не правельно понял... нельзя ее использовать надо все ручками(даже графикой рисовать нельзя) все самому писать...
Автор: autocad devoloper
Дата сообщения: 18.05.2008 22:18
Привет всем!
Собсно решил изучить с++ и столкнулся с такой проблемой!

Есть код:

int main() {
int a = 25, &b=a ;
...
}

Никак не пойму как происходит присваивание &b=a, вродебы же &b это адрес и присваивать надо адрес, тоесть &b=&a ,но это ошибка. А переменная "а" ведь не массив чтоб передавать адрес.
Весь день сижу голову ломаю как так получается две переменные а и b с одним адресом и одинаковыми значениями, нигде в книгах этого не найду.
Поможите разобраться плиз!
Автор: distance
Дата сообщения: 18.05.2008 22:54
autocad devoloper
b - это не адрес, а имя переменной, имеющее ссылочный тип.
эта запись эквивалентна такой:

int a = 25;
int& b = a; // теперь 'b' - это синоним 'а'


Цитата:
нигде в книгах этого не найду.

если это книги по C++, то проблема в книгах, или с пониманием написанного.
Автор: autocad devoloper
Дата сообщения: 19.05.2008 08:00

Цитата:
b - это не адрес, а имя переменной, имеющее ссылочный тип.
эта запись эквивалентна такой:

int a = 25;
int& b = a; // теперь 'b' - это синоним 'а'


Тоесть в данном контексте, & - не совсем оператор возвращения адреса?
Ведь запись бы типа: int b = &a; не поперла бы.
Автор: Rudia
Дата сообщения: 19.05.2008 11:08
autocad devoloper
Вот вам отрывок из Страуструпа...
[more]
Ссылку можно рассматривать как еще одно имя объекта.
В основном ссылки используются для задания параметров и возвращаемых
функциями значений , а также для перегрузки операций (см.$$7).
Запись X& обозначает ссылку на X. Например:

int i = 1;
int& r = i; // r и i ссылаются на одно и то же целое
int x = r; // x = 1
r = 2; // i = 2;

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

int ii = 0;
int& rr = ii;
rr++; // ii увеличивается на 1

Здесь операция ++ допустима, но rr++ не увеличивает саму
ссылку rr; вместо этого ++ применяется к целому, т.е. к переменной ii.
Следовательно, после инициализации значение ссылки не может быть
изменено: она всегда указывает на тот объект, к которому была привязана
при ее инициализации. Чтобы получить указатель на объект,
обозначаемый ссылкой rr, можно написать &rr.
Очевидной реализацией ссылки может служить постоянный указатель,
который используется только для косвенного обращения. Тогда инициализация
ссылки будет тривиальной, если в качестве инициализатора указан адрес
(т.е. объект, адрес которого можно получить; см. $$R.3.7).
Инициализатор для типа T должен быть адресом. Однако, инициализатор
для &T может быть и не адресом, и даже не типом T. В таких случаях
делается следующее:
[1] во-первых, если необходимо, применяется преобразование типа
(см.$$R.8.4.3);
[2] затем получившееся значение помещается во временную переменную;
[3] наконец, адрес этой переменной используется в качестве инициализатора
ссылки.
Пусть имеются описания:

double& dr = 1; // ошибка: нужен адрес
const double& cdr = 1; // нормально

Это интерпретируется так:

double* cdrp; // ссылка, представленная как указатель
double temp;
temp = double(1);
cdrp = &temp;

Ссылки на переменные и ссылки на константы различаются по следующей
причине: в первом случае создание временной переменной чревато
ошибками, поскольку присваивание этой переменной означает присваивание
временной переменной, которая могла к этому моменту исчезнуть.
Естественно, что во втором случае подобных проблем не существует.
и ссылки на константы часто используются как параметры функций
(см.$$R.6.3).
Ссылка может использоваться для функции, которая изменяет значение своего
параметра. Например:

void incr(int& aa) { aa++; }

void f()
{
int x = 1;
incr(x); // x = 2
}

По определению передача параметров имеет ту же семантику, что и
инициализация, поэтому при вызове функции incr ее параметр aa
становится другим именем для x. Лучше, однако, избегать изменяющих
свои параметры функций, чтобы не запутывать программу. В большинстве
случаев предпочтительнее, чтобы функция возвращала результат явным
образом, или чтобы использовался параметр типа указателя:

int next(int p) { return p+1; }
void inc(int* p) { (*p)++; }

void g()
{
int x = 1;
x = next(x); // x = 2
inc(&x); // x = 3
}

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

struct pair {
char* name; // строка
int val; // целое
};

[/more]
Автор: LuckyELF
Дата сообщения: 19.05.2008 21:20

Цитата:
regan32


Возможно поздно, но всеже.

[more=Вот когда-то давно писал, даже не знаю насколько работоспособно]
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <string.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

// Коды клавишь используемых в меню
#define ESC 283
#define ENTER 7181
#define UP 18432
#define DOWN 20480
#define LEFT 19200
#define RIGHT 19712

// Константы для прорисовки рамок окон
const char up_left[3]={" &#9484;&#9556;"}, up_right[3]={" &#9488;&#9559;"}, down_left[3]={" &#9492;&#9562;"};
const char down_right[3]={" &#9496;&#9565;"}, line_g[3]={" -&#9552;"}, line_v[3]={" &#9474;&#9553;"};

// Структура - описатель элументов подменю
typedef struct _tagMenuSubItem
{
    char *text;
    struct _tagMenuSubItem *next;
}tagMenuSubItem;

// Структура - описатель элумунтов меню
typedef struct _tagMenuItem
{
    char *text;
    tagMenuSubItem *first;
    struct _tagMenuItem *next;
}tagMenuItem;

void ShowWindow( int, int, int, int, char, char, char, char, char * );

tagMenuItem* AddItem( char *, tagMenuSubItem *, tagMenuItem * );
tagMenuSubItem* AddSubItem( char *, tagMenuSubItem * );
void DeleteMenuItem( tagMenuItem * );
tagMenuSubItem* ShowItemCursor( tagMenuItem *firstItem, int id, int *xCoor, char cursColor, char cursPaper );
void ShowMenuItem( tagMenuItem *, char, char );
void InitStatusLine( char * );
int ExecMenu( int *, int *, tagMenuItem *, char, char, char, char, char, char );
void InputData( void );
void FreeMatrix( void );
void InputMatrix( void );
void ShowMatrix( void );
int ShowMatrixSegment( int, int );

unsigned long memUsed = 0;
float **theMatrix;
int M, N;

int ExecMenu( int *id1, int *id2, tagMenuItem *firstItem,
                    char textColor, char textPaper,
                    char cursColor, char cursPaper,
                    char winBorder, char winShadow )
{
    tagMenuItem *p, *p1;
    tagMenuSubItem *pp, *pp1;
    int key, iid1=1, iid2, iCount1=0, iCount2=0, xCoor, yCoor, i;
    int wx1, wx2, wy1, wy2, maxLen, zSize;
    char subOpen = FALSE, *zBuf;
    zBuf = NULL;
    p = firstItem;
    _setcursortype( _NOCURSOR );
    while( p )
    {
        p = p -> next;
        iCount1++;
    }

    char quit=TRUE;
    do{
        // Show
        ShowMenuItem( firstItem, textColor, textPaper );
//        xCoor = ShowItemCursor( firstItem, iid1, CYAN, BLUE );
        pp = ShowItemCursor( firstItem, iid1, &xCoor, cursColor, cursPaper );
        if ( pp && subOpen )
        {
            pp1 = pp;
            yCoor = wy1 + 1;
            i = 1;
            while( pp1 )
            {
                if ( i == iid2 )
                {
                    textcolor( cursColor );
                    textbackground( cursPaper);
                }
                else
                {
                    textcolor( textColor );
                    textbackground( textPaper);
                }
                gotoxy( wx1 + 1, yCoor );
                cprintf( "%s", pp1 -> text );
                pp1 = pp1 -> next;
                yCoor++;
                i++;
            }
        }

        key = bioskey(0);
        switch( key )
        {
            case ESC:
                if ( subOpen )
                {
                    if ( zBuf )
                    {
                        puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
                        free( zBuf );
                    }
                    subOpen = FALSE;
                }
                else
                {
                    quit=FALSE;
                }
                break;
            case ENTER:
                if ( subOpen )
                {
                    quit = FALSE;
                }
                else
                {
                    if ( pp )
                    {
                        subOpen = TRUE;
                        iid2 = 1;
///////////////////////////////////////////////////////////////////
                    if ( zBuf )
                    {
                        puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
                        free( zBuf );
                    }
                    pp1 = pp;
                    iCount2 = 0;
                    maxLen = 0;
                    while( pp1 )
                    {
                        if ( maxLen < strlen( pp1 -> text ) )
                            maxLen = strlen( pp1 -> text );
                        pp1 = pp1 -> next;
                        iCount2++;
                    }
                    wx1 = xCoor - 1;
                    wx2 = wx1 + maxLen + 1;
                    wy1 = 2;
                    wy2 = wy1 + iCount2 + 1;
                    zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
                    zBuf = (char *) malloc( zSize );
                    if ( !zBuf )
                    {
                        printf("Not enough memory to allocate buffer\n");
                        exit(1); /* terminate program if out of memory */
                    }
                    // Show window
                    gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
                    ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
                    }
                }
                break;

            case LEFT:
                iid1--;
                if ( iid1 < 1 ) iid1 = iCount1;
                if ( subOpen )
                {
                    iid2 = 1;
                    pp = ShowItemCursor( firstItem, iid1, &xCoor, CYAN, BLUE );
///////////////////////////////////////////////////////////////////
                    if ( zBuf )
                    {
                        puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
                        free( zBuf );
                    }
                    pp1 = pp;
                    iCount2 = 0;
                    maxLen = 0;
                    while( pp1 )
                    {
                        if ( maxLen < strlen( pp1 -> text ) )
                            maxLen = strlen( pp1 -> text );
                        pp1 = pp1 -> next;
                        iCount2++;
                    }
                    wx1 = xCoor - 1;
                    wx2 = wx1 + maxLen + 1;
                    wy1 = 2;
                    wy2 = wy1 + iCount2 + 1;
                    zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
                    zBuf = (char *) malloc( zSize );
                    if ( !zBuf )
                    {
                        printf("Not enough memory to allocate buffer\n");
                        exit(1); /* terminate program if out of memory */
                    }
                    // Show window
                    gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
                    ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
                }
                break;

            case RIGHT:
                iid1++;
                if ( iid1 > iCount1 ) iid1 = 1;
                if ( subOpen )
                {
                    iid2 = 1;
                    pp = ShowItemCursor( firstItem, iid1, &xCoor, CYAN, BLUE );
///////////////////////////////////////////////////////////////////
                    if ( zBuf )
                    {
                        puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
                        free( zBuf );
                    }
                    pp1 = pp;
                    iCount2 = 0;
                    maxLen = 0;
                    while( pp1 )
                    {
                        if ( maxLen < strlen( pp1 -> text ) )
                            maxLen = strlen( pp1 -> text );
                        pp1 = pp1 -> next;
                        iCount2++;
                    }
                    wx1 = xCoor - 1;
                    wx2 = wx1 + maxLen + 1;
                    wy1 = 2;
                    wy2 = wy1 + iCount2 + 1;
                    zSize = ( wx2 - wx1 + 2 ) + ( wy2 - wy1 + 1 );
                    zBuf = (char *) malloc( zSize );
                    if ( !zBuf )
                    {
                        printf("Not enough memory to allocate buffer\n");
                        exit(1); /* terminate program if out of memory */
                    }
                    // Show window
                    gettext( wx1,wy1,wx2+2,wy2+1, zBuf );
                    ShowWindow( wx1, wy1, wx2, wy2, textColor, textPaper, winBorder, winShadow, "" );
///////////////////////////////////////////////////////////////////
                }
                break;

            case UP:
                if ( subOpen )
                {
                    iid2--;
                    if ( iid2 < 1 ) iid2 = iCount2;
                }
                break;
            case DOWN:
                if ( subOpen )
                {
                    iid2++;
                    if ( iid2 > iCount2 ) iid2 = 1;
                }
                break;
        }
    }while( quit );
    _setcursortype( _NORMALCURSOR );
    if ( zBuf )
    {
        puttext( wx1,wy1,wx2+2,wy2+1, zBuf );
        free( zBuf );
    }
    ShowMenuItem( firstItem, textColor, textPaper );
    *id1 = iid1;
    *id2 = iid2;
    return key;
}

tagMenuSubItem* ShowItemCursor( tagMenuItem *firstItem, int id, int *xCoor, char cursColor, char cursPaper )
{
    tagMenuItem *p;
    int x=2, i=1;
    textcolor( cursColor );
    textbackground( cursPaper );
    p = firstItem;
    gotoxy( 1,1 );
    while( p )
    {
        if ( i == id )
        {
            gotoxy( x, 1 );
            cprintf( "%s", p -> text );
            *xCoor = x;
            return p -> first;
        }
        x += strlen( p -> text );
        p = p -> next;
        i++;
    }

    return NULL;
}

void ShowMenuItem( tagMenuItem *firstItem, char lineColor, char linePaper )
{
    tagMenuItem *p;
    int x;
    gotoxy(1,1);
    textcolor( lineColor );
    textbackground( linePaper );
    for( x=1; x<=80; x++ )
        cprintf( " " );
    p = firstItem;
    gotoxy( 2,1 );
    while( p )
    {
        cprintf( "%s", p -> text );
        p = p -> next;
    }
}

void DeleteMenuItem( tagMenuItem *firstItem )
{
    tagMenuItem *p, *p1;
    tagMenuSubItem *pp, *pp1;
    p = firstItem;
    while( p ) // Цикл удаления элументов меню
    {
        p1 = p -> next;
        pp = p -> first;
        while( pp ) // Цикл удаления элементов под меню
        {
            pp1 = pp -> next;
            free( pp -> text ); // Освобождаем память из под текстового поля
            free( pp ); // Удаляем весь элемент подменю
            pp = pp1;
        }
        free( p -> text ); // Освобождаем память из под текстового поля
        free( p ); // Удаляем весь элемент меню
        p = p1;
    }
}

tagMenuSubItem* AddSubItem( char *str, tagMenuSubItem *nextItem )
{
    tagMenuSubItem *p;
    p = (tagMenuSubItem *) malloc( sizeof(tagMenuSubItem) );

    if ( !p )
    {
        printf("Not enough memory to allocate buffer\n");
        exit(1); /* terminate program if out of memory */
    }

    p -> text = (char *)malloc( strlen(str) + 1 );
    if ( !p -> text )
    {
        printf("Not enough memory to allocate buffer\n");
        exit(1); /* terminate program if out of memory */
    }
    strcpy( p -> text, str );
    p -> next = nextItem;

    return p;
}

tagMenuItem* AddItem( char *str, tagMenuSubItem *subItem, tagMenuItem *nextItem )
{
    tagMenuItem *p;
    p = (tagMenuItem *)malloc( sizeof(tagMenuItem) );

    if ( !p )
    {
        printf("Not enough memory to allocate buffer\n");
        exit(1); /* terminate program if out of memory */
    }

    p -> text = (char *)malloc( strlen(str) + 1 );
    if ( !p -> text )
    {
        printf("Not enough memory to allocate buffer\n");
        exit(1); /* terminate program if out of memory */
    }
    strcpy( p -> text, str );
    p -> first = subItem;
    p -> next = nextItem;

    return p;
}

void ShowWindow( int x1, int y1, int x2, int y2, char wc, char wp, char b, char s, char *h )
{
    int x,y,l;
    char buf[200];
    textcolor( wc );
    textbackground( wp );
    for( y=y1; y<=y2; y++ )
        for( x=x1; x<=x2; x++ )
        {
            gotoxy( x,y );
            cprintf(" ");
        }

    for( y=y1; y<=y2; y++ )
    {
        gotoxy( x1,y ); cprintf("%c", line_v[b]);
        gotoxy( x2,y ); cprintf("%c", line_v[b]);
    }

    for( x=x1; x<=x2; x++ )
    {
        gotoxy( x,y1 ); cprintf("%c", line_g[b]);
        gotoxy( x,y2 ); cprintf("%c", line_g[b]);
    }

    gotoxy( x1,y1 ); cprintf("%c",up_left[b]);
    gotoxy( x2,y1 ); cprintf("%c",up_right[b]);
    gotoxy( x1,y2 ); cprintf("%c",down_left[b]);
    gotoxy( x2,y2 ); cprintf("%c",down_right[b]);

    l = strlen( h );
    y = (x2-x1)/2;
    x = x1 + y - l/2 + 1;
    gotoxy( x, y1 );
    cprintf("%s", h );

    if (s)
    {
        gettext( x2+1, y1+1, x2+2, y2+1, buf );
        for( x=1; x<=170; x+=2 )
            buf[x] = LIGHTGRAY;
        puttext( x2+1, y1+1, x2+2, y2+1, buf );
        gettext( x1+2, y2+1, x2+2, y2+1, buf );
        for( x=1; x<=170; x+=2 )
            buf[x] = LIGHTGRAY;
        puttext( x1+2, y2+1, x2+2, y2+1, buf );
    }
}

void InitStatusLine( char *s )
{
    int x,a,l,c=FALSE;
    l = strlen( s );
    textcolor( BLACK );
    textbackground( WHITE );
    window( 1, 25, 80, 25 );
    clrscr();
    for( x=1, a=0; a<l; a++ )
    {
        gotoxy( x,25 );
        if ( s[a]=='~' ) { c=!c; continue; }
        if ( c ) textcolor( RED ); else textcolor( BLACK );
        cprintf("%c", s[a] );
        x++;
        if ( x>80 ) break;
    }
    window( 1,1,80,25 );
}

void FreeMatrix( void )
{
    int i;
    if ( theMatrix )
    {
        for( i = 0; i <= M; i++ )
            free( theMatrix[i] );
        free( theMatrix );
    }
}

void InputData( void )
{
    int i;
    char quit=TRUE;
    FreeMatrix();
    do{
        ShowWindow( 1, 2, 80, 24, YELLOW, BLUE, 2, 0, "" );
        gotoxy( 4,4 ); textcolor( CYAN ); textbackground( BLUE );
        cprintf( "Размерность матрицы (MxN):" );
        gotoxy( 8,6 ); textcolor( BLUE ); textbackground( WHITE );
        cprintf(" ");
        gotoxy( 30, 6 ); cprintf(" ");
        gotoxy( 4,6 ); textcolor( CYAN ); textbackground( BLUE );
        cprintf( "M =" );
        gotoxy( 26,6 ); cprintf( "N =" );
        _setcursortype( _NORMALCURSOR );
        gotoxy( 8,6 ); textcolor( BLUE ); textbackground( WHITE );
        scanf( "%d", &M );
        gotoxy( 30,6 ); textcolor( BLUE ); textbackground( WHITE );
        scanf( "%d", &N );
        _setcursortype( _NOCURSOR );

        theMatrix = (float**) malloc( sizeof(float*) * M );
        if ( !theMatrix )
        {
            gotoxy( 4,8 ); textcolor( CYAN ); textbackground( BLUE );
            cprintf( " Не хватает памяти для создания массива!" );
        }
        else
        {
            memUsed += ( sizeof(float*) * M );

            for( i = 0; i <= M; i++ )
            {
                theMatrix[i] = (float*) malloc( sizeof(float) * N );
                memset( theMatrix[i], 0, sizeof(float) * N );

                if ( !theMatrix )
                {
                    gotoxy( 4,8 ); textcolor( CYAN ); textbackground( BLUE );
                    cprintf( " Не хватает памяти для создания массива!" );
                    free( theMatrix );
                    memUsed -= ( sizeof(float*) * M );
                }
                else
                {
                    quit = FALSE;
                    memUsed += ( sizeof(float) * N );
                }
            }
        }

    }while( quit );

    //InputMatrix();
    ShowMatrix();
}

void ShowMatrix( void )
{
    int key, stat, xs = 0, ys = 0;
    char quit = TRUE;
    do{
        stat = ShowMatrixSegment( ys , xs );
        key = bioskey( 0 );
        switch( key )
        {
            case ESC: quit = FALSE; break;
            case DOWN:
                if ( (stat == 1 || stat == 3) && ys < M )
                    ys++;
                break;
            case UP:
                if ( ys >= 1 ) ys--;
                break;
            case LEFT:
                if ( xs >= 1 ) xs--;
                break;
            case RIGHT:
                if ( (stat == 2 || stat == 3) && xs < N )
                    xs++;
                break;
        }
    }while (quit);
}

int ShowMatrixSegment( int is, int js )
{
    int i, j, x, y;
    int result = 0;
    window( 2, 3, 79, 23 );    textbackground( BLUE );    clrscr();
    window( 1, 1, 80, 25 ); textcolor( LIGHTGRAY );
    gotoxy( 6, 3 ); cprintf( "N" );
    gotoxy( 3, 4 ); cprintf( "M" );
    for( x = 8, j = js; (j < N) && (x < 75); j++, x += 8 )
    {
        gotoxy( x, 3 ); cprintf( "%d", j+1 );
    }

    for( y = 5, i = is; (i < M) && (y < 24); i++, y++ )
    {
        gotoxy( 3, y ); cprintf( "%d", i+1 );
    }

    textcolor( BLUE ); textbackground( WHITE );
    for( y = 5, i = is; (i < M) && (y < 24); i++, y++ )
    {
        for( x = 8, j = js; (j < N) && (x < 75); j++, x+= 8 )
        {
            gotoxy( x,y ); cprintf( "%-4.1f", theMatrix[i][j] );
        }
    }

    if ( i < M && y >= 24 ) result = 1;
    if ( j < N && x > 75 ) result = 2;
    if (( i < M && y >= 24 ) && ( j < N && x > 75 )) result = 3;
    return result;
}

void InputMatrix( void )
{
    int i, j;
    for( i = 0; i < M; i++ )
    {
        for( j = 0; j < N; j++ )
        {
        }
    }
}

void main( void )
{
    char quit=TRUE;
    int key;
    tagMenuItem *mainMenu;

    textbackground( BLACK );
    clrscr();

    mainMenu = AddItem( " Файл ",
                    AddSubItem( " Ввод исходных данных ",
                    AddSubItem( " Редактирование данных ",
                    AddSubItem( " Сохранение данных ",
                    AddSubItem( " Вывод результатов ",
                    AddSubItem( " Выход ", NULL ))))),
                 AddItem( " Обработка ",
                    AddSubItem( " Произведение сумм ",
                    AddSubItem( " Min & Max ", NULL )),
                 AddItem( " Справка ",
                    AddSubItem( " О программе ... ",
                    AddSubItem( " Помощь ",
                    NULL )),
                    NULL )) );

    int id1, id2;
    ShowWindow( 1, 2, 80, 24, YELLOW, BLUE, 2, 0, "" );
    InitStatusLine( " Памяти выделено: ~65535~ Min: ~YYYYYYYYYYY~ Max: ~ZZZZZZZZZ~ Матрица: ~MMM~x~NNN~" );


    do{
        key = ExecMenu( &id1, &id2, mainMenu, BLUE, CYAN, CYAN, BLUE, 2, 1 );
        if ( key == ESC )    {    id1 = 1;    id2 = 5;    }

        switch( id1 )
        {
            case 1:
                switch( id2 )
                {
                    case 1:
                        char str[255];
                        InputData();
                        sprintf (str, " Памяти выделено: ~%ld~ Min: ~YYYYYYYYYYY~ Max: ~ZZZZZZZZZ~ Матрица: ~MMM~x~NNN~", memUsed);
                        InitStatusLine(str);
                        break;
                    case 2: ShowMatrix (); break;
                    case 3: break;
                    case 4: break;
                    case 5: quit = FALSE; break;
                }
                break;

            case 2:
                switch( id2 )
                {
                    case 1: break;
                    case 2: break;
                }
                break;

            case 3:
                switch( id2 )
                {
                    case 1: break;
                    case 2: break;
                }
                break;
        }
    }while( quit );

    DeleteMenuItem( mainMenu );
    FreeMatrix();
}
[/more]



[more=Второй вариант проще, но меню нужно будет вытянуть самому]
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
#include <string.h>
#include <bios.h>

// Макроопределения кодов клавиш
#define ESC 283
#define F1 15104
#define ENTER 7181
#define UP 18432
#define DOWN 20480
#define LEFT 19200
#define RIGHT 19712

// Макрос вычисления адреса элемента в массиве
#define ITEM(Y,X,SIZE_X) (Y*SIZE_X + X)

// Размерность матрицы 7х8
#define ARRAY_SIZE_X 8
#define ARRAY_SIZE_Y 7

// Кол-во буферов (частей) заставки
#define IMG_BUF_COUNT 12

// ---------------------------------------------------------------------------
// Псевдографика для обрамления окошек
const char *LineG = {" &#9472;&#9552;"};
const char *LineV = {" &#9474;&#9553;"};
const char *LeftUp = {" &#9484;&#9556;"};
const char *RightUp = {" &#9488;&#9559;"};
const char *LeftDown = {" &#9492;&#9562;"};
const char *RightDown = {" &#9496;&#9565;"};

// Пункты меню
// Главное меню
const char *MainMenuItems[] = {" Файл  ",
                                         " Обработка ",
                                         " Справка  "};

// Меню файл
const char *FileMenuItems[] = {" Загрузить данные ",
                                         " Сохранить данные ",
                                         " Ввод исходных данных ",
                                         " Редактирование данных ",
                                         " Заполнить случайными ",
                                         " Вывод результатов ",
                                         " Выход из программы "};

// Меню помощь
const char *HelpMenuItems[] = {" Руководство пользователя ",
                                         " Об авторах ... "};

const UserGuideCount = 6;    // Кол-во страниц в руководстве пользоваетеля

// Текст руководства пользователя
const char *UserGuideText[] = {
" Данные программный продукт предназначен для\r\n"
"обработки матриц.\r\n"
" Программа способна выполнять следующие функции:\r\n"
" 1. Формировать массив из модулей произведений "
"отрицательных элементов каждой строки; если таких"
"элементов в строке нет, результат будет = 0.\r\n"
" 2. Определять сумму произведений сформированного"
"массива и общее количество отрицательных\r\n"
"элементов строк.",

" 3. Определять минимальное и максимальное\r\n"
"значения произведений и менять местами строки\r\n"
"исходной матрицы, в которых они найдены.\r\n"
" Исходные данные могут быть введены как\r\n"
"с клавиатуры так и из файла, результат\r\n"
"также может быть сохранен в файл.\r\n"
" Меню файл - данное меню предоставляет\r\n"
"набор операций по вводу исходных данных.\r\n",

" Загрузить данные - данная опция\r\n"
"позволяет загрузить данные из файла,\r\n"
"при ее выборе программа просит ввести\r\n"
"имя загружаемого файла.\r\n"
" Сохранить данные - данная опция меню\r\n"
"позволяет сохранить исходный набор\r\n"
"данных в файле, для их последующего\r\n"
"использования. Для сохранения необходимо\r\n"
"ввести имя файла.\r\n",

" Ввод исходных данных - данный пункт меню\r\n"
"позволяет ввести данные с клавиатуры в режиме\r\n"
"диалога с пользователем.\r\n"
" Редактирование данных - данная опрция меню\r\n"
"позволяет отредактировать ранее введенные или\r\n"
"загруженные данные.\r\n"
" Заполнить случайными - программа производит\r\n"
"автозаполнение матрицы случайными числами.\r\n",

" Вывод результатов - данный пункт меню\r\n"
"позволяет пользователю просмотреть результаты\r\n"
"работы программы.\r\n"
"\r\n"
" Выход из программы - данные пункт меню\r\n"
"завершает работу программы и возвращает\r\n"
"управление ОС.\r\n",

" Меню обработка. Данное меню позволяет\r\n"
"выполнять функции над матрицей. Краткое\r\n"
"описание всех функций дано выше.\r\n"
" Меню справка позволяет получить\r\n"
"справочную информацию о программе и\r\n"
"ее авторах.\r\n"};

// ---------------------------------------------------------------------------
// Определения новых типов
typedef unsigned char byte; // байт
typedef unsigned int word;     // слово

// ---------------------------------------------------------------------------
// Глобальные переменные
// Разрешение экрана в графическом режиме
int MaxX, MaxY;

// Для хранения Суммы, Мин, Мах, и кол-во отрицательных элементов
long gSum, gMin, gMax, gMinus;

// Номера строк с Мах и Мин элементами
int MinLine, MaxLine;

// Матрицы
int Matrix1 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Исходная
int Matrix2 [ARRAY_SIZE_Y][ARRAY_SIZE_X]; // Результирующая
long VectorAbs [ARRAY_SIZE_Y];                // Результирующий массив произведений

// ---------------------------------------------------------------------------
// Описание прототипов функций

// Выбирает Мах из двух целых
int max(int value1, int value2);

// Выбирает Мин из двух целых
int min(int value1, int value2);

// Рисует окошко в графическом режиме
void ShowWindow (int x1, int y1, int x2, int y2, int color);

// Рисует кнопку в графическом режиме
void ShowKey (int x, int y, int paper, int color, char *text);

// Выводит заставку в графическом режиме
int SplashScreen (void);

// Инициализирует графику
void InitGraph (void);

// Запролняет экран белыми квадратиками (в точечку) в текстовом режиме
void DeskTop (void);

// Рисует окошко в текстовом режиме
void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
                 byte Shadow, byte Color, byte Paper, const char *Title);

// Показывает на экране один элемент меню в заданной позиции и заданным цветом
void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item);

// Оконное меню
int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
             byte Shadow, byte Color, byte Paper,
             byte CursPaper, byte CursColor, const char *Title,
             int item, const char *Items[], word defaultItem);

// Рисует строку внизу экрана и выводит на ней заданный текст
// текст заключенный в ~ТЕКСТ~ выводится красным цветом
void TaskBar (const char *Text);

// Выводит окошко диалога, и считывает с клавиатуры строку с именем файла
// считанную строку и возвращает
char *GetFileName (byte xPos, byte yPos, byte xSize);

// Сохраняет указанную матрицу
// *Vector - указатель на матрицу
// size_y,size_x размерность матрицы (7,8)
void SaveData (int *vector, word size_y, word size_x);

// Загружает данные из файла
void LoadData (int *vector, word size_y, word size_x);

// Рисует один элемент массива в заданных координатах с
// указанным цветом и фоном
void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper);

// Для именения элемента
int ChangeItem (word x, word y);

// Рисует матрицу с возможностью редактирования
void ShowMatrix (int *vector, word size_y, word size_x);

// Выполняет ввод матрицы
void InputMatrix (int *vector, int size_y, int size_x);

// Заполняет матрицу случайными числами из диапозона [-50;50]
void RandMatrix (int *vector, int size_y, int size_x);

// Показывает резутаты работы
void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect,
                     long pMin, long pMax, long pSum, long pMinus, int *m_vect,
                     int nMin, int nMax);

// Выполняе решение
void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector,
                             long *pMin, long *pMax, long *pSum, long *pMinus,
                             int *r_vect, int *n_Min, int *n_Max);

// Главная функция - управляет работой всей программы
void AppRun (void);

// Выводин информацию о разработчиках
void About (void);

// Выводит одну страницу руководства пользователя
void ShowUserGuide (const char *Text);

// Выполняет работу диалога руководство пользователя
void UserGuide (void);

// Востанавливает часть экрана
void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf);

// Сохраняет часть экрана
byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize);

// ---------------------------------------------------------------------------
// Определения тел функций

// Выбирает Мах из двух целых
int max(int value1, int value2)
{
    return ( (value1 > value2) ? value1 : value2);
}

// Выбирает Мин из двух целых
int min(int value1, int value2)
{
    return ( (value1 < value2) ? value1 : value2);
}

// Рисует окошко в графическом режиме
void ShowWindow (int x1, int y1, int x2, int y2, int color)
{
    setcolor (DARKGRAY);
    rectangle (x1,y1,x2,y2);
    rectangle (x1+3,y1+3,x2-3,y2-3);
    line (x2,y1,x2-3,y1+3);
    line (x1,y2,x1+3,y2-3);
    setfillstyle (1,LIGHTGRAY);
    floodfill (x1+2,y1+2,DARKGRAY);
    setfillstyle (1,DARKGRAY);
    floodfill (x2-2,y2-2,DARKGRAY);
    setfillstyle (1,color);
    floodfill (x1+6,y1+6,DARKGRAY);
}

// Рисует кнопку в графическом режиме
void ShowKey (int x, int y, int paper, int color, char *text)
{
    int t = strlen (text);
    setcolor (DARKGRAY);
    rectangle (x, y, x + t * 8 + 10, y + 20);
    rectangle (x + 3, y + 3, x + t * 8 + 7, y + 17);
    line (x + t * 8 + 10, y, x + t * 8 + 7, y + 13);
    line (x, y + 20, x + 3, y + 17);
    setfillstyle (1, LIGHTGRAY);
    floodfill (x + 2, y + 2, DARKGRAY);
    setfillstyle (1, DARKGRAY);
    floodfill (x + t * 8 + 8, y + 18, DARKGRAY);
    setfillstyle (1, paper);
    floodfill (x + 6, y + 6, DARKGRAY);
    settextstyle (0,0,1);
    setcolor (color);
    settextjustify(LEFT_TEXT, TOP_TEXT);
    outtextxy (x + 5, y + 7, text);
}

// Выводит заставку в графическом режиме
int SplashScreen (void)
{
    InitGraph ();
    randomize ();

    setactivepage (1);
    int midx = MaxX / 2;
    setbkcolor (CYAN);
    ShowWindow (141, 101, 499, 249, BLUE);
    ShowKey (160,217,CYAN,BLUE,"F1 - About");
    ShowKey (270,217,CYAN,BLUE,"Enter - Run");
    ShowKey (390,217,CYAN,BLUE,"ESC - Exit");
    setcolor (WHITE);
    settextstyle (0, HORIZ_DIR, 1);
    settextjustify(CENTER_TEXT, CENTER_TEXT);
    setcolor (YELLOW);
    // Вставить нужный текст
    outtextxy (midx, 115, "The Matrix v.099"); // Название проги
    outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания

    setcolor (WHITE);
    outtextxy (midx, 145, "Created by"); // Разработано

    setcolor (LIGHTCYAN);
    outtextxy (midx, 165, "Berov Andrey"); // ФИО
//    outtextxy (midx, 180, "4-4b ISE"); // Курс, группа и т.д.
    outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д.

    int step = (500 - 140) / IMG_BUF_COUNT;
    int img_size = imagesize (140, 100, 140 + step, 250);
    void *img_buf[IMG_BUF_COUNT];
    for (int i = 0; i < IMG_BUF_COUNT; i++)
    {
        img_buf[i] = new char [img_size];
        if (!img_buf[i])
        {
            printf("Нет свободной памяти! buffer %d, size %d, all size = %d\n",
                i, img_size, img_size * IMG_BUF_COUNT);
            bioskey (0);
            exit (1);
        }
        getimage (140+step*i, 100, (140+step)+step*i, 250, img_buf[i]);
    }

    setactivepage (0);
    setbkcolor (CYAN);
    cleardevice ();

    for (int y = 100; y >= 0; y--)
    {
        for (int i = 0; i < IMG_BUF_COUNT; i++)
        {
            if ( i % 2 )
                putimage (140+step*i, 100+y, img_buf[i], COPY_PUT);
            else
                putimage (140+step*i, 100-y, img_buf[i], COPY_PUT);
        }
    }

    for (int x = 0; x < IMG_BUF_COUNT; x++)
        delete [] img_buf[x];

    setactivepage (1);
    setbkcolor (CYAN);
    cleardevice ();
    ShowWindow (141, 101, 499, 249, MAGENTA);
    ShowKey (390,217,BLUE,YELLOW,"ESC - Exit");

    settextstyle (0, HORIZ_DIR, 1);
    settextjustify(CENTER_TEXT, CENTER_TEXT);
    setcolor (YELLOW);
    // Вставить нужный текст
    outtextxy (midx, 115, "The Matrix v.099"); // Название проги
    outtextxy (midx, 125, "(C) April 2004"); // Типа Дата создания

    setcolor (WHITE);
    outtextxy (midx, 145, "Демонстрационная программа");
    outtextxy (midx, 165, "выполняет работу с массивами данных");
    outtextxy (midx, 195, "Kamensk YRGTU 2004"); // Универ и т.д.

    setactivepage (0);

    int key;
    for (;;)
    {
        key = bioskey (0);
        switch (key)
        {
            case ESC: restorecrtmode (); return 0;
            case F1: // Показываеть хелп, он на второй страницы
                setvisualpage (1); // Переключим на вторую страницу
                bioskey (0);         // Подождем нажатия на кнопку
                setvisualpage (0); // Вернем первую страницы
                break;
            case ENTER: restorecrtmode (); return 1;
        }
    }
}

// Инициализирует графику
void InitGraph (void)
{
    // Выбран VGA дривер с 2-мя страницами видео памяти
    int gdriver = VGA, gmode = VGAMED, errorcode;

    // При необходимости изменить путь к драйверу (VGAEGA.BGI)
    initgraph(&gdriver, &gmode, "");
    errorcode = graphresult();

    if (errorcode != grOk)
    {
        printf("Ошибка при работе с графикой: %s\n", grapherrormsg(errorcode));
        printf("Нажмите любую клавишу для прекращения работы:");
        bioskey (0);
        exit(1); /* return with error code */
    }

    // Проинициализируем макимальным разрешением экрана
    MaxX = getmaxx ();
    MaxY = getmaxy ();
}

// Запролняет экран белыми квадратиками (в точечку) в текстовом режиме
void DeskTop (void)
{
    textcolor (WHITE);        // Цвет текста на экране
    textbackground (BLUE); // Цвет фона экрана
    _wscroll = 0;
    for (int y = 1; y <= 25; y++)
        for (int x = 1; x <= 80; x++)
        {
            gotoxy (x,y);
            cprintf ("&#9618;"); // Заполняем экран этим символом
        }
    _wscroll = 1;
}

// Рисует окошко в текстовом режиме
void ShowWin (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
                 byte Shadow, byte Color, byte Paper, const char *Title)
{
    // Расчет недостоющих координат
    int y, x, yEnd = yPos + ySize, xEnd = xPos + xSize;

    // Установка цвета символов и фона
    textcolor (Color);
    textbackground (Paper);

    // Рисуем квадратик
    for (y = yPos; y <= yEnd; y++)
        for (x = xPos; x <= xEnd; x++)
        {
            gotoxy (x, y);
            cprintf (" ");
        }

    // Проводим вертикальные линии
    for (y = yPos; y <= yEnd; y++)
    {
        gotoxy (xPos, y);    cprintf ("%c", LineV [Bolder]);
        gotoxy (xEnd, y);    cprintf ("%c", LineV [Bolder]);
    }

    // Проводим горизонтальные линии
    for (x = xPos; x <= xEnd; x++)
    {
        gotoxy (x, yPos);    cprintf ("%c", LineG [Bolder]);
        gotoxy (x, yEnd); cprintf ("%c", LineG [Bolder]);
    }

    // Рисуем уголки окошка
    gotoxy (xPos, yPos); cprintf ("%c", LeftUp [Bolder]);
    gotoxy (xPos, yEnd); cprintf ("%c", LeftDown [Bolder]);
    gotoxy (xEnd, yPos); cprintf ("%c", RightUp [Bolder]);
    gotoxy (xEnd, yEnd); cprintf ("%c", RightDown [Bolder]);

    // Если есть надпись, то выведем ее в верху окошка
    if (Title)
    {
        // Расчитаем середину окна
        int midx = xPos + (xSize / 2) - (strlen (Title) / 2) + xSize % 2;
        gotoxy (midx, yPos); cprintf ("%s", Title);
    }

    // Если окошко должно быть с тень, то нарисуем ее
    if (Shadow)
    {
        int i;
        word buf_size = xSize * 2 + 1;
        byte *pbuf;
        byte *buf = new byte [buf_size];
        gettext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf);
        for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2);
        puttext (xPos + 2, yEnd + 1, xEnd + 2, yEnd + 1, buf);
        delete [] buf;

        buf_size = ySize * 2 * 2 + 1;
        buf = new byte [buf_size];
        gettext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf);
        for (pbuf=&buf[1], i=0; i<buf_size; *pbuf=1+2+4, i+=2, pbuf+=2);
        puttext (xEnd + 1, yPos + 1, xEnd + 2, yEnd, buf);
        delete [] buf;
    }
}

// Показывает на экране один элемент меню в заданной позиции и заданным цветом
void ShowMenuItem (byte xPos, byte yPos, byte Paper, byte Color, const char *Item)
{
    textcolor (Color);
    textbackground (Paper);
    gotoxy (xPos, yPos);
    cprintf ("%s", Item);
}

// Оконное меню
int Menu (byte xPos, byte yPos, byte xSize, byte ySize, byte Bolder,
             byte Shadow, byte Color, byte Paper,
             byte CursPaper, byte CursColor, const char *Title,
             int item, const char *Items[], word defaultItem)
{
    _setcursortype (_NOCURSOR); // вырубим мигающий курсор

    // Нарисуем окошко
    ShowWin (xPos, yPos, xSize, ySize, Bolder, Shadow, Color, Paper, Title);
    int CurrItem = defaultItem;
    byte bExit = 1;
    int key;

    // Нарисуем все элементы
    for (int i=0; i < item; i++)
        ShowMenuItem (xPos+2, yPos+1+i, Paper, Color, Items[i]);

    // Цикл работы меню
    while (bExit)
    {
        // Рисуем курсор
        ShowMenuItem (xPos+2, yPos+1+CurrItem, CursPaper, CursColor, Items[CurrItem]);
        key = bioskey (0);    // Опрос клавиатуры

        // Скрываем выделенный пункт
        ShowMenuItem (xPos+2, yPos+1+CurrItem, Paper, Color, Items[CurrItem]);

        // Обрабатываем нажатие клавиш
        switch (key)
        {
            case DOWN: CurrItem++;    // нажали вниз
                if (CurrItem >= item) CurrItem = 0;
                break;

            case UP: CurrItem--;        // нажали вверх
                if (CurrItem < 0) CurrItem = item - 1;
                break;
            case ESC: CurrItem = -1;    // ESCAPE
            case ENTER: bExit = 0; break; // ENTER
        }
    }

    _setcursortype (_NORMALCURSOR); // Включим курсор
    return CurrItem;    // Вернем номер выбранного пункта (начинается с 0)
}

// Рисует строку внизу экрана и выводит на ней заданный текст
// текст заключенный в ~ТЕКСТ~ выводится красным цветом
void TaskBar (const char *Text)
{
    word i = 80;
    byte color = 0;
    _wscroll = 0;    // Чтобы экран не "убегал" вверх
    // установим начальную позицию и цвета
    gotoxy (1,25);
    textcolor (BLACK);
    textbackground (WHITE);

    // Рисуем линию из начальной позиции
    while (i--)
        cprintf (" ");

    // Вывод текста
    i = 0;
    gotoxy (1,25);
    while (Text[i])
    {
        // Если встретили в тексте ~, то переключим цвет
        if (Text[i] == '~')
            color = !color;
        else    // Иначе просто выведем очедной символ
            cprintf ("%c", Text[i]);

        // Установим цвет в соответсвии с выбранным
        if (color)
            textcolor (RED);    // Красный
        else
            textcolor (BLACK);    // Черный
        i++;    // Чтоб перейте к следующему символу в строку
    }
    _wscroll = 1;    // Включим скролирование экрана
}

// Выводит окошко диалога, и считывает с клавиатуры строку с именем файла
// считанную строку и возвращает
char *GetFileName (byte xPos, byte yPos, byte xSize)
{
    // Запомним кусочек экрана под окошком
    byte *buf = SaveScreen (xPos, yPos, xSize + 2, 2 + 1);
    char str[255], param[25], sparam[50] = {"%"};
    ShowWin (xPos, yPos, xSize, 2, 1, 1, LIGHTCYAN, BLUE, " Укажите имя файла ");
    gotoxy (xPos+1, yPos+1);
    itoa(xSize, param, 10);
    strcat (sparam, param);
    strcat (sparam, "s");
    scanf (sparam, str);
    // Востановим испорченный кусочек экрана
    RestoreScreen (xPos, yPos, xSize + 2, 2 + 1, buf);
    return str;
}

// Сохраняет указанную матрицу
// *Vector - указатель на матрицу
// size_y,size_x размерность матрицы (7,8)
void SaveData (int *vector, word size_y, word size_x)
{
    // Выведем диалог, чтобы нам написали имя файла
    char *str = GetFileName (25, 5, 50);

    // Откроем указанный файл
    FILE *out = fopen (str, "wb");

    // Если не получилось открыть файл, то ничего делать не будем
    if (!out)
    {
        printf ("Ошибка! Не могу открыть файл данных.\n");
        return;
    }

    // цикл записи данных в файл
    for (int y = 0, *ptr = vector; y < size_y; y++)
    {
        for (int x = 0; x < size_x; x++, ptr++)
            fprintf (out, "%d ", *ptr);
        fprintf (out, "\n");
    }

    fclose (out);    // Закроем файл
}

// Загружает данные из файла
void LoadData (int *vector, word size_y, word size_x)
{
    // Выведем диалог, чтобы взять у пользователя имя файла
    char *str = GetFileName (25, 5, 50);
    FILE *in = fopen (str, "rb");    // Откроем файл

    // Если не получилось, то ничего делать не будем
    if (!in)
    {
        printf ("Ошибка! Не могу открыть файл данных.\n");
        return;
    }

    // Цикл чтения данных из файла
    for (int y = 0, *ptr = vector, data; y < size_y; y++)
        for (int x = 0; x < size_x; x++, ptr++)
        {
            fscanf (in, "%d", &data);
            *ptr = data;
        }

    fclose (in);    // Закроем файл
}

// Рисует один элемент массива в заданных координатах с
// указанным цветом и фоном
void ShowVectItem (int item, word xPos, word yPos, byte Color, byte Paper)
{
    textcolor (Color);
    textbackground (Paper);
    gotoxy (xPos, yPos);
    cprintf ("%-3d", item);
}

// Для именения элемента
int ChangeItem (word x, word y)
{
    // Запомним чать экрана
    byte *buf = SaveScreen (x + 1, y + 1, 10 + 2, 2 + 1);
    // выведем окошко
    ShowWin (x + 1, y + 1, 10, 2, 1, 1, WHITE, RED, "");
    int newitem;
    gotoxy (x + 2, y + 2);
    scanf ("%3d", &newitem);    // Прочитаем новое значение с клавиатуры
    // Востановим испорченный экран
    RestoreScreen (x + 1, y + 1, 10 + 2, 2 + 1, buf);
    return newitem;
}

// Рисует матрицу с возможностью редактирования
void ShowMatrix (int *vector, word size_y, word size_x)
{
    _setcursortype (_NOCURSOR);
    word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1);
    int *ptr = vector, data;
    byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
    byte bExit = 1;

    // Окошко для вывода
    ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица ");

    // Цикл вывода данных на экран
    for (int y = 0; y < size_y; y++)
    {
        for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4)
        {
            gotoxy (pos, y + yPos + 1);
            printf ("%-3d", *ptr);
        }
    }

    // Меню для редактирования
    int x, key;
    x = y = 0;
    while (bExit)
    {
        ptr = vector + ITEM (y, x, size_x); // Вычислим Адрес текущего элемента
        // Покажем его на экране другим цветом
        ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, BLUE, LIGHTCYAN);
        key = bioskey (0);    // Прочитам клавиатуру
        // Потушим выделенный элемент
        ShowVectItem (*ptr, x*4 + xPos + 1, y + yPos + 1, LIGHTCYAN, BLUE);

        // Обработаем нажатую клавишу
        switch (key)
        {
            case LEFT: x--; if (x<0) x = size_x-1; break;    // нажали влево
            case RIGHT: x++; if (x>=size_x) x = 0; break;    // нажали вправо
            case UP: y--; if (y<0) y = size_y - 1; break;    // вниз
            case DOWN: y++; if (y>=size_y) y = 0; break;        // вверх
            case ESC: bExit = 0; break;                            // отмена
            // изменить текущий элемент
            case ENTER: *ptr = ChangeItem (x*4+xPos+1, y+yPos+1); break;
        }
    }

    // Востановим ипорченную часть экрана
    RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
    _setcursortype (_NORMALCURSOR);    // включим курсор
}

// Выполняет ввод матрицы
void InputMatrix (int *vector, int size_y, int size_x)
{
    word xPos=1, yPos=1, xSize = min (80, size_x * 4), ySize = min (24, size_y + 1);
    int *ptr = vector, data;
    byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
    // Рисуем окошко
    ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Матрица ");

    // Цикл ввода
    for (int y = 0; y < size_y; y++)
    {
        for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4)
        {
            gotoxy (pos, y + yPos + 1);
            scanf ("%3d", &data);
            *ptr = data;
        }
    }
    bioskey (0);    // Подождем нажатия на любую клавищу
    RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
}

// Заполняет матрицу случайными числами из диапозона [-50;50]
void RandMatrix (int *vector, int size_y, int size_x)
{
    for (int y = 0, *ptr = vector; y < size_y; y++)
    {
        for (int x = 0; x < size_x; x++, ptr++)
            *ptr = (random (99) - 50);
    }
}

// Показывает резутаты работы
void ViewResult (int *m_vector, int size_y, int size_x, long *abs_vect,
                     long pMin, long pMax, long pSum, long pMinus, int *m_vect,
                     int nMin, int nMax)
{
    _setcursortype (_NOCURSOR); // Выключаем курсор

    // Расчитываем параметры окошек
    word xPos=1, yPos=1, xSize = min (50, size_x * 4), ySize = min (12, size_y + 1);
    word xPos1=60, yPos1=1, xSize1 = 18, ySize1 = 7;
    word xPos2=xPos + xSize + 2 + 2, yPos2=1, xSize2 = 10, ySize2 = ySize;
    word xPos3=1, yPos3=ySize + 1 + 2, xSize3 = xSize, ySize3 = ySize;

    // Настраиваем указатели на данные
    int *ptr = m_vector, data, *ptr1 = m_vect;

    // Запомним кусочки экрана куда будут выводится окошки
    byte *buf = SaveScreen (xPos, yPos, xSize + 2, ySize + 1);
    byte *buf1 = SaveScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1);
    byte *buf2 = SaveScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1);
    byte *buf3 = SaveScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1);

    // Нарисуем окошки
    ShowWin (xPos, yPos, xSize, ySize, 2, 1, LIGHTCYAN, BLUE, " Исх. матрица ");
    ShowWin (xPos1, yPos1, xSize1, ySize1, 2, 1, WHITE, MAGENTA, " Статистика ");
    ShowWin (xPos2, yPos2, xSize2, ySize2, 2, 1, WHITE, GREEN, "");
    ShowWin (xPos3, yPos3, xSize3, ySize3, 2, 1, WHITE, BLUE, " Рез. матрица ");

    // Вывод инфы на экран
    gotoxy (xPos1 + 2, yPos1 + 2); printf (" Min = %ld", pMin);
    gotoxy (xPos1 + 2, yPos1 + 3); printf (" Max = %ld", pMax);
    gotoxy (xPos1 + 2, yPos1 + 4); printf (" \"-\" = %ld", pMinus);
    gotoxy (xPos1 + 2, yPos1 + 5); printf ("Сумма = %ld", pSum);

    // Цикл вывода данных из матрицы на экран
    for (int y = 0; y < size_y; y++)
    {
        // Подсветка строки с минимальным и максимальным произведением
        if (y == nMin || y == nMax)
        {
            textbackground (CYAN);
            for (int a = 0; a < size_x * 4 - 1; a++)
            {
                gotoxy (xPos+1+a, y + yPos + 1); cprintf (" ");
                gotoxy (xPos+1+a, y + yPos3 + 1); cprintf (" ");
            }
        }

        // Вывод данных из матрицы на экран
        for (int x = 0, pos = xPos + 1; x < size_x; x++, ptr++, pos += 4, ptr1++)
        {
            gotoxy (pos, y + yPos + 1);    // Первая матрица
            printf ("%-3d", *ptr);

            gotoxy (pos, y + yPos3 + 1);     // вторая матрица
            printf ("%-3d", *ptr1);
        }
        gotoxy (xPos2 + 1, y + yPos2 + 1);    // массив произведений
        printf ("%ld", abs_vect[y]);
    }
    bioskey (0);    // ждем нажатия на любую клавишу

    // востанавливаем испорченные кусочки экрана
    RestoreScreen (xPos, yPos, xSize + 2, ySize + 1, buf);
    RestoreScreen (xPos1, yPos1, xSize1 + 2, ySize1 + 1, buf1);
    RestoreScreen (xPos2, yPos2, xSize2 + 2, ySize2 + 1, buf2);
    RestoreScreen (xPos3, yPos3, xSize3 + 2, ySize3 + 1, buf3);

    _setcursortype (_NORMALCURSOR); // включаем курсор
}

// Выполняе решение
void CreateAbsVector (int *vector, int size_y, int size_x, long *resVector,
                             long *pMin, long *pMax, long *pSum, long *pMinus,
                             int *r_vect, int *n_Min, int *n_Max)
{
    long summ = 0;    // Сумма произведений, пока 0

    // Цикл стоит массив из модулей произведений отрицательных
    // элементов каждой строки, если таких элементов в строке нет,
    // то результат = 0
    // а также считает кол-во отрицательных элементов
    // и определяет сумму произведений сформированного массива
    for (int y = 0, i = 0, *ptr = vector, abs_count = 0; y < size_y; y++, i++)
    {
        resVector[i] = 0;    // снача = 0
        for (int x = 0; x < size_x; x++, ptr++)
        {
            if (*ptr < 0) // элемент отрицательный
            {
                if (resVector[i] == 0)    // пока 0
                    resVector[i] = abs (*ptr);    // тогда пишем первое число
                else    // уже не 0
                    resVector[i] *= abs (*ptr); // тогда умножим на элемент
                abs_count++;    // счетчик отрицательных, увеличим
            }
        }
        summ += resVector[i];    // не забудем прибавить к общей сумме
    }

    // уже вычисленные значения вернем через указатель
    *pSum = summ;
    *pMinus = abs_count;

    // Найдем мин и мах элементы и поменяем строки местами
    long Min, Max;
    int nMin, nMax;    // номера строк с мин и мах элементами

    // цикл для нахождения
    for (i = 0; i < size_y; i++)
    {
        if (!i)    // если это первый элемент
        {    // то положим его равным мин и мах и запомним номер строки
            Max = Min = resVector [i];
            nMin = nMax = i;
        }
        else    // элеменет не первый
        {        // тогда ищем
            if (Max < resVector [i])    // выбор мах из очередной пары
            {
                Max = resVector [i];
                nMax = i;
            }

            if (Min > resVector [i])    // выбор мин из очередной пары
            {
                Min = resVector [i];
                nMin = i;
            }
        }
    }

    // вернем результаты
    *pMin = Min;
    *pMax = Max;
    *n_Min = nMin;
    *n_Max = nMax;

    // поменяем строки с мин и мах местами
    int *ptr_cpy = r_vect;
    ptr = vector;

    // скопируем первую матрицу во вторую
    memcpy (ptr_cpy, ptr, sizeof (int) * size_y * size_x);

    // Если надо менять строки в исходной матрице, то
    // закоментировать следующие 2 строки и "в исходной"
    // разкоментировать 2 строки "в результирующей"
    // указатели на строки с мин и мах элементами, вычислим адресе
    int *ptr_min = r_vect + ITEM (nMin, 0, size_x); // в исходной
    int *ptr_max = r_vect + ITEM (nMax, 0, size_x); // в исходной

    // это было чтобы менять в исходной матрицы строки
//    int *ptr_min = vector + ITEM (nMin, 0, size_x);    // в результирующей
//    int *ptr_max = vector + ITEM (nMax, 0, size_x);    // в результирующей
    int *tmp = new int [size_x];    // временный массив для хранения строки

    // поменяем местами строки, через временный массив
    memcpy (tmp, ptr_min, sizeof (int) * size_x);
    memcpy (ptr_min, ptr_max, sizeof (int) * size_x);
    memcpy (ptr_max, tmp, sizeof (int) * size_x);

    // освободим временный массив
    delete [] tmp;
}

// Главная функция - управляет работой всей программы
void AppRun (void)
{
    DeskTop ();    // нарисуем экран
    TaskBar (" ~ESC~ Выход");    // строку статуса

    byte bExit = 1;
    byte buf_size;
    byte *buf;

    // переменные для записи результатов работы меню
    word MainMenuResult = 0, FileMenuResult, HelpMenuResult;

    // основной цикл работы
    while (bExit)
    {
        // вызов главного меню
        MainMenuResult = Menu (5,3,18,4,2,1,YELLOW,BLUE,CYAN,BLUE,
            " Главное меню ", 3, MainMenuItems, MainMenuResult);

        // Обработка результатов работы главного меню
        switch (MainMenuResult)
        {
            case -1: bExit = 0; break;    // выход из программы

            case 0:
                // запуск меню "Файл"
                buf = SaveScreen (20, 4, 28 + 2, 8 + 1);
                FileMenuResult = Menu (20, 4, 28, 8, 2, 1, YELLOW,MAGENTA,
                    CYAN,BLUE, " Меню файл ", 7, FileMenuItems,0);

                // обработка результатов работы меню файл
                switch (FileMenuResult)
                {
                    case -1: break;
                    case 0: LoadData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // load data
                    case 1: SaveData (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // save data
                    case 2: InputMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // input data
                    case 3: ShowMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // edit data
                    case 4: RandMatrix (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X); break; // random data
                    case 5:
                        ViewResult (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X, VectorAbs, gMin, gMax, gSum, gMinus, &Matrix2[0][0], MinLine, MaxLine);
                        break; // show result
                    case 6: bExit = 0; break; // exit
                }

                RestoreScreen (20, 4, 28 + 2, 8 + 1, buf);
                break;

            case 1:
                // выполнение вычислейний
                CreateAbsVector (&Matrix1[0][0], ARRAY_SIZE_Y, ARRAY_SIZE_X,
                            &VectorAbs[0], &gMin, &gMax, &gSum, &gMinus,
                            &Matrix2[0][0], &MinLine, &MaxLine);
                _setcursortype (_NOCURSOR);
                buf = SaveScreen (20, 5, 44 + 2, 6 + 1);
                ShowWin (20, 5, 44, 6, 2, 1, WHITE, MAGENTA, " Результат ");
                gotoxy (32,7); printf ("Вычисления выполнены.");
                gotoxy (24,9); printf ("Нажмите любую клавишу для продолжение");
                bioskey (0);
                RestoreScreen (20, 5, 44 + 2, 6 + 1, buf);
                _setcursortype (_NORMALCURSOR);
                break;

            case 2:
                // вызов меню "Справка"
                buf = SaveScreen (20, 6, 31 + 2, 3 + 1);
                HelpMenuResult = Menu (20, 6, 31, 3, 2, 1, YELLOW,MAGENTA,
                    CYAN,BLUE, " Меню справка ", 2, HelpMenuItems,0);

                // обработка результатов меню справка
                switch (HelpMenuResult)
                {
                    case 0: UserGuide (); break; // User guide
                    case 1: About (); break; // About ...
                }

                RestoreScreen (20, 6, 31 + 2, 3 + 1, buf);
            break;
        }
    }
}

// Выводин информацию о разработчиках
void About (void)
{
    _setcursortype (_NOCURSOR);
    byte *buf = SaveScreen (18, 7, 44 + 2, 11 + 1);
    ShowWin (18, 7, 44, 11, 2, 1, BLUE, CYAN, " Об авторах ... ");
    gotoxy (20, 9); printf ("Програмный продукт: ********************");
    gotoxy (20,11); printf (" Разработчик: ********************");
    gotoxy (20,13); printf (" Дата выпуска: ********************");
    gotoxy (20,17); printf (" Нажмите любую клавишу для выхода ");
    bioskey (0);
    RestoreScreen (18, 7, 44 + 2, 11 + 1, buf);
    _setcursortype (_NORMALCURSOR);
}

// Выводит одну страницу руководства пользователя
void ShowUserGuide (const char *Text)
{
    ShowWin (15, 7, 50, 11, 2, 1, WHITE, GREEN, " Руководство пользователя ");
    window (16,8,64,17);
    cprintf ("%s", Text);
    textcolor (BLUE);
    gotoxy (9,10); cprintf ("ESC - Выход. Up, Down - Листать.");
    window (1,1,80,25);
}

// Выполняет работу диалога руководство пользователя
void UserGuide (void)
{
    _setcursortype (_NOCURSOR);
    int key;
    byte bExit = 1;
    byte *buf = SaveScreen (15, 7, 50 + 2, 11 + 1);
    int GuideCount = 0;

    while (bExit)
    {
        ShowUserGuide (UserGuideText [GuideCount]);
        key = bioskey (0);
        switch (key)
        {
            case ESC: bExit = 0; break;
            case UP: GuideCount--;
                if (GuideCount < 0)
                    GuideCount = 0;
                break;
            case DOWN: GuideCount++;
                if (GuideCount >= UserGuideCount - 1)
                    GuideCount = UserGuideCount - 1;
                break;
        }
    }
    RestoreScreen (15, 7, 50 + 2, 11 + 1, buf);
    _setcursortype (_NORMALCURSOR);
}

// Востанавливает часть экрана
void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf)
{
    puttext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
    delete [] buf;
}

// Сохраняет часть экрана
byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize)
{
    word buf_size = (xSize + 1) * (ySize + 1) * 2;
    byte *buf = new byte [buf_size];

    if (!buf)
    {
        printf ("Нет свободной памяти для выполнения операции!\n");
        return NULL;
    }

    gettext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
    return buf;
}

// Главная функциия - отсюда происходит старт программы
void main (void)
{
    if (SplashScreen ()) // вывод заставки, если пользователь не нажал выход
        AppRun ();            // то запускаем работу программы
}
[/more]
Автор: regan32
Дата сообщения: 19.05.2008 22:26
LuckyELF

Спасибо! правда к этому времени я уже по большей части разобрался с самой работай меню.
но вызвали очень большой интерес некоторые функции:
Savescreen и Restorescreen(если не сложно можешь пояснить как они у тебя работают)

И вопрос ко всем:
какие существуют способы очистки части экрана при работе в досе?
Автор: autocad devoloper
Дата сообщения: 19.05.2008 22:40
distance, Rudia.
Спасибо большое, разобрался.
Буду дальше постигать дебри с++.
Автор: LuckyELF
Дата сообщения: 24.05.2008 09:34

Цитата:
но вызвали очень большой интерес некоторые функции:
Savescreen и Restorescreen(если не сложно можешь пояснить как они у тебя работают)


Ну собственно вот их код:

Код: // Востанавливает часть экрана
void RestoreScreen (byte xPos, byte yPos, byte xSize, byte ySize, byte *buf)
{
puttext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
delete [] buf;
}

// Сохраняет часть экрана
byte *SaveScreen (byte xPos, byte yPos, byte xSize, byte ySize)
{
word buf_size = (xSize + 1) * (ySize + 1) * 2;
byte *buf = new byte [buf_size];

if (!buf)
{
printf ("Нет свободной памяти для выполнения операции!\n");
return NULL;
}

gettext (xPos, yPos, xPos + xSize, yPos + ySize, buf);
return buf;
}
Автор: integer07
Дата сообщения: 18.06.2008 20:59
Люди,кто-нибудь знает какой алгоритм можно использовать(если он существует вообще),чтобы в графе найти МАКСИМАЛЬНОЕ расстояние между всеми парами его вершин?а то попадаются в основном алгоритмы для поиска кратчайшего пути...
Автор: Chessmaster3000
Дата сообщения: 23.06.2008 07:58
Не могу расшифровать и не получилось найти в Шилдте:

==============
...

public:
A(int _x):x(_x){}
...
===============

Что это значит?

Вот вся программа,если необходимо:

#include<iostream>
using namespace std;
class A{
protected:
int x;
public:
A(int _x):x(_x){}
friend ostream&operator<<(ostream&out,const A& obj)
{
out<<"I am A Object"<<obj.x<<endl;
return out;
}

void f(int _x)
{
x=_x;
cout<<*this;
}
};

class B:public A{
public:
B(int z):A(z){}
void f(int _x)
{
A::f(_x+1);
}
};

void SomeFunction(B b)
{
b.f(3);
}

int main()
{
B p(1);
SomeFunction(p);
getchar();
}




Заранее спасибо







Автор: c0d3r
Дата сообщения: 23.06.2008 08:05
Chessmaster3000

Плохо искали Почитайте про инициализацию переменных в конструкторе, например, здесь: http://www.math.msu.su/%7Evvb/2course/Borisenko/Lect01.html#Initialization
Автор: Sumato
Дата сообщения: 24.06.2008 13:54
c0d3r
Из любопытства прошёл по предложенной ссылке -- и сразу же появились замечания. Как раз по инициализации членов.
Цитата
"1) Все переменные-члены класса должны быть инициализированы в конструкторе, подчеркиваем, все!"
Возражений нет.

Продолжение цитаты
"Если их даже 1000 и инициализация большинства по смыслу не нужна, все равно их все надо тупо выписать в том порядке, в котором они описаны в интерфейсе класса, и присвоить им некоторые начальные значения.
2) Инициализацию всегда следует выполнять не внутри тела конструктора, а в списке инициализации."

Здесь автор лекции чересчур категоричен. Это далеко не панацея.
Два контрпримера навскидку (в подробности не вдаюсь, но если надо -- могу привести конкретные примеры).
Первый (классический): начальное значение одной (или нескольких) из переменных-членов зависит от другой.
Второй -- сторонние (побочные) эффекты во время конструирования объектов-членов.

Chessmaster3000, я бы порекомендовал в дополнение к Шилдту и лекции что-нибудь ещё классическое, например Липпмана. У него такие вещи разжевываются до безобразия, хотя и воды хватает (не стану давать прямые ссылки из-за их недолговечности, поищите в Гугле по ключевым словам Липпман ("C++ для начинающих" OR "C++ Вводный курс")). Вообще, литературу по C++ желательно иметь под рукой разную и побольше. (-;
Автор: Chessmaster3000
Дата сообщения: 24.06.2008 21:50
Sumato, спасибо за комментарий.

Сейчас у меня есть книга Шилдта "Самоучитель С++" и книга Deitel&Deitel "C++ How to Program (third Edition)" -очень даже фундаментальное издание ИМНО.

К сожалению особого времени штудировать других авторов не осталось- экзамен по плюсам послезавтра.
Ссылка мне помогла-понял что другой способ инициализировать переменные.

Добавлено:
Вот такая задача,как решить не знаю.

Обрисую суть проблемы.
Создан класс "Оценка" (анлийскими буквами конечно).Этот класс включает в себя имя предмета и целое число -оценку и указатель на следующий объект того же класса(если есть: если нет-НУЛЬ).

Создан класс "студент" .
В классе студент есть порядковый номер студента,имя и указатель на объект класса "Оценка".
Указатель потому что хотим сделать связанный спиок из объектов класса оценка.Что бы у каждого студента можно было бы пробежаться по связному списку и потому что мы заранее не знаем сколько оценок потребуется добавлять каждому студенту.

Нужно что бы в классе студент была бы функция которая добавляет оценку к связному списку( а получает ессно число и имя предмета).

Вот чего я не могу понять как сделать- ведь если мы создадим функцию в классе студент которая получает число и имя предмета,и которая создаёт объёкт класса оценка и присоединяет его к связному списку, то когда эта функция завершается то последний добавленный объект уничтожается...и вся работа по созданию оцеки коту под хвост . Что же делать? (Надеюсь что я понятно всё объяснил)
Автор: c0d3r
Дата сообщения: 25.06.2008 08:48
Chessmaster3000


Цитата:
то когда эта функция завершается то последний добавленный объект уничтожается


Это только в том случае, если вы создавали класс Оценка на стеке, т.е. как локальную переменную для этой ф-ции. Если вы будете выделять память под класс Оценка из кучи, м помощью оператора new, то объект будет существовать до тех пор, пока вы его не удалите (в конструкторе класса Студент).
Автор: Sumato
Дата сообщения: 25.06.2008 10:06
Chessmaster3000

Цитата:
экзамен по плюсам послезавтра

А, понятно, А я по наивности подумал, что просто самостоятельно язык изучаете. Ну, бывает.
О лекции я ничего плохого сказать не хотел, но уточнять такие вещи просто необходимо, поскольку это из области базовых знаний.
Вы бы что-нибудь сами написали (на C++, что сможете), чтобы было от чего оттолкнуться, а иначе придётся приводить кучу примеров, чтобы проиллюстрировать такие понятия как время жизни и область видимости, что есть в любом учебнике.
Если чувствуете, что ситуация запущенная, срочно берите Элджера "C++" (не знаю, можно ли оставлять в этой теме ссылки на книги, поэтому кидаю в ПМ) и тщательно читайте главу 2 "Синтаксис C++". Я не шучу. Там сжатый, но достаточно полный обзор сиснтаксиса языка. За несколько часов можно убрать кучу белых пятен.
Автор: c0d3r
Дата сообщения: 25.06.2008 11:13

Цитата:
чтобы проиллюстрировать такие понятия как время жизни и область видимости, что есть в любом учебнике. Если чувствуете, что ситуация запущенная, срочно берите Элджера "C++"


Интересно, что в соседнем форуме буквально только, что говорили, что Элджера читать не надо )

http://www.rsdn.ru/forum/message/3000079.flat.aspx#3000079
Автор: Chessmaster3000
Дата сообщения: 25.06.2008 11:36


Цитата:

Это только в том случае, если вы создавали класс Оценка на стеке, т.е. как локальную переменную для этой ф-ции. Если вы будете выделять память под класс Оценка из кучи, м помощью оператора new, то объект будет существовать до тех пор, пока вы его не удалите (в конструкторе класса Студент).


Понял это написал простую программу ,сейчас работает предыдущая версия не работала потому что связный список был реализован не правильно , вот маленькая версия программы по которой видно что объекты НЕ уничтожаются.




Код: #include<iostream>
using namespace std;

class mark{
int m;
mark* next;
public:
mark(){next=NULL;}
mark(int mm){next=NULL;m=mm;}
int getmark(){return m;}
mark* getnext(){return next;}
void setnext(mark* obb){next=obb;}
};


class student{
mark* p1;
public:
student(){p1=NULL;}

void add_mark(int k){mark* e=new mark(k);
mark* t=p1;

if(p1==NULL) p1=e;
else{
while((t->getnext())!=NULL)t=t->getnext();
t->setnext(e);
}
}

void print_out(){
mark* temp;
temp=p1;
while(temp->getnext()!=NULL){cout<<temp->getmark()<<' ';temp=(temp->getnext());}


}

};


int main()
{
student vas;

for(int i=0;i<10;i++)
vas.add_mark(i+55);

vas.print_out();

system("PAUSE");
return 0;
}
Автор: Sumato
Дата сообщения: 25.06.2008 15:24
Chessmaster3000
Не забудьте деструктор в student добавить. Сейчас список оценок удаляет ОС после завершения программы.
P.S. Кстати, через некоторое время, когда станете более опытным, загляните сюда и посмотрите свою программу ещё раз -- уверяю, не пожалеете.
Автор: c0d3r
Дата сообщения: 25.06.2008 15:32
Chessmaster3000


Цитата:
вот маленькая версия программы по которой видно что объекты НЕ уничтожаются.


Естественно, ведь память в ф-ции add_mark() вы выделяете в куче (heap) с помощью оператора new.

В чем ваш вопрос?
Автор: Sumato
Дата сообщения: 25.06.2008 16:01
c0d3r
Ваш пост чуть было не пропустил.

Цитата:
Интересно, что в соседнем форуме буквально только, что говорили, что Элджера читать не надо )

Так и думал, что получу Элджером по башке.
Самое смешное, что я в основном согласен. Но обратите внимание, что я порекомендовал прочитать главу 2. Более краткого (и интересного, кстати) обзора синтаксиса я не встречал. Если человеку нужен обзор C++ одним взглядом, если можно так выразиться, -- эта глава может быть хорошим подспорьем. Тем более, что автор затрагивает там весьма тёмные места языка.
А то, что книга написана до принятия Стандарта -- это факт. Соответственно, стандартной библиотеки нет и в помине, по шаблонам автору сказать особо нечего, в тексте, к сожалению, масса опечаток (хотя иногда кажется, что это скорее ошибки) и т.п.. Да и вряд ли даже опытному программисту будут интересны авторские трюки: т.е. начинающий с ума сойдёт, пытаясь их понять, а значительно более опытному и самому есть что сказать.
Автор: c0d3r
Дата сообщения: 25.06.2008 16:12
Chessmaster3000


Цитата:
Вот такая задача,как решить не знаю.


Решается очень просто. Вот мой вариант:

[more]

Код:
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

class Mark {
string name;
int value;

public:
Mark(const string &mark_name, int mark_value)
: name(mark_name), value(mark_value) {}

int getValue() const {return value;}
const string& getName() const {return name;}
};

class Student {
int id;
string name;
vector<Mark> marks;

public:

Student(const string &sname, int sid) : id(sid), name(sname) {}

void addMark(const string &name, int mark_value) {
marks.push_back(Mark(name, mark_value));
}

int getID() const {
return id;
}

const string& getName() const {
return name;
}

void printMarks() const {
for (vector<Mark>::const_iterator cit = marks.begin();
cit != marks.end();
++cit) {
cout << cit->getName() << '\t' << cit->getValue() << endl;
}
}
};

int main() {

Student student("coder", 1);
student.addMark("Biology", 4);
student.addMark("Math", 4);
student.addMark("English", 5);
student.addMark("Russian", 5);

cout << "Student #" << student.getID()
<< ": " << student.getName()
<< " has following marks:" << endl;

student.printMarks();

return 0;
}
Автор: Qraizer
Дата сообщения: 25.06.2008 19:07
Sumato
Цитата:
Все переменные-члены класса должны быть инициализированы в конструкторе, подчеркиваем, все!"

Цитата:
Здесь автор лекции чересчур категоричен. Это далеко не панацея.
Прокомментирую с позволения. Да, это черезчур категорично. Но тут не стоит настолько всё понимать буквально, лучше понять, чем этот совет полезен. Просто пример:
Код: int x, y, z;
const int a; // это компилятору не понравится
int& b; // и это тоже

/* ... */
x = 10;
y = 15;
z = x+y;
a = b-z; // и это
b = y; // а это нормально, но будет воспринято не так, как рассчитывал программист

/* то же самое, но в классе */
class someClass
{
int x, y, z;
const int a; // а вот тут нормально
int& b; //

public:
someClass()
{
x = 10;
y = 15;
z = x+y;
a = b-z; // но не тут
b = y; //
}
}
Автор: 4aineG
Дата сообщения: 04.07.2008 14:25
#pragma once
#include <stdio.h>
class Line
{
private:
    char *Line1;
public:
    Line(char *L1)
    {
        L1 = new char [100];
        Line1 = L1;
        //L2 = new char [100];
        //Line2 = L2;
    }
    int CountWordsInLine()
    {
        int i=0;
        int Count=0;
        while(Line1[i]!='/0')
            if (Line1[i]==" ")
                Count++;
        Count+=1;
        return Count;
    }
};

#pragma once
#include "Class.h"
int main()
{
    Line ln("Preved, ya Krevedko");
    int temp = ln.CountWordsInLine();
    printf("%d", temp);
    return 0;
}

захотел написать прогу при помощи класса подсчета слов в строке, но вылазит ошибка о несоответствии типов int и char, вот они собственно говоря

c:\мои документы\visual studio 2005\projects\symbolline(rough_copy)\symbolline(rough_copy)\class.h(21) : error C2446: '==' : no conversion from 'const char *' to 'int'
There is no context in which this conversion is possible
c:\мои документы\visual studio 2005\projects\symbolline(rough_copy)\symbolline(rough_copy)\class.h(21) : error C2040: '==' : 'int' differs in levels of indirection from 'const char [2]'
ошибки вылазят в этой функции CountWordsInLine()

как мне быть... подскажите люди добрые
слишком не глумитесь над моим вопросом, я ведь еще 4aineg
усе ... заранее благодарю
Автор: Zyava
Дата сообщения: 04.07.2008 14:30
Может таки

Цитата:

Line1[i]==' '

?
Автор: 4aineG
Дата сообщения: 04.07.2008 22:37
Line1[i]==' ' - я это изменил но почему то распечатывать не хочет, не знаю почему

Добавлено:
может это проблема с выделением памяти, я кое чего изменил, и вылезла ошибка "память не может быть read", кстати не могли бы вы подсказать как правильно создавать массив при помощи класса, буду очень признателен
Автор: Rudia
Дата сообщения: 05.07.2008 08:36
4aineG
Это проблема с кодом
Line(char *L1)
{
L1 = new char [100]; //???? что это такое? вы создаете новую строку.
Line1 = L1;
//L2 = new char [100];
//Line2 = L2;
}
Автор: 4aineG
Дата сообщения: 05.07.2008 09:37
а как мне правильно создать конструктор, тут конечно можно обойтись и без него, просто я хочу разобраться
Автор: virpool
Дата сообщения: 05.07.2008 12:02
4aineG
Line(char *L1)
{
Line1 = new char[strlen(L1)+1];
strcpy(Line1, L1); // для использования strcpy необходимо проинклудить string.h
}
и кстати желательно еще и деструктор реализовать.. примерно так:

~Line()
{
delete [] Line1; // Или просто delete Line1;
}

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.