Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 3 [4] 5 6   Вниз
  Печать  
Автор Тема: Процессы  (Прочитано 102561 раз)
0 Пользователей и 1 Гость смотрят эту тему.
v.korleone
Помогающий

ua
Offline Offline

« Ответ #90 : 31-12-2008 13:48 » 

Вад, припустим уже сделано все о чем ты говорил, а как организовать здесь вывод?
Код: (C++)
for (int i = 0; i < 4; ++i)
    {   tasks[i].avgst = a;
        tasks[i].size = n;
        tasks[i].subj = i;
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvgst, &tasks[i], 0, &tid);

    cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
        <<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<tasks[i].avgst<<"                          |"<< endl;
        if((i+1)%10==0) getch();//задержка на экране
    }
        WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
        //cout<<"Потоки завершили виконання" <<endl;
        //Закриваем потоки
                for (i=0;i<4;i++) CloseHandle(Thread[i]);
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #91 : 31-12-2008 19:21 » 

После цикла закрытия потоков идти новым циклом по тому массиву, где хранятся результаты, и выводить.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #92 : 01-01-2009 09:35 » 

Вад, сделал, что-то подобное, но с ошибками (компилятор все компилит, вот только средний бал для всех студентов 0). Подскажи, пожалуйста, в чем дело.
Структуры:
Код: (C++)
struct Student
{
fio f; //ФИО
int col[4];  // массив оценок за 4 дисциплины.
};

struct STask
{
   Student *src;    // исходные данные
   Student *src_st;
   int size;       // число элементов в src
   int subj;       // дисциплина, для которой считаем среднее
   float avg;      // средний балл - используется для сохранения результата
   int beg_st;     // начало подмассива студентов
   int am_st;      // конец  подмассива студентов для обработки
   float avg_st[n];     // массив средних баллов для студентов
};

Student s[20];

Функция для нахождения среднего балла для каждого студента:
Код: (C++)
float srbal_st(
    Student *src_st,   // массив данных
    int subj,          // номер дисциплины
    int beg_st,        // начало подмассива студентов
    int am_st         //  конец подмассива студентов для обработки
           )
{
    int i,sum,avg_st[20];
    {
    for(i = beg_st; i < am_st; i++)
    avg_st[i] = src_st[i].col[subj]+src_st[i].col[subj+1]+src_st[i].col[subj+2]+src_st[i].col[subj+3];
    return (avg_st[i]/(float)4);//средний бал по дисциплинам для i-го студента
    }
}
Функция передачи знчения средного балла студента потоку:
Код: (C++)
unsigned __stdcall CalcAvg_st (void * arg)
{
    STask *task_st = (STask*) arg;
        if (task_st) // проверяем - вдруг параметры забыли передать
    {   task_st->avg = srbal_st(task_st->src_st,task_st->subj,task_st->beg_st,task_st->am_st);
        return 0;
    }
    else
        return 1; // типа, ошибка - вдруг кого волнует
}
Главная программа:
Код: (C++)
for (int i = 0; i < 4; ++i)
    {
        tasks[i].src_st = a; // Массив студентов
        tasks[i].subj = i;   // Предмет
        tasks[i].beg_st = i*5; // Начало подмассива студентов
        tasks[i].am_st = (i+1)*5-1;  // Конец подмассива студентов для обработки в одном потоке
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvg_st, &tasks[i], 0, &tid);
    }
        WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
        cout<<"\n \n Потоки завершили виконання по розрахунку середнього бала для студентів." <<endl;
        //Закриваем потоки
                for (i=0;i<4;i++) CloseHandle(Thread[i]);
        //Вывод студентов на экран
    cout << " \n \n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"------------------------------------|"<<"\n";
    cout<<"|  Прізвище  |"<<"  Ім'я    |"<<"  По батькові |"<<" Середній бал для кожного студента  |"<<"\n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"------------------------------------|"<<"\n";
                for (i=0;i<20;i++)
                {
                cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
        <<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<tasks[i].avg_st[i]<<"                          |"<< endl;
        if((i+1)%20==0) getch();//задержка на экране
                }
« Последнее редактирование: 01-01-2009 10:54 от v.korleone » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #93 : 01-01-2009 13:00 » 

1. Я бы не стал лепить всё в одну структуру STask - сделай две, каждую для своей задачи: подсчёт среднего по дисциплинам и по студентам
2. Я бы не стал объявлять массив с результатами (float avg_st[n] в самой STask) - во всяком случае, не так
3. Функция srbal_st делает нечто странное, но не подсчёт балла по 1 студенту. Она, по идее, должна возвращать 0 или какой-то мусор.
4. Не понял, с каким умыслом используется поле avg структуры STask в данной части задачи (в CalcAvg_st). Впрочем, это проблема прямого копирования кода, как я понимаю Улыбаюсь копипастить нужно с умом и оглядкой Улыбаюсь

Попробуй воспользоваться отладкой и по шагам посмотреть, что у тебя происходит - это можно сделать даже в многопоточной программе, точки останова и просмотр значений переменных в ней при отладке ещё никто не отменял Ага
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #94 : 02-01-2009 09:53 » 

Цитата
1. Я бы не стал лепить всё в одну структуру STask - сделай две, каждую для своей задачи: подсчёт среднего по дисциплинам и по студентам
Спасибо,исправил, на это:
Код: (C++)
...
const int n=20; //  количество средних баллов массива студентов
...
struct STask_st
{
   Student *src_st; //исходные данные
   int subj_st;    // дисциплина, для которой считаем среднее
   int beg_st;     // начало подмассива студентов
   int am_st;      // количество студентов в подмассиве для обработки
   float avg_st[n];// массив средних баллов для студентов
};
Цитата
2. Я бы не стал объявлять массив с результатами (float avg_st[n] в самой STask) - во всяком случае, не так
А как лучше сделать?
Цитата
3. Функция srbal_st делает нечто странное, но не подсчёт балла по 1 студенту. Она, по идее, должна возвращать 0 или какой-то мусор.
Вад, если честно, я не очень разбираюсь в отладке по шагам  Жаль. Что-то пробовал, выводило на экран и записи в ассемблере, а также показало, что проблема действительно, как ты говорил здесь:
Код: (C++)
avg_st = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
Я пробовал переделывать, но как видно, это тоже неправильно. Потом я сделал так:
Код: (C++)
avg_st = src_st[i].col[0];
Просто, хотел посмотреть будет ли выводить, но безрезультатно. Сейчас дошел до этого:
Код: (C++)
...
const int p=5;  //  количестов средних баллов одного из 4 подмассивов студентов
...
    float srbal_st(
    Student *src_st,   // массив данных
    int subj_st,       // номер дисциплины
    int beg_st,        // начало подмассива студентов
    int am_st         //  количество студентов для обработки
           )
{
    int i;
    float avg_str[p];// массив для хранения результатов среднего балла для 5-ти студентов
    {
    for(i = beg_st; i < am_st; i++)
    avg_str[i] = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
    return (avg_str[i]/(float)4);//средний бал по дисциплинам для i-го студента
    }
}
Не работает, и все!
Цитата
4. Не понял, с каким умыслом используется поле avg структуры STask в данной части задачи (в CalcAvg_st). Впрочем, это проблема прямого копирования кода, как я понимаю  копипастить нужно с умом и оглядкой
Спасибо, исправил на это:
Код: (C++)
task_st->avg_st[n] = srbal_st(task_st->src_st,task_st->subj_st,task_st->beg_st,task_st->am_st);
где
Код: (C++)
...
const int n=20;//  количество средних баллов массива студентов
....


P.S. После проведенных перестановок программа компилится, но выводит только первую часть программы т.е. ту где нужно посчитать среднее по дисциплинам.


Вад, подскажи, пожалуйста, что делать с этим?
Код: (C++)
...
const int p=5;  //  количестов средних баллов одного из 4 подмассивов студентов
...
    float srbal_st(
    Student *src_st,   // массив данных
    int subj_st,       // номер дисциплины
    int beg_st,        // начало подмассива студентов
    int am_st         //  количество студентов для обработки
           )
{
    int i;
    float avg_str[p];// массив для хранения результатов среднего балла для 5-ти студентов
    {
    for(i = beg_st; i < am_st; i++)
    avg_str[i] = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
    return (avg_str[i]/(float)4);//средний бал по дисциплинам для i-го студента
    }
}
« Последнее редактирование: 05-01-2009 11:29 от RXL » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #95 : 02-01-2009 11:56 » 

По п.2: если хочется отдельный массив с результатами, то что-то вроде такого:
Код:
struct STask_st
{
   Student *src_st; //исходные данные
   int beg_st;     // начало подмассива студентов
   int am_st;      // количество студентов в подмассиве для обработки
   float *avg_st;// массив средних баллов для студентов
};

Код:
int main()
{
    Student a[N];
    float result[N];
    //...

    for (int i = 0; i < 4; ++i)
    {
        tasks[i].src_st = a; // Массив студентов
        tasks[i].beg_st = i*5; // Начало подмассива студентов
        tasks[i].am_st = (i+1)*5-1;  // Конец подмассива студентов для обработки в одном потоке
        tasks[i].avg_st = result; // массив результатов
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvg_st, &tasks[i], 0, &tid);
    }
    //...
}
а потом выводить содержимое этого result вместе со списком фамилий из массива студентов.

А пошаговую отладку лучше освоить - полезная штука.

Что касается функции srbal_st, то я бы упростил: такая функция должна считать 1 среднее для 1 студента. Соответственно, в неё передавать только информацию об одном из студентов; возвращать - среднее для него. А цикл поместить в CalcAvg_st, и там чётко понимать, откуда брать данные для вызовов srbal_st и куда записывать результат, возвращаемый функцией.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #96 : 04-01-2009 10:42 » 

Вад,спасибо, за советы. Сделал вот так:
Структура:
Код: (C++)
struct STask_st
{
   Student *src_st; //исходные данные
   int subj_st;    // дисциплина, для которой считаем среднее
   int beg_st;     // начало подмассива студентов
   int am_st;      // количество студентов в подмассиве для обработки
   float *avg_st;// массив средних баллов для студентов
};
Функция для нахождения среднего бала для i-ого студента:
Код: (C++)
float srbal_st(
    Student *src_st,   // массив данных
    int subj_st)       // номер дисциплины
{
    int i;
    float avg_stud;// переменная для хранения результатов среднего балла для i-го студента
    avg_stud = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
    return (avg_stud/(float)4);//средний бал по 4 дисциплинам для i-го студента

}
Функция передачи потоку:
Код: (C++)
unsigned __stdcall CalcAvg_st (void * arg)
{   int i;
    STask_st *task_st = (STask_st*) arg;
        if (task_st) // проверяем - вдруг параметры забыли передать
    {   for(i = task_st->beg_st; i < task_st->am_st; i++)
        task_st->avg_st = srbal_st(task_st->src_st,task_st->subj_st);
        return 0;
    }
    else
        return 1; // типа, ошибка - вдруг кого волнует
}
Вызов потоков и вывод результата на экран:
Код: (C++)
STask_st tasks_st[4];
        for (int i = 0; i < 4; ++i)
    {
        tasks_st[i].src_st = a; // Массив студентов
        tasks_st[i].beg_st = i*5; // Начало подмассива студентов
        tasks_st[i].am_st = (i+1)*5-1;  // Количество студентов для обработки в одном потоке
        tasks_st[i].avg_st = result; // массив результатов
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvg_st, &tasks_st[i], 0, &tid);
    }
        WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
        cout<<"\n \n Потоки завершили виконання по розрахунку середнього бала для студентів." <<endl;
        //Закриваем потоки
                for (i=0;i<4;i++) CloseHandle(Thread[i]);
        //Вывод студентов на экран
    cout << " \n \n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"------------------------------------|"<<"\n";
    cout<<"|  Прізвище  |"<<"  Ім'я    |"<<"  По батькові |"<<" Середній бал для кожного студента  |"<<"\n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"------------------------------------|"<<"\n";
                for (i=0;i<20;i++)
                {
                cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
        <<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<tasks_st[i].avg_st<<"                          |"<< endl;
        if((i+1)%20==0) getch();//задержка на экране
                }
Пишет ошибку относительно этой строчки:
Код: (C++)
task_st->avg_st = srbal_st(task_st->src_st,task_st->subj_st);
Текст ошибки:
error: cannot convert `float' to `float*' in assignment
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #97 : 04-01-2009 11:28 » 

Ну, в общем-то, компилятор прав Улыбаюсь ты пытаешься записать float в указатель на массив, хотя стоило бы записать в элемент массива. По-моему, ты не совсем понимаешь, зачем существуют указатели, на что именно они указывают, и как обращаться с данными, передаваемыми по указателю. Вот это:
Код:
cout <<tasks_st[i].avg_st;
тоже выведет не то, на что ты, похоже, рассчитываешь Улыбаюсь Повторю: у тебя есть один массив для результатов - такой же, как и массив студентов, только элементы имеют более простую структуру - обычный float. У тебя это не учитывается при записи результата в CalcAvg_st и выводе результатов на экран.

Между прочим:
Код:
float srbal_st(
    Student *src_st,   // массив данных
    int subj_st)       // номер дисциплины
зачем тебе здесь номер дисциплины? Он же в функции никак не используется.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #98 : 04-01-2009 11:49 » 

Вад, это да:
Цитата
По-моему, ты не совсем понимаешь, зачем существуют указатели, на что именно они указывают, и как обращаться с данными, передаваемыми по указателю.
Сделал так, надеюсь правильно?:
Код: (C++)
task_st->avg_st[i] = srbal_st(task_st->src_st,task_st->subj_st);
Цитата
Между прочим:
Код:
float srbal_st(
    Student *src_st,   // массив данных
    int subj_st)       // номер дисциплины
зачем тебе здесь номер дисциплины? Он же в функции никак не используется.
Согласен, забыл убрать.


Вернее будет так:
Код: (C++)
task_st->avg_st[i] = srbal_st(task_st->src_st);


Вывод, сделал так:
Код: (C++)
for (i=0;i<20;i++)
{
cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
<<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
<<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
<<"|"<<setw(10)<<setiosflags(ios::left)<<tasks_st[i].avg_st[i]<<"                            |"<< endl;
if((i+1)%20==0) getch();//задержка на экране
}
Но, хотя стоит for (i=0;i<20;i++), программа  выводит 4 студента, со средним балом для каждого "4.5" (как мне кажется программа считает средний бал только для первого студента и записует его стальным трем).


Вад, прощу прощения за свою невнимательность, тобой было предложено это:
Цитата
а потом выводить содержимое этого result вместе со списком фамилий из массива студентов.
Поэтому, я сделал так:
Код: (C++)
for (i=0;i<20;i++)
                {
    cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
        <<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<result[i]<<"                            |"<< endl;
        if((i+1)%20==0) getch();//задержка на экране
                }
В этом случае выводит "4,5" бала для 1-4,6-9,11-14,16-19 студента, а также "0" для 5,10,15,20 студента


Поменял, определения начала и конца подмассива студентов для обработки на эти:
Код: (C++)
tasks_st[i].beg_st = i*5-1;    // Начало подмассива студентов для обработки в одном потоке
tasks_st[i].am_st = (i+1)*5;   // Конец подмассива студентов для обработки в одном потоке
Теперь выводит средний бал "4,5" для всех студентов. Не пойму в чем дело?
« Последнее редактирование: 05-01-2009 11:30 от RXL » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #99 : 04-01-2009 14:30 » 

Поменял, определения начала и конца подмассива студентов для обработки на эти:
Код: (C++)
tasks_st[i].beg_st = i*5-1;    // Начало подмассива студентов для обработки в одном потоке
tasks_st[i].am_st = (i+1)*5;   // Конец подмассива студентов для обработки в одном потоке
Теперь выводит средний бал "4,5" для всех студентов. Не пойму в чем дело?
Во-первых, (i*5 - 1) даст "-1" для i=0. Нужно i*5 и ((i+1)*5-1) соответственно. А далее, лучше показывай весь код 2й задачи целиком Улыбаюсь
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #100 : 04-01-2009 14:32 » 

Вот:
Код: (C++)
STask_st tasks_st[4];
        for (int i = 0; i < 4; ++i)
    {
        tasks_st[i].src_st = a;        // Массив студентов
        tasks_st[i].beg_st = i*5;    // Начало подмассива студентов для обработки в одном потоке
        tasks_st[i].am_st = (i+1)*5-1;   // Конец подмассива студентов для обработки в одном потоке
        tasks_st[i].avg_st = result;   // Массив результатов
        Thread[i] = (HANDLE)_beginthreadex(NULL, 0, CalcAvg_st, &tasks_st[i], 0, &tid);
    }
        WaitForMultipleObjects(4, Thread, TRUE, INFINITE);
        cout<<"\n \n Потоки завершили виконання по розрахунку середнього бала для студентів." <<endl;
        //Закриваем потоки
                for (i=0;i<4;i++) CloseHandle(Thread[i]);
        //Вывод студентов на экран
    cout << " \n \n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"--------------------------------------|"<<"\n";
    cout<<"|  Прізвище  |"<<"  Ім'я    |"<<"  По батькові |"<<" Середній бал для кожного студента    |"<<"\n";
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"--------------------------------------|"<<"\n";
                for (i=0;i<20;i++)
                {
    cout<<"|"<<setw(12)<<setiosflags(ios::left)<<a[i].f.fam//вывод на экран фамилий,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<a[i].f.im//имен,
        <<"|"<<setw(14)<<setiosflags(ios::left)<<a[i].f.ot//отчеств,
        <<"|"<<setw(10)<<setiosflags(ios::left)<<result[i]<<"                            |"<< endl;
        if((i+1)%20==0) getch();//задержка на экране
                }
    cout<<"|------------|"<<"----------|"<<"--------------|"<<"--------------------------------------|"<<"\n";
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #101 : 04-01-2009 14:35 » 

Функция:
Код: (C++)
float srbal_st(
    Student *src_st)   // массив данных
{
    int i;
    float avg_stud;// переменная для хранения результатов среднего балла для i-го студента
    avg_stud = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
    return (avg_stud/(float)4);//средний бал по 4 дисциплинам для i-го студента

}
Функция передачи потоку:
Код: (C++)
unsigned __stdcall CalcAvg_st (void * arg)
{   int i;
    STask_st *task_st = (STask_st*) arg;
        if (task_st) // Проверка передачи параметров
    {   for(i = task_st->beg_st; i < task_st->am_st; i++)
        task_st->avg_st[i] = srbal_st(task_st->src_st);
        return 0;
    }
    else
        return 1; // Ошибка!
}
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #102 : 04-01-2009 14:40 » 

А, ну всё ясно. В srbal_st переменная i = 0 всегда - и то по той причине, что имеет значение по умолчанию: ты её нигде не инициализируешь. Соответственно, для подсчёта среднего она будет брать всегда 0-го (первого) студента. Переделай эту функцию и её вызов: я бы советовал передавать структуру Student в функцию по константной ссылке (const Student& src_st). Можно и по указателю, хотя это не так красиво, имхо - но тогда нужно передавать именно адрес нужного элемента, и не нужно использовать оператор [], а просто разыменовывать указатель.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #103 : 04-01-2009 14:48 » 

Спасибо, за разъяснение.
Написал:
Код: (C++)
float srbal_st(const Student& src_st)
Относительно этой строчки:
Код: (C++)
avg_stud = src_st[i].col[0]+src_st[i].col[1]+src_st[i].col[2]+src_st[i].col[3];
пишет ошибку:
error: no match for 'operator[]' in 'src_st'
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #104 : 04-01-2009 14:53 » 

Правильно. Потому что const Student& - это почти то же самое, что и const Student - то есть, тип самой структуры. Разница только в том, что если написать Student - то структура будет передаваться по значению - то есть, структура будет копироваться, а это лишняя работа. Ссылка в данном случае нужна для того, чтобы передать данные без копирования - то есть, если бы мы решили изменять Student& st - то мы изменяли бы те данные, которые были переданы через эту ссылку. Но поскольку данные нам менять не нужно, делаем ссылку константной, запрещая изменение: const Student& src_st.

Теперь нужно в функцию srbal_st передавать саму структуру Student, т.е., элемент массива студентов. А в самой функции убрать [i]
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #105 : 04-01-2009 15:01 » 

Цитата
Теперь нужно в функцию srbal_st передавать саму структуру Student, т.е., элемент массива студентов. А в самой функции убрать
Спасибо, понял. Но как это сделать? Жаль
Может как-то с использованием этих стрелочек "->"?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #106 : 04-01-2009 15:17 » 

Эти "стрелочки" - просто один из способов разыменования указателей (наряду с * и []), применяемый для структур данных. Скажем, есть структура
Код:
struct SExample
{
    int field1;
    float field2;
};
Тогда для SExample *test - указателя на SExample - выражения test->field1 и (*test).field1 будут равносильны. А если test - это массив структур SExample (для C/C++, в сущности, test - это лишь адрес в памяти, разница между массивом и динамически выделенным элементом есть только при выделении и освобождении памяти в C++) - так вот, если test - это массив, то два следующих выражения также равнозначны: *(test + 5) и test[5] - хотя второй вариант более предпочтителен, потому как арифметикой над указателями нужно пользоваться аккуратно Улыбаюсь Происходит расчёт адреса с заданным в квадратных скобках смещением относительно исходного указателя, и извлечение значения, которое по этому адресу хранится.

Если всё ещё непонятно, можешь взять учебник по C++ Улыбаюсь

Передать в структуру элемент можно операцией разыменования типа test[i].
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #107 : 04-01-2009 15:36 » 

Большое, спасибо! Разбираюсь.
А какого типа может быть test?

Все понял.

Если пишу так:
Код: (C++)
...
struct STask_st
Student *src_st;
...
float srbal_st(
    const Student& src_st)   // массив данных
{
    float avg_stud;// переменная для хранения результатов среднего балла для i-го студента
    avg_stud =  src_st->col[0]+src_st->col[1]+src_st->col[2]+src_st->col[3];
    return (avg_stud/(float)4);//средний бал по 4 дисциплинам для i-го студента

}
Пишет:
error: base operand of `->' has non-pointer type `const Student'
« Последнее редактирование: 05-01-2009 11:27 от RXL » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #108 : 04-01-2009 16:19 » 

Правильно, ты разыменовываешь указатель, тогда как тип - не указатель ни разу, он - const Student&.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #109 : 04-01-2009 16:34 » 

Я не знаю как разыменовать тип на указатель  Жаль Пожалуйста, напиши как это должно выглядеть?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #110 : 04-01-2009 18:51 » 

у тебя же ссылка, а не указатель. тебе достаточно src_st.col[0] и т.п.
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #111 : 04-01-2009 19:22 » 

Вад, спасибо, сделал так:
Код: (C++)
    float srbal_st(
    const Student& src_st)   // массив данных
{
    float avg_stud;// переменная для хранения результатов среднего балла для i-го студента
    avg_stud = src_st.col[0]+src_st.col[1]+src_st.col[2]+src_st.col[3];
    return (avg_stud/(float)4);//средний бал по 4 дисциплинам для i-го студента

}
но тогда в компиляторе КодеБлокс в котором я компилю это файл пишет:
undefined reference to `srbal_st(Student*)'
По компиляции в Визуал 2008 пишет:
error LNK2019: unresolved external symbol "float __cdecl srbal_st(struct Student *)" (?srbal_st@@YAMPAUStudent@@@Z) referenced in function "unsigned int __stdcall CalcAvg_st(void *)" (?CalcAvg_st@@YGIPAX@Z)
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #112 : 04-01-2009 19:45 » 

Значит, ты передаёшь из CalcAvg_st в функцию srbal_st не тот тип - не структуру Student, а указатель на неё
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #113 : 04-01-2009 19:56 » 

А как правильно?

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

Я понял, что в этой строчке:
Код: (C++)
task_st->avg_st[i] = srbal_st(task_st->src_st);
я вызываю функцию с неправильным типом аргумента. Тогда, что здесь записать:(?)
Код: (C++)
srbal_st(task_st->src_st)
, что написать вместо src_st?
« Последнее редактирование: 05-01-2009 11:27 от RXL » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #114 : 04-01-2009 21:20 » 

Что касается функции srbal_st, то я бы упростил: такая функция должна считать 1 среднее для 1 студента. Соответственно, в неё передавать только информацию об одном из студентов; возвращать - среднее для него. А цикл поместить в CalcAvg_st, и там чётко понимать, откуда брать данные для вызовов srbal_st и куда записывать результат, возвращаемый функцией.
Что ты хочешь сосчитать вызовом функции srbal_st? Какие исходные данные тебе нужно для этого передать? Откуда взять эти данные в CalcAvg_st? В ответе на эти вопросы содержится решение.
« Последнее редактирование: 04-01-2009 21:22 от Вад » Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #115 : 04-01-2009 21:33 » 

Код: (C++)
float srbal_st(
    const Student& src_st)   // массив данных
{
    float avg_stud;// переменная для хранения результатов среднего балла для i-го студента
    avg_stud = src_st.col[0]+src_st.col[1]+src_st.col[2]+src_st.col[3];
    return (avg_stud/(float)4);//средний бал по 4 дисциплинам для i-го студента
}

Код: (C++)
unsigned __stdcall CalcAvg_st (void * arg)
{   int i;
    STask_st *task_st = (STask_st*) arg;
        if (task_st) // Проверка передачи параметров
    {   for(i = task_st->beg_st; i < task_st->am_st; i++)
        task_st->avg_st[i] = srbal_st(task_st->src_st);
        return 0;
    }
    else
        return 1; // Ошибка!
1-я вроде считает среднее, во второй цикл то же есть. Насчет этого может я неправ:
Цитата
и там чётко понимать, откуда брать данные для вызовов srbal_st и куда записывать результат, возвращаемый функцией.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #116 : 04-01-2009 21:34 » 

Когда ты вызываешь srbal_st в цикле, подсчитать ты хочешь среднее для какого студента?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #117 : 04-01-2009 21:39 » 

Согласен!!! Улыбаюсь Но как указать sr_bal какого(-их) студента(-ов) хотим посичтать?

Я вообще с этими структурами ни какой! Вад, подскажи, что делать...
« Последнее редактирование: 05-01-2009 11:24 от RXL » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #118 : 04-01-2009 21:46 » 

task_st->src_st - это массив студентов, так? ну и как оттуда взять одного студента?
Записан
v.korleone
Помогающий

ua
Offline Offline

« Ответ #119 : 04-01-2009 21:49 » 

Дошло (как мне кажется)... src_st Угадал?

УРАААААААААААААААААААААААААААААААААААААААААААААААААА!!!!

src_st, все было в i. СПАСИБО!!!!!!!!!!!!!!!!!!!!!!!!!

ВАД, БОЛЬШОООООООООООООЕ СПАААААААААСИБО, ЗА ТЕРПЕНИЕ И ПОНИМАНИЕ студента-чайника!!!!
(пока тему, не закрываю, т.к. мне кажется, что препод завтра еще что-то выдумает)
« Последнее редактирование: 05-01-2009 11:24 от RXL » Записан
Страниц: 1 2 3 [4] 5 6   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines