С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/25: Рейтинг темы: голосов - 25, средняя оценка - 5.00
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018

Где лучше эти переменные объявлять?

29.10.2011, 21:03. Показов 5028. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Посмотрите пожалуйста на следующий код (код сишный, но компилировался как C++, так как в чистом Си нет ООП... Но не это меня в данном случае интересует). А интересует следующее. В классе есть 8 функций, в которых в циклах используется переменная i. В данном коде я ее объявил в классе, как приватную, которая одна для всех функций. Но так, как учили делать, говорят, что эта переменная должна быть у каждой функции своя и объявляться типа так: for(int i=0; бла-бла-бла). Но я не пойму одного момента... Ведь получается, что если делать так, как в последнем случае, то за всю работу программы эта переменная i будет десятки раз создаваться, потом удаляться десятки раз при выходе из функции. Разве это оптимально?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <alloc.h>
#include <stdlib.h>
#include <conio.h>
 
#define SIZE_ARR1 7;
 
class Arr{
    private:
        int *arr;
        int i, j, n, num;
    public:
        Arr()
        {
            n=SIZE_ARR1;
            arr=(int*)malloc(n*sizeof(int));
        }
        Arr(int nums)
        {
            n=nums;
            arr=(int*)malloc(n*sizeof(int));
        }
        ~Arr()
        {
            free(arr);
        }
        void InputArr()
        {
            for(i=0;i<n;i++)
            {
                printf("arr[%d] = ",i);
                scanf("%d",&arr[i]);
            }
        }
        void ShowArr()
        {
            for(i=0;i<n;i++)
                printf("arr[%d] = %d\n", i, arr[i]);
        }
        int NumberNegative()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]<0)
                    num++;
            return num;
        }
        int NumberPositive()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]>0)
                    num++;
            return num;
        }
        int NumberZero()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]==0)
                    num++;
            return num;
        }
        int SumNegative()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]<0)
                    num+=arr[i];
            return num;
        }
        int SumPositive()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]>0)
                    num+=arr[i];
            return num;
        }
        float AverageNegative()
        {
            return (float)SumNegative()/(float)NumberNegative();
        }
        float AveragePositive()
        {
            return (float)SumPositive()/(float)NumberPositive();
        }
        void DeleteNegativeZero()
        {
            int np = NumberPositive();
            if(!np)
                return;
            for(i=0,j=0;i<n;i++)
            {
                if(arr[i]>0)
                {
                    arr[j]=arr[i];
                    j++;
                }
            }
            n=np;
            arr=(int*)realloc(arr,n*sizeof(int));
        }
};
 
int main()
{
    Arr Arr1;
    Arr1.InputArr();
    puts("\nThe contents of the array:");
    Arr1.ShowArr();
    printf("The number of negative elements: %d\n", Arr1.NumberNegative());
    printf("The number of positive  elements: %d\n", Arr1.NumberPositive());
    printf("The number of zero  elements: %d\n", Arr1.NumberZero());
    printf("The sum of negative elements: %d\n", Arr1.SumNegative());
    printf("The sum of positive elements: %d\n", Arr1.SumPositive());
    if(Arr1.NumberNegative())
        printf("The average of negative  elements: %.2f\n", Arr1.AverageNegative());
    if(Arr1.NumberPositive())
        printf("The average of positive  elements: %.2f\n", Arr1.AveragePositive());
    Arr1.DeleteNegativeZero();
    puts("Array after the removal of negative and zero elements:");
    Arr1.ShowArr();
    puts("Complete.");
    getch();
    puts("\nDo you want to create another array? (y or n)");
    if(getch()!='y')
        return 0;
    int number;
    puts("Enter the number of array elements");
    scanf("%d",&number);
    Arr Arr2(number);
    Arr2.InputArr();
    puts("\nThe contents of the array:");
    Arr2.ShowArr();
    puts("\nPress any key to exit...");
    getch();
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.10.2011, 21:03
Ответы с готовыми решениями:

Глобальные переменные и массивы: как объявлять и использовать?
Доброго времени суток! Не знаю, как объявить глобальные переменные и массивы и как их потом юзать. Приведите простые примеры их...

Как лучше объявлять переменные
Написал такой код, который сначала получает несколько(много) текстовых файлов: DirectoryInfo FilesPath = new...

Как и где объявлять глобальные переменные типа String?
Извините за нубовский вопрос, но никак не могу разобраться где и как объявлять глобальные переменные в коде программы: изначально...

31
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
29.10.2011, 22:54
Оптимально с какой точки зрения? По скорости выделение локальных переменных одинаково, хоть сотня их там будет, т.к. локальные переменные хранятся на стеке и выделяются простым изменением указателя стека.
По памяти оптимально, т.к. когда переменная не нужна она не хранится (так можно для всех процедур выделить память заранее, чтобы потом не выделять, но это шаг назад, к прошлому языков программирования Тут же можно задаться вопросом оптимальности использования ООП перед процедурными парадигмами или вообще принципами ассемблера) Но, думаю, на память таких размеров в наши дни пофиг. Важнее соблюдение парадигмы программирования (влияет на понятность программы, вероятность возникновения и слложность поиска ошибок.) Так что правильно учат: всему свое место, включая переменные.
1
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
29.10.2011, 22:59  [ТС]
Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
Оптимально с какой точки зрения?
Меня интересует вопрос по скорости выполнения. А то с памятью и так все понятно, что будет оптимальнее, когда переменная объявляется непосредственно перед использованием и удаляется после выхода из функции.

Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
По скорости выделение локальных переменных одинаково, хоть сотня их там будет, т.к. локальные переменные хранятся на стеке и выделяются простым изменением указателя стека.
То есть, по скорости нету разницы, объявляется ли одна глобальная перменная и потом используется в сотнях функций, или же при входе в сотни функций там объявляется каждый раз локальная переменная. Я правильно понял?
0
Заблокирован
29.10.2011, 23:21
Цитата Сообщение от Tolias28 Посмотреть сообщение
То есть, по скорости нету разницы, объявляется ли одна глобальная перменная и потом используется в сотнях функций, или же при входе в сотни функций там объявляется каждый раз локальная переменная. Я правильно понял?
Меня так же мучает этот вопрос. Предположим, что переменная i - это не просто int, а экземпляр полноценного класса, причем довольно таки увесистого. Какой нибудь тяжеловесный итератор.
Каждый раз при входе в функцию он будит создаваться, а при выходе - разрушаться.

Если класс постоянно его использует внутри своих методов, не лучше ли тогда сделать его один раз в качестве приватных данных-членов?
Что бы не пришлось каждый раз запускать конструктор класса, и захватывать ресурсы?
1
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
29.10.2011, 23:26  [ТС]
Bers, вот-вот Потому я и решил узнать ответ на этот вопрос на форуме, чтобы в дальнейшем разумно распоряжаться с ресурсами при коддинге.
0
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
30.10.2011, 01:05
Ну не совсем без разницы. Тут может быть 2 случая:
1) Если в подпрограмме нет локальных переменных, то выполнится на 1 процессорную инструкцию меньше (вычитание числа - размера памяти для локальных переменных из указателя стека)
2) иначе, если есть другие локальные переменные, тогда действительно без разницы, потому что появление еще одной переменной увеличиват вычитаемое число, а не количество инструкций.

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

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

p.s. По ходу рассуждения над Вашим вопросом возник другой: есть ли разница по скорости между
C++
1
for (int i; ; )
И
C++
1
2
int i;
for (i; ; );
Если интересно, попробую проверить

Цитата Сообщение от Bers Посмотреть сообщение
Предположим, что переменная i - это не просто int, а экземпляр полноценного класса
Да, наверное. Тут конечно от ситуации зависит. Просто выделить переменную - это быстро, а создавать и разрушать объекты - это уже динамическая память, которая обрабатывается значительно медлеенее, и если можно сократить выделение/освобождение такой памяти, то хорошо.

Добавлено через 1 час 32 минуты
Вынужден Вас огорчить: эксперимент с компиляцией различных вариантов объявления переменной ни к чему хорошему не привел:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <windows.h>
 
class myClass
{
    int x,c,d;
public:
    void math(int a)
    {
        x = 0;
        int b = 0;
        a += 1;
        for (int i = 0; i <= a; i++)
            x += i;
    }
    void print()
    {
        printf("%d\n", x);
    }
};
 
int main()
{
    myClass arr = myClass();
    arr.math(10);
    arr.print();
    return 0;
}
в debug режиме выделяется некий фиксированный объем памяти для локальных переменных, намного превышающий необходимый для 1-2 переменных. И строчки типа
Assembler
1
2
008D14E8   8945 E0          MOV DWORD PTR SS:[EBP-20],EAX
008D14EB   8B45 E0          MOV EAX,DWORD PTR SS:[EBP-20]
явно свидетельствуют о том, что оптимальности тут не было и не будет (debug все-таки)

в release вызов метода явно не представлен: программа скомпилировалась как последовательность команд. Как оно будет выглядеть в более сложных случаях сказать сложно.

Отсюда можно сделать выводы:
1) Отнести выделение памяти для переменных к статическому распределению памяти (оно изначально быстрое) и предоставить работу по оптимизации компилятору.
2) Разделить выделение памяти на статическое и динамическое (более медленное).
Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
создавать и разрушать объекты - это уже динамическая память
исправлюсь: так будет только в случае явного использования операторов new и delete, иначе это та же статическая память, и затраты по времени будут только на иничиализацию объекта. (если, опять же, внутри объекта не исп.динамическая память).

Получается, каждый случай специфичен, и нельзя дать универсальный ответ, как правильно поступить. Будет лучше изучить, как устроена работа с объектами, выделением памяти, хорошо в этом разобраться и руководствоваться здравым сыслом.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
30.10.2011, 01:17
Цитата Сообщение от Bers Посмотреть сообщение
Если класс постоянно его использует внутри своих методов, не лучше ли тогда сделать его один раз в качестве приватных данных-членов?
Что бы не пришлось каждый раз запускать конструктор класса, и захватывать ресурсы?
не лучше, для таки целей есть static переменные
0
Заблокирован
30.10.2011, 01:20
Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
исправлюсь: так будет только в случае явного использования операторов new и delete, иначе это та же статическая память, и затраты по времени будут только на иничиализацию объекта. (если, опять же, внутри объекта не исп.динамическая память).
Значит, если объект внутри себя использует динамическую память, либо затраты на его инициализацию велики сами по себе (допустим это сложный-долгий процесс, расчеты там какие то хитрые происходят), то есть смысл создать его один раз в качестве данного-члена, а не создавать каждый раз заново в каждом вызове методов.

Если же это примитивный локальный int, то и нечего заморачиваться.

Я правильно вас понял?
0
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
30.10.2011, 11:21
Bers, из ваших слов
Цитата Сообщение от Bers Посмотреть сообщение
(допустим это сложный-долгий процесс, расчеты там какие то хитрые происходят)
становится уже понятно, что "сложный-долгий процесс" длится долго. Конечно было бы неплохо избавиться от таких повторяющихся долгих вычислений.

Вы бы пример привели какой-нибудь, чтобы можно было о чем-то конкретном спорить. (ну или контр-пример для моих рассуждений, который покажет что я не прав )
0
Заблокирован
30.10.2011, 12:31
Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
Вы бы пример привели какой-нибудь, чтобы можно было о чем-то конкретном спорить. (ну или контр-пример для моих рассуждений, который покажет что я не прав
1.Я не спорю, я пытаюсь понять.

2. Пример - класс Контейнера2Д. На самом деле это обертка на вектором контейнеров (по умолчанию - над вектором векторов)
Предоставляет интерфейс управления "матрицей". Многие методы внутри себя создают Итератор вектора. И с его помощью осуществляют пробег по массиву.

Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void_TContainer2D::Copy(TContainer2D& priemnick, const SRectange& target)
{
    SRectange modTarget(target); ModificatedRectange(modTarget);
    priemnick.ReSize(modTarget.sizeX,modTarget.sizeY);
 
    typename tCont::const_iterator Begin;
    typename tCont::const_iterator End;
    typename CTable::iterator BeginTable=myTable.begin()+modTarget.y;
    typename CTable::iterator IterPriemnick=priemnick.myTable.begin();
 
    while(IterPriemnick!=priemnick.myTable.end())
    {
        Begin=BeginTable->begin()+modTarget.x;
        End =Begin+modTarget.sizeX;
        IterPriemnick->assign(Begin, End);
        ++BeginTable; ++IterPriemnick;
    }
}
Я не знаю насколько трудозатратно создание итератора стандартного контейнера, но:
1. Многие методы вынуждены постоянно создавать их, и разрушать.

2. Обертка позволяет хранить строки матрицы не только в виде вектора, но и в виде стринга, виде дека, в виде самопального какого нибудь одномерного контейнера. А это значит, что теоретически, итератор может быть каким угодно, вплоть до того, что будит жрать дин. память.

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

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

То бишь, итераторы таблицы неплохо было бы забацать в виде статик-членов...

/ps метод не доделан, там нужно с константностью всего метода разобраться
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.10.2011, 13:13
Кроме того, по правилу "единого интерфейса", контейнер-таблица окажет себе большую услугу, если максимально будит похож на все прочие контейнеры стл.
В стл если что итераторы не хранятся в классе.
0
Заблокирован
30.10.2011, 13:28
Цитата Сообщение от ForEveR Посмотреть сообщение
В стл если что итераторы не хранятся в классе.
Я не видел моральный класс того же вектора (вся стл у меня перепахана дефайном на дифайне, там сам черт ногу сломит).
Однако записть типа: typename tCont::const_iterator Begin;
Мне прозрачно намекает, что итераторы являются:
- статиками,
- данными-членами класса.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.10.2011, 13:36
Bers, ЭЭЭ... Вы ничего не забыли?

C++
1
2
3
4
5
6
    typedef _List_const_iterator<_Mybase>
        const_iterator;
    typedef _List_iterator<_Mybase>
        iterator;
 
    typedef _STD reverse_iterator<iterator> reverse_iterator;
Из visual studio 10.0... Где тут объявление переменной???
0
Заблокирован
30.10.2011, 13:46
Цитата Сообщение от ForEveR Посмотреть сообщение
Из visual studio 10.0... Где тут объявление переменной???
Вы щас показали псевдонимы типов.

А вы покажите реализацию метода std::vector<int>::begin();
Сразу станет понятно, он создается заново каждый раз, или присутствует в принципе.

И потом, вопрос все равно остаётся: создавать итератор каждый раз заново в каждом методе, где требуется пробег по вектору. Или сделать его один раз членом-данным, и не тратить время на создание/разрушение ?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
30.10.2011, 13:50
Цитата Сообщение от Bers Посмотреть сообщение
Или сделать его один раз членом-данным
считаю это захламлением области видимости, ИМХО конечно
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.10.2011, 14:48
Bers,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
iterator begin()
        {   // return iterator for beginning of mutable sequence
        return (iterator(this->_Nextnode(this->_Myhead), this));
        }
 
    const_iterator begin() const
        {   // return iterator for beginning of nonmutable sequence
        return (const_iterator(this->_Nextnode(this->_Myhead), this));
        }
 
    iterator end()
        {   // return iterator for end of mutable sequence
        return (iterator(this->_Myhead, this));
        }
 
    const_iterator end() const
        {   // return iterator for end of nonmutable sequence
        return (const_iterator(this->_Myhead, this));
        }
Добавлено через 41 секунду
Bers, А по сабжу - создавать когда нужен.
0
Заблокирован
30.10.2011, 14:54
Цитата Сообщение от ForEveR Посмотреть сообщение
(iterator(this->_Nextnode(this->_Myhead), this));
_Nextnode - эт что за гусь?

Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, А по сабжу - создавать когда нужен.
Изумительно! Все сразу стало ясно и понятно!
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
30.10.2011, 14:58
Bers, Вот _NextNode - объект, содержащийся в классе. Но итератор создается только когда нужен, при вызове begin к примеру.

Резоннее создавать объекты, тогда и только тогда, когда они нужны.

Добавлено через 2 минуты
Хотя нет. Я не прав.


C++
1
2
3
4
    static _Nodepref _Nextnode(_Nodeptr _Pnode)
        {   // return reference to successor pointer in node
        return ((_Nodepref)(*_Pnode)._Next);
        }
0
Заблокирован
30.10.2011, 15:06
Цитата Сообщение от ForEveR Посмотреть сообщение
(iterator(this->_Nextnode(this->_Myhead), this));
Я так эту строчку понял - конструируется итератор, который инициализируется какими то внутренними данными..

Цитата Сообщение от ForEveR Посмотреть сообщение
Резоннее создавать объекты, тогда и только тогда, когда они нужны.
А пулы памяти, объектные пулы для чего придумали?
Служебные данные-члены выполняют по сути точно такую же задачу, как и пулы.
Хотя конечно, в примере с вектором сэкономить на итераторах явно не получится.
0
Заблокирован
30.10.2011, 19:16
Цитата Сообщение от Tolias28 Посмотреть сообщение
Посмотрите пожалуйста на следующий код (код сишный, но компилировался как C++, так как в чистом Си нет ООП... Но не это меня в данном случае интересует). А интересует следующее. В классе есть 8 функций, в которых в циклах используется переменная i. В данном коде я ее объявил в классе, как приватную, которая одна для всех функций. Но так, как учили делать, говорят, что эта переменная должна быть у каждой функции своя и объявляться типа так: for(int i=0; бла-бла-бла). Но я не пойму одного момента... Ведь получается, что если делать так, как в последнем случае, то за всю работу программы эта переменная i будет десятки раз создаваться, потом удаляться десятки раз при выходе из функции. Разве это оптимально?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <alloc.h>
#include <stdlib.h>
#include <conio.h>
 
#define SIZE_ARR1 7;
 
class Arr{
    private:
        int *arr;
        int i, j, n, num;
    public:
        Arr()
        {
            n=SIZE_ARR1;
            arr=(int*)malloc(n*sizeof(int));
        }
        Arr(int nums)
        {
            n=nums;
            arr=(int*)malloc(n*sizeof(int));
        }
        ~Arr()
        {
            free(arr);
        }
        void InputArr()
        {
            for(i=0;i<n;i++)
            {
                printf("arr[%d] = ",i);
                scanf("%d",&arr[i]);
            }
        }
        void ShowArr()
        {
            for(i=0;i<n;i++)
                printf("arr[%d] = %d\n", i, arr[i]);
        }
        int NumberNegative()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]<0)
                    num++;
            return num;
        }
        int NumberPositive()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]>0)
                    num++;
            return num;
        }
        int NumberZero()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]==0)
                    num++;
            return num;
        }
        int SumNegative()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]<0)
                    num+=arr[i];
            return num;
        }
        int SumPositive()
        {
            num=0;
            for(i=0;i<n;i++)
                if(arr[i]>0)
                    num+=arr[i];
            return num;
        }
        float AverageNegative()
        {
            return (float)SumNegative()/(float)NumberNegative();
        }
        float AveragePositive()
        {
            return (float)SumPositive()/(float)NumberPositive();
        }
        void DeleteNegativeZero()
        {
            int np = NumberPositive();
            if(!np)
                return;
            for(i=0,j=0;i<n;i++)
            {
                if(arr[i]>0)
                {
                    arr[j]=arr[i];
                    j++;
                }
            }
            n=np;
            arr=(int*)realloc(arr,n*sizeof(int));
        }
};
 
int main()
{
    Arr Arr1;
    Arr1.InputArr();
    puts("\nThe contents of the array:");
    Arr1.ShowArr();
    printf("The number of negative elements: %d\n", Arr1.NumberNegative());
    printf("The number of positive  elements: %d\n", Arr1.NumberPositive());
    printf("The number of zero  elements: %d\n", Arr1.NumberZero());
    printf("The sum of negative elements: %d\n", Arr1.SumNegative());
    printf("The sum of positive elements: %d\n", Arr1.SumPositive());
    if(Arr1.NumberNegative())
        printf("The average of negative  elements: %.2f\n", Arr1.AverageNegative());
    if(Arr1.NumberPositive())
        printf("The average of positive  elements: %.2f\n", Arr1.AveragePositive());
    Arr1.DeleteNegativeZero();
    puts("Array after the removal of negative and zero elements:");
    Arr1.ShowArr();
    puts("Complete.");
    getch();
    puts("\nDo you want to create another array? (y or n)");
    if(getch()!='y')
        return 0;
    int number;
    puts("Enter the number of array elements");
    scanf("%d",&number);
    Arr Arr2(number);
    Arr2.InputArr();
    puts("\nThe contents of the array:");
    Arr2.ShowArr();
    puts("\nPress any key to exit...");
    getch();
    return 0;
}
Во-первых,вы уж как-то определитесь,то ли действительно у васкод, как вы пишите, "сишный", или же выпишите код С++.

Теперь что касается вашего вопроса. Ваша переменная i, никакой полезной информации о классе не несет. Вы лишь засоряете объявление своего класса рабочими переменными, которые нужны лишь кратковременно. Но зато вы при этом увеличиваете размер своего класса! И к тому же запутываете пользователей вашего класса!
К тому же вы ничего на самомделе не оптимизируете! Еслибыэта переменная была былокальной переменной каждой функции, то компилятор мог бьпоместитьее в один регистр, икодбыл быкомпактным, так как никакие дополнительные машинные инструкции пообращению к этой переменной не требовались! Другое дело, когдаэта переменная - член класса. Теперь к ней можнообратиться лишьчерез указатель this. То естьпоявляютсядополнительные машинные команды по обращению к этой переменной.

Так что я усматриваюлишь одни минусы в вашем подходе!
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.10.2011, 19:16
Помогаю со студенческими работами здесь

Где лучше объявлять функции API - в форме или модуле
вопрос про использование вообще API и конкретно одной функции. 1) почему когда я описывал функцию в форме оно ругалось, стоило перенести...

Глобальные переменные, методы - где лучше заводить?
Добрый день! Только начинаю осваивать Android разработку. Бывает так, что для удобства требуется завести глобальные переменные,...

Зачем объявлять переменные?
В самом деле. Зачем объявлять переменные, если требуется просто написать решение, сдать преподавателю И забыть все на свете. Но вот...

Как правильно объявлять переменные?
Здравствуйте, перед тем как писать что то наподобие &quot;google в помощь&quot; скажу что на разных сайтах написано по разному! Собственно говоря...

Как объявлять глобальные переменные в с#?
В общем, хочу написать программу рисования линий из одной точки. То есть по событию Form1_MouseDown будет инициализироваться эта самая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru