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

Указатели и конструкторы - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Построение таблиц идентификаторов (хеш-функции, рехеширование) http://www.cyberforum.ru/cpp-beginners/thread438884.html
построить таблицу идентификаторов методом хэш-функции, использование метода рехеширования.
C++ Программа для вычисления суммы ряда Составить программу для вычисления суммы данного ряда для указанного значения аргумента х, если известна количество N членов ряда. \sum_{k-1}^{N}{e}^{kx}{\cos }^{2}kx N=10 x=2,1 http://www.cyberforum.ru/cpp-beginners/thread438874.html
C++ Перегруженные функции
Перегруженные функции Написать перегруженные функции и основную программу, которая их вызывает. а) для преобразования десятичной дроби в обыкновенную; б) для преобразования обыкновенной дроби в десятичную. Помогите с написанием кода пожалуйста,а то никак не пойму.
Программа для вычисления функции C++
Состивить программу для вычисления функции y\begin{cases}a{x}^{2}+b\sqrt{x}+c & \text{ if } x=> 5 \\ \pi \arcsin x & \text{ if } x< 5 \end{cases} a=2,3 b=4,1 c=6 Помогите пожалуйста
C++ Линейная программа http://www.cyberforum.ru/cpp-beginners/thread438860.html
Известны меньшее основание "а" равнобокой трапеции, ее высота h и острый угол альфа. Найти периметр Р и площадь S трапеции.
C++ Подсчитать количество слов в файле и... помогите пожалуйста с похожим заданием 1) Скопировать в файл F2 только те строки из F1, которые начинаются с буквы «А». 2) Подсчитать количество слов в F2. подробнее

Показать сообщение отдельно
stawerfar
 Аватар для stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
31.01.2012, 22:30     Указатели и конструкторы
Всем доброго времени суток!!!
Выполняя упражнение Лафоре 10 главы №1 написав и проверив всё столкнулся с такой проблемой.
Проще показать чем объяснить ниже код, там я в комментариях в main написал в какой момент перестает работать.

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include<iostream>
#include<conio.h>
#include<string>
#include<stdlib.h>
class metring
{
private :
    char* ch_pt;//для хранения выражения введённого пользователем
    int imax_fmas;//максимально количество элементов массива fmas
    float* fmas ;//массив вещественных чисел
public:
    //конструктор без параметров
    metring(void);
    //конструктор содним параметром
    metring(char* ch_c);
    //деструктор для освобождение памяти
    ~metring(void);
    //операция преобразования из объекта класса в float*
    operator float*(void);
    //возврат количества элементов в вещественном массиве
    int* return_imax_fmas(void);
    //получение от пользователя набора чисел 
    void get_number(void);
};
 
//конструктор без параметров
metring::metring(void):imax_fmas(1)
{
    setlocale(LC_ALL,"Russian");//разрешаю вывод Русского языка
    ch_pt = new char[2];//первый раз выдиляю память под строку
    ch_pt[0]='\0';//принудительное указаник конца строки
    fmas = new float[imax_fmas];//создаём подходящий по размерам массив для чисел
}
 
//конструктор содним параметром
metring::metring(char* ch_c)
{
    
    setlocale(LC_ALL,"Russian");//разрешаю вывод Русского языка
    ch_pt = new char[2];//первый раз выдиляю память под строку
    ch_pt[0]='\0';//принудительное указаник конца строки
    imax_fmas=1;
    fmas = new float[imax_fmas];//создаём подходящий по размерам массив для чисел   
 
    
    if(strlen(ch_c)>1)
    {delete []ch_pt;}//освобождаю ранее выделенную память т.к. она не достаточна для хранения новой строки 
    ch_pt = new char [strlen(ch_c)+1];
    ch_pt[0]='\0';//принудительное указаник конца строки
    strcpy(ch_pt,ch_c);
    ch_pt[strlen(ch_c)]='\0';//принудительное указаник конца строки
}
//деструктор для освобождение памяти
metring::~metring(void)//освобождаю память
{delete []ch_pt;delete []fmas;}
//получение от пользователя набора чисел 
void metring::get_number(void)
{
    int ilen = 1;//для хранения длинны строки
    char* ch_pt_temp ;//временный банк для обмена
    char ch_temp[2]="e";//инициализация любым значение отличным от нуля и не равным 13(знаку Enter)
    std::cout<<"Введите числа через запятую\nЧисла могут быть целыми так и вещественными : ";
    //создание строки необходимого размера для хранения строки ch_c
    while(ch_temp[0]!=13)//продолжать пока пользователь не нажмёт клавишу Enter
    {
        ch_pt_temp = new char[strlen(ch_pt)+2];//выделяю память под переменную для обмена
        ch_pt_temp[0]='\0';//принудительное указаник конца строки           
        bool flag=true;//флаг для инкримента счетчика символов
        ch_temp[0] = getche();//отобразить символ и записать его значение в переменную типа char
        if(ilen!=1&&ch_temp[0]!=13)//если ilen!=1 и ch_temp!=Enter 
        {                                   //  то освобождаем память для перевыдиления
            //перед освобождением памяти делаю копию значения строки
            //копируем сиволы в нашу строку с нулевым символом
        
            for(int i = 0, r = strlen(ch_pt_temp); i < strlen(ch_pt)+1;i++,r++)
            {
                ch_pt_temp[r]=ch_pt[i]; 
            }
            ch_pt_temp[strlen(ch_pt_temp)+1];//принудительное завершение строки
            delete []ch_pt;//освобождаю выделенную память
            if(ch_temp[0]==8&&strlen(ch_pt_temp))
            {
                std::cout<<"\x20\x08";//затираем предыдущий символ знаком пробела и перемещаем курсор
                ilen--;//уменьшаем значение количество символов в строке
                flag=false;
            }
            else if(ch_temp[0]==8&&strlen(ch_pt_temp)<=0)
            {
                std::cout<<"\x3A";
            }
            ch_pt=new char[ilen+2];//заного выделяю память 1 для нового сивола другой для знака \0 конца строки
            ch_pt[0]='\0';//принудительное указаник конца строки
            //возвращаю значение строки предшествующие перевыдилинию памяти
            //копируем сиволы в нашу строку с нулевым символом
            int itemplen=(strlen(ch_pt_temp)==ilen-2)?ilen-1:ilen;
            for(int i = 0, r = strlen(ch_pt); i < itemplen;i++,r++)
            {
                ch_pt[r]=ch_pt_temp[i]; 
            }
            if(strlen(ch_pt_temp)!=ilen-2)
            {ch_pt[ilen-1]='\0';}
            
        }
        if(ch_temp[0]!=13&&ch_temp[0]!=8)//если ch_temp!=Enter помещаем символ в строку
        {
            //копируем сиволы в нашу строку с нулевым символом
            for(int i = 0, r = strlen(ch_pt); i < strlen(ch_temp)+1;i++,r++)
            {
                ch_pt[r]=ch_temp[i];    
            }
            
        }
        delete[]ch_pt_temp;//освобождаем память
        if(flag)
        {ilen++;}//инкременация счетчика символов
    }
}
 
//операция преобразования из объекта класса в float*
metring:: operator float*(void)
{
    char* ch_pt_temp ;//временный банк для обмена
    int isecondlen=2,//разряд числа
        idex=0;//индекс массива который представляет одно число
    bool flag= true;//флаг для разрешения выдиления памяти для ch_pt_temp
    
    //разбираем массив т.е. отдиляем числа от запятых, целые от вещественных
    for(int i = 0; i<strlen(ch_pt);i++)
    {
        if(flag)//выделяем каждый раз когда следует отдельное число 
        {
            ch_pt_temp = new char[isecondlen];//выделяю память под переменную для обмена
            ch_pt_temp[0]='\0';//принудительное указаник конца строки
            flag=false;//запрещаем перевыдиление памяти пока не закочится число
        }
        
        if(isecondlen>strlen(ch_pt_temp)&&(strlen(ch_pt_temp)!=0)&&ch_pt[i]!=',')
        {
            char* ch_pt_temp2 = new char[isecondlen+2];//выделяю память для временной переменной
            ch_pt_temp2[0]= '\0';//принудительно инициализирую её первый символ нулём
            //копируем сиволы в нашу строку с нулевым символом
            for(int i = 0, r = strlen(ch_pt_temp2); i < strlen(ch_pt_temp)+1;i++,r++)
            {
                ch_pt_temp2[r]=ch_pt_temp[i];   
            }
            delete []ch_pt_temp;//освобождаю память
            //выделяю памяти больше на одну единицу
            ch_pt_temp = new char[isecondlen+2];//выделяю память под переменную для обмена
            ch_pt_temp[0]= '\0';//принудительно инициализирую её первый символ нулём
 
            //копируем сиволы в нашу строку с нулевым символом
            for(int i = 0, r = strlen(ch_pt_temp); i < strlen(ch_pt_temp2)+1;i++,r++)
            {
                ch_pt_temp[r]=ch_pt_temp2[i];   
            }
            delete []ch_pt_temp2;//освобождаю память
        }
        if(ch_pt[i]!=',')//если символ не является разделительным символом то просто копируем цифру
        {
            ch_pt_temp[idex++]=ch_pt[i];//копируем символ
            ch_pt_temp[idex]= '\0';//принудительное завершение строки
            isecondlen++;//увеличиваем разряд числа
        }
        if(ch_pt[i]==','||(i+1>=strlen(ch_pt)))//если символ разделительный то переобразуем массив ch_pt_temp в float
        {
            
            isecondlen=2;//инициализируем  флаг на 1 следящий за разрядом числа
            flag=true;//разрешаем перевыдиление памяти т.к. число закончилось
            if(imax_fmas)//если не нулевое значение значит нужно перевыделить память для вещественного массива
            {
                float* f_mas_temp = new float[imax_fmas];//создаю временный массив для страховки основного массива fmas
                for(int e =0 ; e<imax_fmas;e++)
                {
                    f_mas_temp[e]=fmas[e];//копирую значения массива
                }
                delete []fmas;//освобождаю память
                fmas = new float[imax_fmas+1];// перевыдиляю память
                for(int e =0 ; e<imax_fmas;e++)
                {
                    fmas[e]=f_mas_temp[e];//копирую значения массива
                }
                delete[]f_mas_temp;//освобождаю выделенную память
            }
            ch_pt_temp[idex]='\0';//принудительно завершаю строку нулевым символом
            idex = 0;//обнуление индекса
            //проверка числа т.е. было оно целым или вещественным путем поиска символа '.'
            for(int k = 0 ; k<strlen(ch_pt_temp);k++)
            {
                if(ch_pt_temp[k]=='.')//если такой символ есть то меняю его на ',' так требует atof
                {ch_pt_temp[k]=',';}
            }
 
            //преобразуем массив символов в вещественное число
            fmas[imax_fmas-1] = atof(ch_pt_temp);
            if(!(i+1>=strlen(ch_pt)))
            {imax_fmas++;}//увеличиваем число элементов в вещественном массиве
            delete[]ch_pt_temp;//освобождение памяти для массива для представления любого числа
        }
        
    }
    return (fmas);//возвращаю массив чисел типа float
}
//возврат количества элементов в вещественном массиве
int* metring:: return_imax_fmas(void)
{return(&imax_fmas);}
 
/**************************************************************************************************************/
int main(void)
{
    //объявление класса
    class metring metring_val;
    //прототип
    float avg(metring&);
    //получение значения от пользователя
    metring_val.get_number();
    // подсчёт среднего значения  вывод результата на экран
    std::cout<<std::endl<<"Средние арефметическое : "<<avg(metring_val)<<std::endl;
    //использования конструктора с одним параметром
    class metring metring_val2 ("1,2,3,4,5,6");
    // подсчёт среднего значения  вывод результата на экран
    std::cout<<std::endl<<"Средние арефметическое : "<<avg(metring_val2)<<std::endl;
/*НЕРАБОТАЕТ ЕСЛИ ДЕЛАТЬ ВОТ ТАК
              metring_val2 ="1,2,3,4,5,6";
    // подсчёт среднего значения  вывод результата на экран
    std::cout<<std::endl<<"Средние арефметическое : "<<avg(metring_val2)<<std::endl;
*/
 
system("pause");
 
return 0;
}
float avg(metring& metring_val)
{
    //подсчитываем среднее арефметическое массива вещественных чисел
    float db_result = 0.0;//для среднего арефметического массива
    float* fres = static_cast<float*>(metring_val);
    for(int i=0;i<*(metring_val.return_imax_fmas());i++)
    {db_result+=fres[i];}
 
    return  db_result/ *(metring_val.return_imax_fmas());
}
В этой строчке
C++
1
metring_val2 ("1,2,3,4,5,6");
я вызываю конструктор с одним параметром , там происходят все необходимые действия т.е выделение памяти для массива символов и вещественного массива, так же инициализация поля для хранения количества чисел в вещественном массиве.
НО каким то чудесным образом когда я передаю объект по ссылке оказывается что поля класса оказываются не инициализированными, ну и в следствии ошибка т.к. я обращаюсь к не пойми каким адресам.
Подскажите в чем дело или как исправить если кто сталкивался с подобной ситуацией.
Заранее спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 19:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru