С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
darkAngel
Технофашист
217 / 200 / 4
Регистрация: 11.03.2009
Сообщений: 883
#1

Указатель на пользовательский тип - C++

05.08.2010, 22:40. Просмотров 1782. Ответов 23
Метки нет (Все метки)

Чёто туплю, почему когда передаёшь переменную (например int) параметром через адрес в функцию (параметр - указатель на этот тип), то в теле этой функции для доступа к этой переменной приходится обращаться через указатель как через массив, причём работает только для [0] [1] [2], а дальше выдаёт ошибку. Вообще что значит это? Почему не 1 а 3 элемента и вообще как это так с точки зрения компилятора




p.s. название темы левое, случайно )))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.08.2010, 22:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатель на пользовательский тип (C++):

Зачем нужен указатель на указатель при работе с однонаправленным списком? - C++
День добрый. Столкнулся с непониманием этой темы. В частности, совершенно непонятен алгоритм инициализации такого вот списка. Например:...

Если в класс нужно передать указатель на указатель на массив строк неизвестной длинны? - C++ Builder
Как проинициализировать массив строк wchar_t * (произвольного размера) , если его нужно передать в конструктор класса ? wchar_t *A1 =...

Как сделать пользовательский интерфейс в С++ builder6? - C++ Builder
Есть обычная консольная программа,работающая из командной строки.Хочу сделать простые окошки кнопки ,как это осуществить?Просто не разу не...

Пользовательский тип - Visual C++
Как задать пользовательский тип в С++? То есть аналог type

Пользовательский тип переменной с произвольной размерностью - Visual C++
Можно ли создать тип,переменные которого имеют,к примеру, разрядность 99 бит Например,если int - 32 бит,то нужно int99 бит По заданию...

Пользовательский PEN в MFC - Visual C++
Нужно нарисовать линию с пользовательскими характеристиками (редкие точки)ю Создаю pen c указанием что буду рисовать по образцу. Однако в...

23
darkAngel
Технофашист
217 / 200 / 4
Регистрация: 11.03.2009
Сообщений: 883
06.08.2010, 13:04  [ТС] #16
Не, у меня такая ситуация, в теле функции:
C
1
2
3
4
void ddd(Tlong a)
{
   Tlong *b = &a;
}
Вне функции всё ОК, а так выдаёт ошибку Cannot convert 'long ( * *)[1000]' to 'long ( *)[2][1000]'

Добавлено через 1 минуту
ппочему-то одно измерение массива пропадает ( * *)[1000] и ( *)[2][1000]'
0
Demihalf
Унылый школьник
126 / 60 / 3
Регистрация: 06.11.2009
Сообщений: 354
06.08.2010, 13:44 #17
darkAngel, хм. Можно извратиться и попробовать так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef long int Tlong[2][1000];
  
void ddd(long int **c)
{
    long int ***b = &c;
}
 
int main( void )
{ 
    Tlong a;
    long int **b = new long int*[2];
    for (int i = 0; i < 2; i++) {
        b[i] = new long int[1000];
        
        for (int j = 0; j < 1000; j++) {
            b[i][j] = a[i][j];
        }
    }
     
    ddd(b);
  
    return 0;
}
А вообще, было бы проще сделать отдельный класс, в который инкапсулировать массив.
1
darkAngel
Технофашист
217 / 200 / 4
Регистрация: 11.03.2009
Сообщений: 883
06.08.2010, 22:26  [ТС] #18
void ddd(long int **c)
Да как бы всё с этого и началось в начале темы )) что указатель на Tlong был в параметре. А CyBOSSeR посоветовал просто передавать.

А вообще, было бы проще сделать отдельный класс, в который инкапсулировать массив.
Ага, у же сам так подумал. Да и операции можно перегрузить. Ладно спасибо за помощь.

Добавлено через 3 часа 50 минут
Теперь проблема с перезагрузкой операций. Вот (код не дословный, только основные моменты, чтобы передать суть):

Вот у меня пусть есть класс:
C++
1
2
3
4
5
class Long
{
   long int lng[2][1000];  
   //конструкторы и методы, не пишу
};
Есть 3 объекта:
C++
1
Long a, b, c;
Вот я прегружаю присваивание:
C++
1
2
3
4
5
6
7
Long& operator = (Long &ch)
{
   for (int i=0; i<1000; i++) {
      lng[0][i] = ch.lng[0][i];
      lng[1][i] = ch.lng[1][i];
   }
   return *this;
}

Вот теперь внимание здесь - прегрузка сложения:
C++
1
2
3
4
5
6
Long& operator +(Long chB)
{
   Long *chR = new Long;          
   //....тут идёт сложение, что-то типа: chR->lng[0][0] = lng[0][0] + chB.lng[0][0]
   return *chR;
}

Ну и результат:
c = a + b;
Работает всё ровно, но у меня закрались сомнения. В теле перегрузки сложения я выделал память под новый объект, где хранился результат и возвращал ссылку на него. После шло присваивание, а точнее копирование в переменную C данных по ссылке, полученной из сложения.
Дак получается, что память, куда указывает ссылка, остаётся занятой и превращается в мусор. Как мне быть? очищать её в теле перегрузки присваивания в конце? Тогда получается, если я просто буду присваивать c = b, то будет удаляться нужный объект b.
Надеюсь понятно выразил мысли
0
Demihalf
Унылый школьник
126 / 60 / 3
Регистрация: 06.11.2009
Сообщений: 354
06.08.2010, 22:39 #19
darkAngel, чтобы проверить утечки памяти можно использовать утилиту valgrind или что-нибудь подобное.

Да, и еще, как мне кажется, лучше будет заменить массив на stl'шный vector

Добавлено через 5 минут
Какой-то бессмысленный совет я дал насчет valgrind... Вы зачем в куче память для временного объекта выделяете? Если его объявить в стеке, проблема сама исчезнет.
0
abiprofi
48 / 48 / 2
Регистрация: 04.08.2010
Сообщений: 110
07.08.2010, 03:34 #20
С помощью ключевого слова typedef можно определить новое имя типа данных. Новый тип при этом не создается!
Используя оператор typedef, можно повысить наглядность программы, но нельзя создать новый тип данных!
typedef long int Tlong[2][1000], воспринимается компилятором как long int Tlong[2][1000]
C++
1
2
3
Tlong a;
a[0][0] = 0;//это верно
a[1][999] = 5;//это верно
Добавлено через 1 час 7 минут
Объявление:
C++
1
typedef long int Tlong[2][1000];
Без всяких извращений
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------
//В .h
 void __fastcall Mytest(long int c[][1000]);
//---------------------------------------------------------------------------
//В .cpp
void __fastcall TForm1::Button5Click(TObject *Sender)
{
 Tlong a;
 a[0][0] = 0;
 a[1][999] = 5;
 
 Memo1->Lines->Add(FloatToStr(a[1][999]));//5
 Mytest(a);
 Memo1->Lines->Add(FloatToStr(a[1][999]));//11
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Mytest(long int c[][1000])
{
 c[1][999] = 11;//это верно
}
//---------------------------------------------------------------------------
0
Nick Alte
Эксперт С++
1642 / 1014 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
07.08.2010, 20:41 #21
Цитата Сообщение от Demihalf Посмотреть сообщение
А typedef в Си++ - чаще всего псевдоним для существующего типа.
Даже не просто чаще всего, а вообще всегда. Определённое в typedef имя ничем не отличается от набранного вручную определения этого типа, одно с другим абсолютно взаимозаменяемо.
0
darkAngel
Технофашист
217 / 200 / 4
Регистрация: 11.03.2009
Сообщений: 883
10.08.2010, 23:32  [ТС] #22
Ещё новая проблема.
Создал класс. Перегрузил операции сложения и вычитания.
Пытаюсь из вычитания вызвать перегруженное сложение, но получаю ошибку памяти (скрин).
Как быть?
Даже если через внешнюю функцию вызывать сложение в вычитании, всёравно эта ошибка.
0
Миниатюры
Указатель на пользовательский тип  
Demihalf
Унылый школьник
126 / 60 / 3
Регистрация: 06.11.2009
Сообщений: 354
11.08.2010, 07:58 #23
darkAngel, Access violation означает, что программа лезет в чужие/read-only области памяти. Вооружайтесь дебаггером и ищите, что вызывает ошибку.
0
darkAngel
Технофашист
217 / 200 / 4
Регистрация: 11.03.2009
Сообщений: 883
11.08.2010, 13:39  [ТС] #24
Всё понял причину, даже дебагерством не пришлось заниматься..
Просто к параметрам в перегруженных операциях нужно было оператор ссылки добавить (&). Хотя и без него всё работало и ошибок не было, но вызов операций из операции был не возможен.
0
11.08.2010, 13:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2010, 13:39
Привет! Вот еще темы с ответами:

Указатель на указатель, в чем смысл? - C++ WinAPI
BOOL WTSEnumerateProcesses( _In_ HANDLE hServer, _In_ DWORD Reserved, _In_ DWORD Version, _Out_ PWTS_PROCESS_INFO...

Пользовательский тип - C (СИ)
Как создать пользовательский тип такой же как int только чтобы он вмещал 100-значное число? Мне бы направление куда думать, нужно чтобы...

Пользовательский тип данных - C#
Подскажите как реализовать что-то такое: MyClass a = new MyClass() a = 100; По сути мне нужно сделать что-то вроде типа данных в...

Пользовательский тип данных для C - C++
Помогите пожалуйста создать пользовательский тип данных для языка C, так как мне не хватает обычных....


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

Или воспользуйтесь поиском по форуму:
24
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.