Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
5 / 5 / 0
Регистрация: 22.10.2013
Сообщений: 103

Передать указатель в метод по ссылке и подобное

03.03.2015, 15:54. Показов 3376. Ответов 62
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Первая часть: Change(*t1); - это нормальная практика? Тут по сути мы разъименовываем указатель и получаем адрес памяти в куче? Я всё правильно понимаю?
Вторая часть: Массив это по сути тоже указатель, только на отрезок в памяти? Можно ли при передаче в функцию Fill(arr); получить размерности массива? Или только передать размерности? Есть ли возможность передать обычный массив в такую функцию? Был бы весьма благодарен если бы помогли разобраться с этим...
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
class Test
{
public:
    int value;
 
    Test()
    {
        value = 0;
    }
};
 
void Change(Test& obj)
{
    obj.value = 777;
}
 
void Fill(int **arr)
{
    // типо происходит заполнение
}
 
int main()
{
    Test t;
    Test *t1 = new Test();
 
    Change(t);
    Change(*t1);
 
    delete t1;
 
///////////////////////////////////////////////////////////
 
    int **arr = new int*[5];
    for (size_t i = 0; i < 5; i++)
        arr[i] = new int[5];
 
    Fill(arr);
 
    int mass[5][5];
 
    Fill(mass);
 
    for (size_t i = 0; i < 5; i++)
        delete arr[i];
    delete []arr;
 
    return 0;
}
Примеры наглядные, просто хочу разобраться...
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.03.2015, 15:54
Ответы с готовыми решениями:

В функцию-метод передать указатель на другую функцию-метод и вызвать через переданный указатель
Друзья! Всем привет. Вот код: class otets { public: void f (void (otets::*p)()); private: void echo_f (){}; ...

Можно ли передать в метод свойство по ссылке
Имеется метод int metod(ref Peremennia peremennia ) { metod++; ... } peremennia - это обычная переменная. Вопрос...

Как в аргумент функции передать указатель на метод класса?
Как в аргумент функции передать указатель на метод класса? Метод в классе у меня статический,все равно не получается(невозможно...

62
04.03.2015, 09:38
Студворк — интернет-сервис помощи студентам

Не по теме:

hoggy, такое только со стат массива, в данном примеры был вариант передачи по указателю.. и неизвестно как будет выделена память под массив, может быть new...

0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.03.2015, 09:40
Цитата Сообщение от castorsky Посмотреть сообщение
Но это еще ничего, тут пациенты утверждают что a имеет тип int[5]. Я никого за язык не тянул.
Именно так и есть. А что тебя смущает?
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 10:01
Цитата Сообщение от Voivoid Посмотреть сообщение
Подозреваю, что твой компилятор пытается выполнить decay типа до указателя с надеждой
Мне не надо это компилировать чтобы понять что происходит. Разве что скопилировать и указать публике на их ошибки. Проблема в том что за один проход это сложно выявить учитывая особенность преобразований, хотя константный тип вполне себе легко. Ради интереса отпиши в багзиллу, почитаем комменты.
Цитата Сообщение от Voivoid Посмотреть сообщение
Именно так и есть. А что тебя смущает?
Меня ничего не смущает. Просто это ложь, ибо таких типов в языке нет. Как ноль в математике, формаьлная абстракция, а потрогать (или создать, что важно в разрезе темы) нельзя.

Добавлено через 4 минуты
Цитата Сообщение от aLarman Посмотреть сообщение
в данном примеры был вариант передачи по указателю
когда мы работаем с указателями, то всегда размер массива надо хранить отдельно, или в первом элементе массива, или инкапсулировать, но в любом случае размер должен где-то быть под нашим неусыпным контролем.
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:04
Цитата Сообщение от castorsky Посмотреть сообщение
когда мы работаем с указателями, то всегда размер массива надо хранить отдельно, или в первом элементе массива, или инкапсулировать, но в любом случае размер должен где-то быть под нашим неусыпным контролем.
да я то в курсе, вот hoggy, так не считает видимо...
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.03.2015, 10:10
Цитата Сообщение от castorsky Посмотреть сообщение
Ну ты был немного уверенней.
Ну дык, одно дело знание C++, а совсем другое знание реализации компилятора.

Цитата Сообщение от castorsky Посмотреть сообщение
Просто это ложь, ибо таких типов в языке нет
Ну, лол, т.е. по твоему у переменной a тип int (*)[5]? Или какой?

Цитата Сообщение от castorsky Посмотреть сообщение
Как ноль в математике, формаьлная абстракция, а потрогать (или создать, что важно в разрезе темы) нельзя.
Лол, ага, с такой логикой недалеко и до байтиков добраться-то
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 10:14
Цитата Сообщение от Voivoid Посмотреть сообщение
Ну дык, одно дело знание C++, а совсем другое знание реализации компиляторов
Нельзя сказать что знаешь язык если не пытался написать для него компилятор/транслятор/интерпретатор. Вот когда попробуешь, тогда прозреешь от убожества этого недоязыка.
Цитата Сообщение от Voivoid Посмотреть сообщение
Ну, лол, т.е. по твоему у переменной a тип int (*)[5]? Или какой?
Я об этом уже неоднократно говорил. Сишные массивы не объекты, они просто не могут иметь другой тип.
Цитата Сообщение от Voivoid Посмотреть сообщение
Лол, ага, с такой логикой недалеко и до байтиков добраться-то
Это же с++, тут и память контролировать надо и частичная си совместимоять. Самое что ни на есть байтослесарство. Не нужно себя обманывать, крестовики - байтослесари.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.03.2015, 10:31
Цитата Сообщение от castorsky Посмотреть сообщение
Я об этом уже неоднократно говорил. Сишные массивы не объекты, они просто не могут иметь другой тип.
Ок, тогда смотри, есть вот такой код:
C++
1
2
  typedef int X[ 5 ];
  typedef int( *Y )[ 5 ];
Что ты можешь сказать о типах X и Y? Это одинаковые типы? Если да, то почему? Разные типы? Если разные, в чем их различие? И вообще что они собой представляют?
Или это вообще какая-то бесполезная фигня для детей, мол я всегда найду способ скастить все что угодно чтобы добраться до заветного байтика?

Цитата Сообщение от castorsky Посмотреть сообщение
Это же с++, тут и память контролировать надо и частичная си совместимоять
Ну да, это одна из его частей позволяющая писать высокопроизводительный код. Только не надо забывать и про другую часть: возможность строить абстракции практически произвольной сложности. Благодаря кстати в том числе и достаточно развитой системе типов. Только C'шникам этого непонять. Им система типов только мешает, не дает с байтиками работать напрямую, лол. У них же каст на касте и кастом погоняет.

Добавлено через 6 минут
Цитата Сообщение от castorsky Посмотреть сообщение
Нельзя сказать что знаешь язык если не пытался написать для него компилятор/транслятор/интерпретатор
Лол, это что-то уровня: нельзя разбираться в живописи если сам не нарисовал шедерв
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 10:36
Цитата Сообщение от Voivoid Посмотреть сообщение
Ок, тогда смотри, есть вот такой код
не понимаю подвоха, это разные объекты (в широком смысле), которые просто нельзя сравнивать. Первое - синтаксический сахар, второе - фактическое представление первого в "физическом" смысле при попытке доступа. И кстати не единственное, ибо как мы видели компилятор также может привести и к типу int*, что есть неоднозначность и убогость системы типов доставшаяся в наследство.
Цитата Сообщение от Voivoid Посмотреть сообщение
олько не надо забывать и про другую часть
Ок, я помню
Цитата Сообщение от Voivoid Посмотреть сообщение
Только C'шникам этого непонять. Им система типов только мешает, не дает с байтиками работать напрямую, лол. У них же каст на касте и кастом погоняет.
Не по адресу.

Добавлено через 2 минуты
Цитата Сообщение от Voivoid Посмотреть сообщение
Лол, это что-то уровня: нельзя разбираться в живописи если сам не нарисовал шедерв
Это вывод, основанный на ошибочной предпосылке. Логическая ошибка. Ты можешь знать в совершенстве язык forth и утверждать что программа на forth'e есть стек, но когда попытаешься написать его рантайм, то сильно обломаешься. И никакие шедевры тут не при чем, это обычному студенту под силу.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
04.03.2015, 11:13
Просто ради интереса, если это баг компилятора, то какой компилятор способен скомпилировать это без ошибок и предупреждений?
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 11:20
castaway,
Цитата Сообщение от castorsky Посмотреть сообщение
Ради интереса отпиши в багзиллу, почитаем комменты.
Это скорее баг языка, хотя возможно и компилятора.
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2222 / 1424 / 419
Регистрация: 16.05.2013
Сообщений: 3,639
Записей в блоге: 6
04.03.2015, 11:28
Цитата Сообщение от castorsky Посмотреть сообщение
Но это еще ничего, тут пациенты утверждают что a имеет тип int[5]. Я никого за язык не тянул.
Переменная a имеет тип int[5]. Переменная с имеет тип указателя на массив int[5]. Это легко показать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    // a имеет тип int(*)[5]
    int a[5];
 
    // компилятор умный, он знает что мы с помощью указателя хотим пробежаться по массиву
    // во время компиляции a неявно приводится к int*
    int * pa = a;
 
    // main.cpp:5:16: error: cannot convert 'int*' to 'int (*)[5]' in initialization
    // баг компилятора. Как и в прошлый раз rvalue приводится к int*, но это не соответствует типу lvalue.
    // рапортуем в багзиллу, потому что мы-то точно знаем что здесь компилятор должен послушаться нас
    // а не умничать как voivoid и hoggy.
    int (*b)[5] = a;
    int d[5][5];
    // всё бенч, типы соответствуют.
    int (*c)[5] = &a;   // ok
    int (*f)[5] = d;   // ok
}
Т.е. b это указатель на массив int[5], а переменная а есть сам массив. Конечно получим ошибку.
А еще лучше сделать вот такую глупость:
C++
1
    c[2] = std::cout; //error: incompatible types in assignment of 'std::ostream {aka std::basic_ostream<char>}' to 'int [5]'|
Т.е. с есть указатель на int[5]. Следовательно здесь
C++
1
    int (*c)[5] = &a;   // ok
Для получения указателя на переменную вы берете ее адрес.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 11:30
Цитата Сообщение от Ilot Посмотреть сообщение
Т.е. b это указатель на массив int[5], а переменная а есть сам массив. Конечно получим ошибку
синтаксический сахар + pretty print как бы, читайте выше, всё уже сказано.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.03.2015, 11:36
Цитата Сообщение от castorsky Посмотреть сообщение
это разные объекты (в широком смысле)
Ты ведь хотел сказать типы?

Цитата Сообщение от castorsky Посмотреть сообщение
Первое - синтаксический сахар
Э-э-э, кхм. Кажется придется начать с фундаментальных вопросов.

1) Что такое тип? Углубляться в теорию типов не надо, копипастить стаю с вики тоже. Интересно твое понимание этого термина ( а то у меня есть подозрение, что именно в этом корень всех бед )
2) Здесь
C++
1
typedef int X[ 5 ];
X это тип? Если не тип, по почему возможно выражение
C++
1
X a;
. Ведь в плюсах у любой переменной должен быть тип. Если же это тип, то чем он отличается от
C++
1
typedef int( *Y )[ 5 ];
Да и отличается ли вообще?


3) Вспомним твой код ( я убрал лишнее там )
Цитата Сообщение от castorsky Посмотреть сообщение
int main()
{
* * // a имеет тип int(*)[5]
* * int a[5];
* * int (*c)[5] = &a; * // ok
}
у переменных a и c одинаковые типы? Если одинаковые, то почему происходят следующие ошибки:
C++
1
2
3
4
5
6
7
8
9
10
int main() {
  int a[5];
  int(*c)[5];
 
  a = a; // error
  c = c; // ok
 
  a = nullptr; // error incompatible types in assignment of ‘std::nullptr_t’ to ‘int [5]’
  c = nullptr; // ok
}
Ведь если у переменной одинаковые типы, то для них доступен одинаковый набор операций над ними.
А если они разные... кхм, как они могут быть разными, если у a, по твоим словам, тип int (*)[5] и у c, очевидно, тип int (*)[5]? Но если все таки они по-твоему разные, то какие у них типы?
1
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2222 / 1424 / 419
Регистрация: 16.05.2013
Сообщений: 3,639
Записей в блоге: 6
04.03.2015, 11:36
Цитата Сообщение от castorsky Посмотреть сообщение
читайте выше, всё уже сказано.
Выше я увидел только ваше сквернословие и не уважение к пользователям форума. А так же утверждения с которыми я не согласен. На которые я и обратил ваше внимание.
0
04.03.2015, 12:01
 Комментарий модератора 
Воспользуюсь своими привелегиями и объявляю, что разговор окончен. Пусть каждый остается при своем мнении.
Тема почищена.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
04.03.2015, 12:13
Цитата Сообщение от castorsky Посмотреть сообщение
это разные объекты, их просто нельзя сравнивать. Как нельзя сравнивать форму материи с дисперсией света.
Ага, лол разные сущности. Т.е. только один из них тип, а втрой не тип что-ли? Или оба не типа? Или оба типа?
Если написать следущий код:
C++
1
2
X a;
Y b;
То какие типы будут у переменных а и b? Ведь у них не может не быть типов. Или думаешь может?

Цитата Сообщение от castorsky Посмотреть сообщение
ничего что &c != &a? после c = a.
Что ты имеешь в виду, что их адреса в момент выполнения будут не равны? Или что типы &c и &a не равны?

Цитата Сообщение от castorsky Посмотреть сообщение
Мейби, только мне за это не платят
Ага, какая унылая отмазка. Ведь написать десяток другой строк кода так сложно ( особенно с учетом того, что ты в этом треде уже написал кучу текста бесплатно, лол )

Добавлено через 3 минуты
Цитата Сообщение от Ilot Посмотреть сообщение
объявляю, что разговор окончен
Думаю в конце можно привести цитату из стандарта ( 4.2, conv.array ):

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”

Прошу заметить, что не pointer to array of N T, а array of N T.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 12:45
мейби это расставит точки
C++
1
2
3
4
5
6
7
8
9
int main() {
    int a;              // int
    int * b = &a;       // int* = int*
    
    int aa[5];          // int(*)[5]
    int (*bb)[5] = &aa; // int(**)[5] = int(**)[5]
    
    return 0;
}
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
04.03.2015, 12:54
В 5-й и 6-й строках, в комменнтариях убери по одной первой звездочки.

Добавлено через 1 минуту
В 6-й строке даже две убери, по одной по обе стороны присваивания.

Добавлено через 4 минуты
Ты не верно интерпретируешь типы в языке С++. Это нормально для новичка. Всё приходит с опытом.
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2222 / 1424 / 419
Регистрация: 16.05.2013
Сообщений: 3,639
Записей в блоге: 6
04.03.2015, 13:08
Никто мой мод не видел? Непомню куда его поставил... вот беда с памятью-то...
castorsky,
castaway, прав
Цитата Сообщение от castaway Посмотреть сообщение
Ты не верно интерпретируешь типы в языке С++
Если типы int[] и int * это одно и то же тогда почему не компилируется код:
C++
1
2
3
4
5
6
7
8
void func(int(&a)[5]) {
}
int main() {
    int b[5];
    int * c = b;
    func(b);
    func(c);
}
Напомню. При передаче параметра по ссылке его тип не может быть изменен для стандартных типов.
int(*)[] это указатль на массив int[], но ни как не сам массив.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
04.03.2015, 13:11
Цитата Сообщение от Ilot Посмотреть сообщение
Если типы int[] и int * это одно и то же тогда почему не компилируется код
Это не одно и то же, типа int[] нет, это просто сахар, такой же сахар как и ссылки. Я уже устал это повторять. Я так же жду ссылку на стандарт где указано что тип T[N] есть.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.03.2015, 13:11
Помогаю со студенческими работами здесь

Как передать указатель на функцию через метод класса ?
typedef void (*FuncCallback)(float* flValue); Пробовал по всякому и ни как: Class.CallFunc // error C3867: CClass::CallFunc :...

Указатель на массив указателей на объекты, передать в метод объекта
Здравствуйте! Нужно решить задачу, есть такой класс. class MyClsDisk { public: void...

Как передать в метод класса Menu указатель на метод дочернего класса?
Как передать в метод базового класса указатель на метод дочернего: class Menu() { protected: setCallback(*********); //...

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

Передать в неуправляемую функцию указатель на указатель
Неуправляемая функция типа FUNC(int ** r); Делаю так fixed (int* ptr = arr) { FUNC((int **)ptr); ...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru