1 Востаннє редагувалося Adamchuk (23.12.2014 00:11:37)

Тема: Глобальні змінні

Потрібно використати глобальні змінні і організувати всі функції в різних файлах.
В мене вийшло зробити його все в одному, а далі не виходить((
Можливо в коді є якісь недоліки, вибачайте, я тільки вчусь.


Загальний код програми

#include <iostream>
#include <ctime>
#include <conio.h>
#include "func.h"

const int rows=3,cols=3;
double AcademicRecord[rows][cols], rez, avg=0;
bool sesrez;
int StudNum, SubNum,choise;
#define Sub1 "Програмування" 
#define Sub2 "Архітектура"
#define Sub3 "Мат аналіз"

using namespace std;


void main()
   {
   system("chcp 1251");
   srand(unsigned(time(0)));
   while (true)
      {
      cout<<"Ввід результатів [1]\t"<<"Виправлення результату [2]\t"<<"Вивід результату [3]\t"<<"Середній бал з екзамену [4]\t"<<endl;
      cout<<"Випадкові результати [5]\t"<<"Очистити екран [6]\t"<<"Вихід [7]\t"<<"Обнулити дані[0]"<<endl;
      switch (_getch())
         {
         case '0':  // обнулення даних
            func0();
            break;
         case '1':    // ввід результатів
            func1();
            break;                                                                                                     
         case '2':    // виправлення результатів
            func2();
            break;
         case '3':    // вивід результатів
            func3();
            break;
         case '4':    // середній бал за екзамен
            func4();
            break;
         case '5': // випадкові результати
            func5();
            break;
         case '6': // очищення екрану
            system("cls");
            break;
         case '7': // вихід з програми
            exit (0);
            break;
         }
      };
   system ("pause");
   }     

void func0()
   {
   for(int i=0;i<rows;++i)
      {
      for(int j=0;j<cols;++j)
         AcademicRecord[i][j]=0;
      }
   system ("cls");
   }
void func1()
   {
   cout<<endl;
   for (int i=0;i<rows;++i)
      {
      cout<<"Введіть результати студента № \t"<<i+1<<endl;
      for (int j=0;j<cols;++j)
         {
         switch (j+1)
            {
            case 1:
               cout<<"Екзамен №"<<j+1<<" - "<<Sub1<<" ";
               cin>>rez;
               AcademicRecord[i][j]=rez;
               break;
            case 2:
               cout<<"Екзамен №"<<j+1<<" - "<<Sub2<<" ";
               cin>>rez;
               AcademicRecord[i][j]=rez;
               break;
            case 3:
               cout<<"Екзамен №"<<j+1<<" - "<<Sub3<<" ";
               cin>>rez;
               AcademicRecord[i][j]=rez;
               break;
            }
         }
      }
   system ("cls");
   }
void func2()
   {
   cout<<endl;
   cout<<"Введіть № студента дані якого бажаєте змінити: ";
   cin>>StudNum;
   cout<<"[1]"<<Sub1<<"\t"<<"[2]"<<Sub2<<"\t\t"<<"[3]"<<Sub3<<endl;
   for (int j=0;j<cols;++j)
      {
      cout<<"\t"<<AcademicRecord[StudNum-1][j]<<"\t\t";
      }
   cout<<endl;
   cout<<"Введіть номер предмету результат якого ви бажаєте змінити ";
   cin>>SubNum;
   cout<<"Ви бажаєте  змінити "<<AcademicRecord[StudNum-1][SubNum-1]<<" на ";
   cin>>rez;
   AcademicRecord[StudNum-1][SubNum-1]=rez;
   cout<<endl;
   system ("cls");
   }
void func3()
   {
   cout<<endl;
   cout<<"№ п/п"<<"\t\t"<<Sub1<<"\t   "<<Sub2<<"\t   "<<Sub3<<endl;
   for (int i=0;i<rows;++i)
      {
      cout<<"Студент №"<<i+1;
      for (int j=0;j<cols;++j)
         {
         cout<<"\t\t"<<AcademicRecord[i][j];
         }
      cout<<endl;
      }
   cout<<endl;
   }
void func4()
   {
   cout<<endl;
   cout<<"Виберіть предмет"<<endl;
   cout<<"[1]"<<Sub1<<"\t"<<"[2]"<<Sub2<<"\t\t"<<"[3]"<<Sub3<<endl;
   switch (_getch())
      {
      case '1':
         for (int i=0;i<rows;++i)
            {
            cout<<Sub1<<" "<<AcademicRecord[i][0]<<endl;
            avg+=AcademicRecord[i][0];
            }
         cout<<"Середній бал за екзамен: "<<avg/rows<<endl;
         break;
      case '2':
         for (int i=0;i<rows;++i)
            {
            cout<<Sub2<<" "<<AcademicRecord[i][1]<<endl;
            avg+=AcademicRecord[i][1];
            }
         cout<<"Середній бал за екзамен: "<<avg/rows<<endl;

         break;
      case '3':
         for (int i=0;i<rows;++i)
            {
            cout<<Sub3<<" "<<AcademicRecord[i][2]<<endl;
            avg+=AcademicRecord[i][2];
            }
         cout<<"Середній бал за екзамен: "<<avg/rows<<endl;
         break;
      default:
         cout<<"Помилка! Ви ввели недопустиме (некоректне) значення!"<<endl;
         break;
      }
   avg=0;
   cout<<endl;
   }
void func5()
   {
   cout<<endl;
   for (int i=0;i<rows;++i)
      {
      for (int j=0;j<cols;++j)
         {
         AcademicRecord[i][j]=1+rand()%5;
         }
      }
   cout<<"Ви заповнили результати випадковими значеннями"<<endl;
   cout<<endl;    
   }

Файл func.h

     
void func1(void);
void func2(void);
void func3(void);
void func4(void);
void func5(void);
void func0(void);

Допоможіть будь ласка.

2

Re: Глобальні змінні

Так попереносьте функції до файлів: наприклад, func0 до файлу func0.cpp, а далі включайте їх, так як ви включили func.h. Глобальні змінні теж можна винести до одного з таких файлів; тільки не використовуйте для їх оголошення define, просто оголосіть їх поза будь-яким блоком.

П’ятихвилинка ненависті

Хочеться взяти і самі знаєте що таким викладачам з такими придуркуватими завданнями

Подякували: leofun011

3

Re: Глобальні змінні

Глобальні змінні треба проголосити в одному з файлів .cpp, в решті треба дати extern - проголошення:
globals.cpp

int my_global;

main.cpp

extern int my_global;

extern означає "в якомусь іншому файлі проекту існує глобальна змінна, треба скористатися нею, а не створювати в цьому".
І глобальні змінні - зло, ви в курсі?

Подякували: Chemist-i, Adamchuk, leofun013

4

Re: Глобальні змінні

koala написав:

Глобальні змінні треба проголосити в одному з файлів .cpp, в решті треба дати extern - проголошення:
globals.cpp

int my_global;

main.cpp

extern int my_global;

extern означає "в якомусь іншому файлі проекту існує глобальна змінна, треба скористатися нею, а не створювати в цьому".
І глобальні змінні - зло, ви в курсі?

Як би в курсі, але умова задачі така...

5 Востаннє редагувалося Adamchuk (23.12.2014 15:08:02)

Re: Глобальні змінні

koala написав:

Глобальні змінні треба проголосити в одному з файлів .cpp, в решті треба дати extern - проголошення:
globals.cpp

int my_global;

main.cpp

extern int my_global;

extern означає "в якомусь іншому файлі проекту існує глобальна змінна, треба скористатися нею, а не створювати в цьому".
І глобальні змінні - зло, ви в курсі?

Таке ще питання. А як можна оголосити всі ці змінні щоб їх можна було використовувати без повторної ініціалізації через extern.
Наприклад, оголосити їх в func.h а тоді просто підключати через include. Є якийсь спосіб, альтернативний?
А то переписувати всі змінні і дописувати extern, якось по-ідіотські виглядає.

6

Re: Глобальні змінні

Adamchuk написав:

А то переписувати всі змінні і дописувати extern, якось по-ідіотські виглядає.

Використовувати глобальні змінні - це ідіотизм, тож і виглядає ідіотично.

Подякували: quez, Adamchuk, leofun013

7

Re: Глобальні змінні

koala написав:
Adamchuk написав:

А то переписувати всі змінні і дописувати extern, якось по-ідіотські виглядає.

Використовувати глобальні змінні - це ідіотизм, тож і виглядає ідіотично.

Я повторюсь.
А як можна оголосити всі ці змінні щоб їх можна було використовувати без повторної ініціалізації через extern.
Наприклад, оголосити їх в func.h а тоді просто підключати через include (чи так не можна?). Є якийсь спосіб, альтернативний?

8 Востаннє редагувалося koala (23.12.2014 23:03:22)

Re: Глобальні змінні

Додайте їх всіх в globals.cpp, і створіть globals.h з extern-проголошеннями. Тільки не інклудьте в globals.cpp globals.h.

9

Re: Глобальні змінні

koala написав:

Додайте їх всіх в globals.cpp, і створіть globals.h з extern-проголошеннями. Тільки не інклудьте в globals.cpp globals.h.

А їх можна оголосити в main.cpp?
Зробивши Вашим методом (+ дані з інших джерел де написано що в extern не можна задавати значення для змінних) вийшов такий код

#pragma once

extern const int rows,cols;
extern double AcademicRecord[rows][cols], rez, avg;
extern bool sesrez;
extern int StudNum, SubNum,choise;
#define Sub1 "Програмування" 
#define Sub2 "Архітектура"
#define Sub3 "Мат аналіз"

але тоді помилка в

extern double AcademicRecord[rows][cols]

що вираз повинен мати константне значення.

10 Востаннє редагувалося P.Y. (24.12.2014 01:22:11)

Re: Глобальні змінні

Можна цей рядок:

const int rows=3,cols=3;

включити в globals.h перед описом масиву, а рядок extern з ними викинути.

Подякували: Adamchuk1

11

Re: Глобальні змінні

А їх можна оголосити в main.cpp?

#include — препроцесорна команда, тому для компілятора не має значення, описано змінні в самому .cpp-файлі чи в .h-файлі, що в нього інклудиться. Але якщо одні й ті ж глобальні об'єкти використовуються кількома модулями, доцільно такі описи робити в спільному .h-файлі, що інклудиться в кожен модуль — це гарантує, що описи у всіх модулях будуть ідентичними, і якщо ми змінимо опис якоїсь глобальної змінної чи функції, ці зміни буде враховано в кожному модулі. Технічно, можна ці описи просто зкопіпастити в кожен модуль, але хороший стиль тут — використати інклуд.

Подякували: Adamchuk1

12 Востаннє редагувалося koala (24.12.2014 12:26:33)

Re: Глобальні змінні

"extern ..." означає "десь в іншому файлі проголошено ...", його тип для компіляції вказано, а от конкретну пам'ять виділяти не треба, бо вона виділена деінде. Масиву треба виділити пам'ять під час проголошення. Але скільки пам'яті - подивитися не виходить, бо ці константи визначені в іншому місці, а тут стоїть тільки нагадування, що вони існують.
А нащо вам здалися глобальні константи? Додайте їх просто в заголовок зі static, хай будуть в усіх файлах. Все одно константи ж.

Подякували: Adamchuk1

13

Re: Глобальні змінні

Тс, потрібні вам змінні ліпше огорніть їх у клас. Зручніше вийде, і екстернів зайвих не треба. А якщо викладач канючитиме про "глобальні змінні" - ну додайте яке-небудь

const char VERSION[] = "1.0";

int main()
{
    printf("MyCoolProgram v %s. Written by Adamchuk. All rights reserved.\n", VERSION);// або через cout - як вам ліпше
}

Так і глобальна, і константа, і код не сильно різко пахне:).


Нижче приклад (по суті, ООП-версія ідеї від koala):

// globals.hxx

class Globals
{
public:
/*    static %place your variables here% */
static int var1;
};

// globals.cxx
#include "globals.h"

int Globals::var1 = 0; // init variable

Globals::Globals()
{}

// *.cxx
#include "globals.hxx"
void myFoo()
{
    int x = Globals::var1;
    // ...
}

14

Re: Глобальні змінні

koala написав:

"extern ..." означає "десь в іншому файлі проголошено ...", його тип для компіляції вказано, а от конкретну пам'ять виділяти не треба, бо вона виділена деінде. Масиву треба виділити пам'ять під час проголошення. Але скільки пам'яті - подивитися не виходить, бо ці константи визначені в іншому місці, а тут стоїть тільки нагадування, що вони існують.
А нащо вам здалися глобальні константи? Додайте їх просто в заголовок зі static, хай будуть в усіх файлах. Все одно константи ж.

Ви можете написати як правильно треба записувати file.h?

15

Re: Глобальні змінні

Правильно - це як? Конкретні вимоги, будь ласка.

16

Re: Глобальні змінні

koala написав:

Правильно - це як? Конкретні вимоги, будь ласка.

#pragma once
#ifndef
#define  що з цього треба записувати, що не треба?
Можливо є якісь правила по оформленню file.h

17

Re: Глобальні змінні

Те, що вам треба - треба.
Те, що вам не треба - не треба.
Можу припустити, що ви за захист включення питаєте, але це тільки припущення.

18

Re: Глобальні змінні

koala написав:

Те, що вам треба - треба.
Те, що вам не треба - не треба.
Можу припустити, що ви за захист включення питаєте, але це тільки припущення.

Просто при написанні програми треба (наприклад)

#include <iostream>
using namespace std;
void main()
{
// тіло функції
}

тобто ми підключили ніби як основні елементи програми: необхідні бібліотеки, простір імен, тоді саму програму записали в void main.
А з file.h є такі обов'язкові елементи?

19

Re: Глобальні змінні

C - це не паскаль, тут немає "основних елементів". Ніхто не визначає вміст файлів. Є домовленості про структуру програми, але вони ніким не нав'язуються і нічого обов'язкового немає - більше того, в різних програмах такі структури різні!
#include просто заміняється на вміст файла, який вказано параметром. using зазвичай означає, що ви дуже тісно працюєте з одним простором імен, далеко не факт, що так буде в реальності. Варіантів проголошення main достобіса, особливо з урахуванням того, що багато фреймворків пропонують свої заміни на кшталт _tmain. Ну і не обов'язково в .cpp-файлі взагалі буде main.
Хоча в будь-якому разі спершу ідуть проголошення, а потім визначення. А проголошення часто виносять в .h-файли, і додають до них include guards. Але нічого більше.

Подякували: Adamchuk1

20

Re: Глобальні змінні

Bartash написав:

Тс, потрібні вам змінні ліпше огорніть їх у клас. Зручніше вийде, і екстернів зайвих не треба. А якщо викладач канючитиме про "глобальні змінні" - ну додайте яке-небудь

const char VERSION[] = "1.0";

int main()
{
    printf("MyCoolProgram v %s. Written by Adamchuk. All rights reserved.\n", VERSION);// або через cout - як вам ліпше
}

Так і глобальна, і константа, і код не сильно різко пахне:).


Нижче приклад (по суті, ООП-версія ідеї від koala):

// globals.hxx

class Globals
{
public:
/*    static %place your variables here% */
static int var1;
};

// globals.cxx
#include "globals.h"

int Globals::var1 = 0; // init variable

Globals::Globals()
{}

// *.cxx
#include "globals.hxx"
void myFoo()
{
    int x = Globals::var1;
    // ...
}

Можливо це і кращий варіант, але класи я ще не вивчав.