Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 5.00
Tolias28
202 / 117 / 2
Регистрация: 18.08.2010
Сообщений: 1,006
29.10.2011, 21:03     Где лучше эти переменные объявлять? #1
Посмотрите пожалуйста на следующий код (код сишный, но компилировался как 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.10.2011, 21:03     Где лучше эти переменные объявлять?
Посмотрите здесь:

C++ Вопрпос про const: в какой области памяти они находятся, и где это объявлять ?
C++ Для чего нужно писать в int main() в скобках всякие args потом объявлять переменные, и прочее. Для чего если можно в сборках это все обьявлять.
C++ Где объявлять переменную: перед циклом, или внутри класса
Где инициализировать переменные класса? C++
C++ Где найти эти книги?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Lonely_Romantic
8 / 8 / 1
Регистрация: 13.07.2010
Сообщений: 14
29.10.2011, 22:54     Где лучше эти переменные объявлять? #2
Оптимально с какой точки зрения? По скорости выделение локальных переменных одинаково, хоть сотня их там будет, т.к. локальные переменные хранятся на стеке и выделяются простым изменением указателя стека.
По памяти оптимально, т.к. когда переменная не нужна она не хранится (так можно для всех процедур выделить память заранее, чтобы потом не выделять, но это шаг назад, к прошлому языков программирования Тут же можно задаться вопросом оптимальности использования ООП перед процедурными парадигмами или вообще принципами ассемблера) Но, думаю, на память таких размеров в наши дни пофиг. Важнее соблюдение парадигмы программирования (влияет на понятность программы, вероятность возникновения и слложность поиска ошибок.) Так что правильно учат: всему свое место, включая переменные.
Tolias28
202 / 117 / 2
Регистрация: 18.08.2010
Сообщений: 1,006
29.10.2011, 22:59  [ТС]     Где лучше эти переменные объявлять? #3
Цитата Сообщение от Lonely_Romantic Посмотреть сообщение
Оптимально с какой точки зрения?
Меня интересует вопрос по скорости выполнения. А то с памятью и так все понятно, что будет оптимальнее, когда переменная объявляется непосредственно перед использованием и удаляется после выхода из функции.

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

Если класс постоянно его использует внутри своих методов, не лучше ли тогда сделать его один раз в качестве приватных данных-членов?
Что бы не пришлось каждый раз запускать конструктор класса, и захватывать ресурсы?
Tolias28
202 / 117 / 2
Регистрация: 18.08.2010
Сообщений: 1,006
29.10.2011, 23:26  [ТС]     Где лучше эти переменные объявлять? #5
Bers, вот-вот Потому я и решил узнать ответ на этот вопрос на форуме, чтобы в дальнейшем разумно распоряжаться с ресурсами при коддинге.
Lonely_Romantic
8 / 8 / 1
Регистрация: 13.07.2010
Сообщений: 14
30.10.2011, 01:05     Где лучше эти переменные объявлять? #6
Ну не совсем без разницы. Тут может быть 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, иначе это та же статическая память, и затраты по времени будут только на иничиализацию объекта. (если, опять же, внутри объекта не исп.динамическая память).

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

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

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

Вы бы пример привели какой-нибудь, чтобы можно было о чем-то конкретном спорить. (ну или контр-пример для моих рассуждений, который покажет что я не прав )
Bers
Заблокирован
30.10.2011, 12:31     Где лучше эти переменные объявлять? #10
Цитата Сообщение от 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 метод не доделан, там нужно с константностью всего метода разобраться
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.10.2011, 13:13     Где лучше эти переменные объявлять? #11
Кроме того, по правилу "единого интерфейса", контейнер-таблица окажет себе большую услугу, если максимально будит похож на все прочие контейнеры стл.
В стл если что итераторы не хранятся в классе.
Bers
Заблокирован
30.10.2011, 13:28     Где лучше эти переменные объявлять? #12
Цитата Сообщение от ForEveR Посмотреть сообщение
В стл если что итераторы не хранятся в классе.
Я не видел моральный класс того же вектора (вся стл у меня перепахана дефайном на дифайне, там сам черт ногу сломит).
Однако записть типа: typename tCont::const_iterator Begin;
Мне прозрачно намекает, что итераторы являются:
- статиками,
- данными-членами класса.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.10.2011, 13:36     Где лучше эти переменные объявлять? #13
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... Где тут объявление переменной???
Bers
Заблокирован
30.10.2011, 13:46     Где лучше эти переменные объявлять? #14
Цитата Сообщение от ForEveR Посмотреть сообщение
Из visual studio 10.0... Где тут объявление переменной???
Вы щас показали псевдонимы типов.

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

И потом, вопрос все равно остаётся: создавать итератор каждый раз заново в каждом методе, где требуется пробег по вектору. Или сделать его один раз членом-данным, и не тратить время на создание/разрушение ?
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
30.10.2011, 13:50     Где лучше эти переменные объявлять? #15
Цитата Сообщение от Bers Посмотреть сообщение
Или сделать его один раз членом-данным
считаю это захламлением области видимости, ИМХО конечно
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.10.2011, 14:48     Где лучше эти переменные объявлять? #16
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, А по сабжу - создавать когда нужен.
Bers
Заблокирован
30.10.2011, 14:54     Где лучше эти переменные объявлять? #17
Цитата Сообщение от ForEveR Посмотреть сообщение
(iterator(this->_Nextnode(this->_Myhead), this));
_Nextnode - эт что за гусь?

Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, А по сабжу - создавать когда нужен.
Изумительно! Все сразу стало ясно и понятно!
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.10.2011, 14:58     Где лучше эти переменные объявлять? #18
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);
        }
Bers
Заблокирован
30.10.2011, 15:06     Где лучше эти переменные объявлять? #19
Цитата Сообщение от ForEveR Посмотреть сообщение
(iterator(this->_Nextnode(this->_Myhead), this));
Я так эту строчку понял - конструируется итератор, который инициализируется какими то внутренними данными..

Цитата Сообщение от ForEveR Посмотреть сообщение
Резоннее создавать объекты, тогда и только тогда, когда они нужны.
А пулы памяти, объектные пулы для чего придумали?
Служебные данные-члены выполняют по сути точно такую же задачу, как и пулы.
Хотя конечно, в примере с вектором сэкономить на итераторах явно не получится.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2011, 19:16     Где лучше эти переменные объявлять?
Еще ссылки по теме:

C++ Где в приведенном коде переменные хранят свои значения
C++ Где найти эти библиотеки?

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

Или воспользуйтесь поиском по форуму:
Сыроежка
Заблокирован
30.10.2011, 19:16     Где лучше эти переменные объявлять? #20
Цитата Сообщение от 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. То естьпоявляютсядополнительные машинные команды по обращению к этой переменной.

Так что я усматриваюлишь одни минусы в вашем подходе!
Yandex
Объявления
30.10.2011, 19:16     Где лучше эти переменные объявлять?
Ответ Создать тему
Опции темы

Текущее время: 01:31. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru