1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11

Ссылки и указатели

01.03.2011, 12:10. Показов 18580. Ответов 54
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.
Возможно было. В чем существенная разница между передачей данных в функцию по ссылке или указателю. В каких случаях вы бы что рекоммендовали. Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.03.2011, 12:10
Ответы с готовыми решениями:

Указатели и Ссылки
извеняюсь,но никак не могу понять. int sum(int* inLeft, int* inRight) { if(inLeft == inRight) return *inLeft; ...

Ссылки и указатели
#include <iostream> using namespace std; int main() { int *n=new int{1,2}; cout<<&n<<' '<<&n<<' '<<&n<<endl; return...

Ссылки и указатели
Всем привет. Совсем запутался с ссылками и указателями. Помогите решать задачку: Функция принимает два аргумента, число с плавающей...

54
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
20.06.2011, 13:05
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от silentnuke Посмотреть сообщение
выведет
10
10
хотя смотрел по дебагу в памяти записано 100. Интересно особенности оптимизации mvs, или везде так, просто нет сейчас возможности проверить
Это оптимизация компилятора. Он верит модификатору const и во всех местах использования "p" в main заменяет её на 10. Т.е. в cout'ы отдаётся значение 10, хотя в функцию отдаётся указатель (ибо там уже ничего сделать нельзя) и по этому указателю успешно записывается 100
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 01:57
окей, в продолжение темы, ещё немного магии, взываем функцию которая имеет принимаемые параметры, без параметров)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
 
void f(int a, int b)
{
    cout<<a+b<<endl;
}
 
void main()
{
    void (*p)();
    p=(void(*)())&f;
    (*p)();
}

Но то были цветочки, пойдем дальше)
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
#include <iostream>
using namespace std;
 
class A
{
protected:
    int a;
public:
    A(){a=10;}
};
 
class B:public A
{
    char *str;
public:
    B(){cout<<"constr\n";}
    void myfunc2()
    {
        str=new char[20];
        strcpy(str,"Hello World\n");
        cout<<str;
    }
};
 
void main()
{
    A* t=new A;
    B* tc=(B*)&t;
    tc->myfunc2();
}
Создали указатель базового класса, выделили память.
Создали указатель производного класса, привели базовый класс к классу наследнику.
И что же мы видим? У нас есть методы класса наследника, только большой вопрос откуда? ведь конструктор то не отработал, и как бы по идеи методов не должно быть, а так у нас есть и методы и поля наследника. и можно с ними работать....
0
71 / 76 / 9
Регистрация: 30.06.2011
Сообщений: 176
15.07.2011, 05:25
Цитата Сообщение от silentnuke Посмотреть сообщение
Создали указатель базового класса, выделили память.
Создали указатель производного класса, привели базовый класс к классу наследнику.
И что же мы видим? У нас есть методы класса наследника, только большой вопрос откуда? ведь конструктор то не отработал, и как бы по идеи методов не должно быть, а так у нас есть и методы и поля наследника. и можно с ними работать....
Методы - это просто функции, они создаются всегда один раз ( исключение шаблонные, там для каждого типа своя функция создается), которые одним параметром принимают указатель на вызывающий объект ( this).
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 12:53
Цитата Сообщение от silentnuke Посмотреть сообщение
окей, в продолжение темы, ещё немного магии, взываем функцию которая имеет принимаемые параметры, без параметров)
Ну вызовется у тебя функция с неинициализированными параметрами. И чего?

Цитата Сообщение от silentnuke Посмотреть сообщение
У нас есть методы класса наследника, только большой вопрос откуда?
Что есть метод на пальцах пояснял тут: раз (пост 11) и два (пост 23)
Там пояснял с другого угла зрения, но в данном случае должно быть то же самое

Добавлено через 23 минуты
silentnuke, касаемо твоего первого примера. В языке Си поддерживается "старый" стиль описания процедур (так называемый, традиционный стиль Кернигана-Ритчи). И там такое безобразие можно делать без всяких преобразований над указателями

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
void
func (str, i1, i2)
  const char *str;
  int i1;
  int i2;
{
  printf ("%s: i1=%d, i2=%d\n", str, i1, i2);
}
 
int
main (void)
{
  func ("first");
  func ("second", 10, 20);
  return 0;
}
что выдаст на исполнении что-то типа:

C
1
2
first: i1=1073784948, i2=1073830340
second: i1=10, i2=20
Или можно вообще вот так написать:

C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int
main (void)
{
  printf ("%s: i1=%d, i2=%d\n", "first");
  printf ("%s: i1=%d, i2=%d\n", "second", 10, 20);
  return 0;
}
и получим точно такое же мусорное значение.

Все три примера (один твой и два моих) принципиально друг от друга ничем не отличаются. В них имеет место быть передача одного количества параметров, в то время как ожидалось другое количество. Правда в твоём случае дополнительно ожидался параметр-указатель другого типа (this)
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 15:23
Цитата Сообщение от silentnuke Посмотреть сообщение
окей, в продолжение темы, ещё немного магии, взываем функцию которая имеет принимаемые параметры, без параметров)
Я не силён в этом деле, но вообще вопрос конечно заслуживает удивления.
То, что компилится эта строчка- целиком пусть будет на совести авторов компилятора.
C++
1
        p=(void(*)())&f;
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 15:51
Цитата Сообщение от kravam Посмотреть сообщение
То, что компилится эта строчка- целиком пусть будет на совести авторов компилятора
А почему она должна не компилиться?
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 17:03
Потому, что p это void (*)();

а f имеет два аргумента
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 17:15
Цитата Сообщение от kravam Посмотреть сообщение
Потому, что p это void (*)();

а f имеет два аргумента
Программист явно поставил операцию преобразования над указателями. При любом явном преобразовании над указателями всегда считается, что программист "сам дурак" и компилятор снимает с себя всю ответственность за последствия. Никто же тебе не запрещает указатель на char приводить к указателю на int. А конструкция сия есть опасная, потому как, например, на машинах, где запрещены невыровненные обращения в память, работа с таким указателем может привести к слому программы. Если у тебя есть просто присваивание одного в другое, то компилятор ругнётся, а если явно вставлена операция преобразования типа - то компилятор молча это съест и переложит всю ответственность на программиста

Собственно, почему весь мир уже несколько десятков лет пытается создать защищённые системы программирования: потому что из-за бесконтрольной работы над указателями у людей постоянно возникают всякие скрытые проблемы и ошибки
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 17:21
Evg, с первым случаем то все понятно, привел для ознакомления.)
больше второй случай интересный. с функцией ну ещё допустим понятно, она я так думаю создается в памяти один раз, дальше уже кидается адрес, но черт возьми откуда то указатель появился, мы же не создавали объект дочернего класса.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 17:28
silentnuke, вся иерархия классов - оно точно так же опускается до уровня языка Си. В твоём случае мы имеем что-то типа:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct A
{
  int a;
};
 
struct B
{
  int a; /* это поле как бы пронаследовано из A */
  char *str;
};
 
...
struct A *a;
struct B *b;
 
a = malloc (sizeof (A));
b = (B*) &a;
...
Реально у тебя создался экземпляр класса A. Замет указатель на него трактуется как указатель на экземпляр B. При обращении к "b->str" номинально ты обращаешься в недопустимую память (поскольку память под это поле не выделялось в принципе). Но реально в конкретно данном случае у тебя код вряд ли где-то сломается. Причину этого объяснял здесь И снова malloc...
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 17:46
Evg, странно. Ты спрашиваешь что неверно с МОЕЙ Точки зрения. А опровергаешь её с точки зрения создателей компилятора.
...Так-то мне понятны причины, по которым это компилится. Понятны но неубедительны.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 17:48
Цитата Сообщение от kravam Посмотреть сообщение
Evg, странно. Ты спрашиваешь что неверно с МОЕЙ Точки зрения. А опровергаешь её с точки зрения создателей компилятора.
...Так-то мне понятны причины, по которым это компилится. Понятны но неубедительны.
Да я вроде бы ничего не спрашивал и ничего не опровергал... Во всяком случае, я так и не понял, о чём ты
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 17:54
Evg, ОК
Тогда я так спрошу: тебе непонятно недоумение человека, который считает, что не должно компилиться присваивание указателю на функцию, не принимающую аргументов, адреса функции, принимающей два аргумента?
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
15.07.2011, 18:00
Цитата Сообщение от kravam Посмотреть сообщение
тебе непонятно недоумение человека, который считает, что не должно компилиться присваивание указателю на функцию, не принимающую аргументов, адреса функции, принимающей два аргумента?
Мне непонятно. Ибо такое присваивание и не будет компилироваться. А вот присваивание с предварительным приведением будет. Потому что производители дрелей производят их для строительных работ и не несут ответа за какого-то чудака, который этой дрелью просверлит себе голову.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
15.07.2011, 18:02
Цитата Сообщение от silent_1991 Посмотреть сообщение
Ибо такое присваивание и не будет компилироваться.
компилится, шеф
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 18:03
Цитата Сообщение от kravam Посмотреть сообщение
Evg, ОК
Тогда я так спрошу: тебе непонятно недоумение человека, который считает, что не должно компилиться присваивание указателю на функцию, не принимающую аргументов, адреса функции, принимающей два аргумента?
Нет. Недоумения у меня не было. Ты сказал "но вообще вопрос конечно заслуживает удивления", а своим вопросом я попытался выяснить у тебя, почему это заслуживает удивления. Такой код заведомо корректный с точки зрения языка, т.е. компилятор должен его проглотить, не моргнув.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
15.07.2011, 18:04
kravam, мне компилятор в ответ на скармливание такого кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
void f(int a, int b)
{
        std::cout << a + b << std::endl;
}
 
int main()
{
    void (*p)();
 
    p = /*(void (*)())*/&f;
    
    (*p)();
 
    return 0;
}
говорит про невозможность преобразования void (*)(int, int) в void (*)(void).
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 18:08
Цитата Сообщение от kravam Посмотреть сообщение
компилится, шеф
В Си++ такое НЕ компилится

C++
1
2
3
4
5
6
7
8
extern void func (int, int);
 
int main (void)
{
  void (*p)(void);
  p = &func;
  return 0;
}
потому что справа и слева от присваивания стоят указатели несовместимых типов. Но если поставить операцию преобразования (т.е. 5-ю строку заменить на "p = (void (*)(void)) &func;"), то всё будет нормально
0
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 18:10
Evg, спасибо, со вторым случае стало хоть более менее понятно.)
я так понял то что я привел класс A к наследнику тут вообще не причем, у нас поля стали доступны уже при создании указателя класса наследника.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21282 / 8307 / 637
Регистрация: 30.03.2009
Сообщений: 22,668
Записей в блоге: 30
15.07.2011, 18:12
Цитата Сообщение от silentnuke Посмотреть сообщение
у нас поля стали доступны уже при создании указателя класса наследника
Они стали доступны с точки зрения языка. Но компилятор при этом не знает, выделена под них память, или нет. И это находится в твоей ответственности (потому как ты сделал преобразование типа над указателями)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.07.2011, 18:12

Указатели и ссылки?
Ниже приведёна программы которая вызывает функцию. В функции происходит следующее создаются 2 массива в которые записыватся чётные и...

Ссылки, указатели
Доброго времени. Как, используя ссылки, указатели и, возможно, другие приемы сделать что-то вроде этого?: int a = 1; int b = 2; ...

Указатели и ссылки
а если написать return this тогда что вернется? и как определить? П.5.18.Правил Запрещено размещать задания и решения в виде картинок...

Ссылки и указатели
Добрый день, не могу понять чем помогают при использовании указатели и ссылки? Есть код на c++ #progma once class well { ...

Указатели и ссылки
Собственно, не могу до конца осознать как это работает, вот пример из вики(комменты входят в пример) int n = 6; // Объявление...


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

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

Новые блоги и статьи
Кто сможет объяснить тихое удаление авторских алгоритмов с Хабра без замечаний и объяснений?
Hrethgir 05.08.2026
Администрация Хабра причин удаления не объясняет. Может это кто сделает другой? Алгоритм эффективен и рабочий, ошибка было только в пагинации сообщений, что является отдельным алгоритмом а не. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru