Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.52/75: Рейтинг темы: голосов - 75, средняя оценка - 4.52
xKirillx
1 / 1 / 0
Регистрация: 01.03.2011
Сообщений: 11
1

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

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

Добрый день.
Возможно было. В чем существенная разница между передачей данных в функцию по ссылке или указателю. В каких случаях вы бы что рекоммендовали. Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.03.2011, 12:10
Ответы с готовыми решениями:

Ссылки и указатели
Добрый день, не могу понять чем помогают при использовании указатели и ссылки?...

Указатели и ссылки c++
Здравствуйте! Не могли бы вы объяснить как можно использовать ссылки и...

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

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

Указатели и ссылки
Используя вместо самой переменной указатель на нее написать программу в...

54
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:21 41
Цитата Сообщение от kravam Посмотреть сообщение
компилится, шеф
Не должно! Какой компилятор? Выкиньте его на свалку, он нарушает стандарт.
С преобразованием типа - будет компилиться, без преобразования - не должно.
0
Evg
Эксперт CАвтор FAQ
19289 / 7148 / 528
Регистрация: 30.03.2009
Сообщений: 20,000
Записей в блоге: 30
15.07.2011, 18:36 42
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Не должно! Какой компилятор? Выкиньте его на свалку, он нарушает стандарт
gcc в режиме Си вроде бы как сожрёт это дело
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:41 43
Насколько помню, в Си не было ссылок...
0
kravam
быдлокодер
1709 / 896 / 105
Регистрация: 04.06.2008
Сообщений: 5,531
15.07.2011, 18:44 44
ДРузья, я был неправ. Но это бросает тень на меня и только.

Итак, мне нравится когда всё о чём я говорил компилится с преобразованием типов
C++
1
        p=(void(*)())&f;
Это плохо.
0
Evg
Эксперт CАвтор FAQ
19289 / 7148 / 528
Регистрация: 30.03.2009
Сообщений: 20,000
Записей в блоге: 30
15.07.2011, 18:46 45
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Насколько помню, в Си не было ссылок...
А при чём тут ссылки? Речь идёт о преобразовании типа над указателями на функцию (первый пример из поста #22). Далее в посте #38 я нарисовал пример, отрезавшись от Си++ (чтобы его можно было компилять и на Си, и на Си++). В режиме Си на, к примеру, борландовском компиляторе он не пройдёт компиляцию, а на gcc - пройдёт. Ибо gcc по умолчанию работает в некотором своём расширении, который допускает больше безобразия, нежели стандартный Си
1
grizlik78
15.07.2011, 18:47
  #46

Не по теме:

— Доктор, когда я делаю вот так, мне больно!
— А вы не делайте "вот так"!

2
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 18:48 47
Цитата Сообщение от kravam Посмотреть сообщение
ДРузья, я был неправ. Но это бросает тень на меня и только.

Итак, мне нравится когда всё о чём я говорил компилится с преобразованием типов
C++
1
        p=(void(*)())&f;
Это плохо.
Не... Просто аккуратно надо.
Я когда-то исследовал функции с переменным числом параметров и тоже вовсю использовал преобразование указателей. Было интересно передать в функцию с переменным числом параметров указатели на функции с разным числом параметров и там все их вызвать...
0
Evg
Эксперт CАвтор FAQ
19289 / 7148 / 528
Регистрация: 30.03.2009
Сообщений: 20,000
Записей в блоге: 30
15.07.2011, 19:14 48
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Я когда-то исследовал функции с переменным числом параметров и тоже вовсю использовал преобразование указателей. Было интересно передать в функцию с переменным числом параметров указатели на функции с разным числом параметров и там все их вызвать...
С точки зрения языка сие допустимо, но по сути дела это UB, потому как в точке вызова и в точке самой функции должны быть одинаковые прототипы. Возьмём пример из двух файлов:

C
1
2
3
4
5
6
7
8
extern void func (float f1, float f2);
 
int
main (void)
{
  func (1.25, 2.75);
  return 0;
}
C
1
2
3
4
5
6
7
#include <stdio.h>
 
void
func (int f1, int f2)
{
  printf ("f1=%x, f2=%x\n", f1, f2);
}
Мы видим, что в точке вызова прототип описан как с двумя float'ами, а в точке реализации - с двумя int'ами. Два файла компилируются раздельно, а потому для компилятора они оба корректные. Линкер работает только с именами: он видит, что в одном модуле есть определение символа "func", а в другом - использование символа с таким же именем, а потому он свяжет эти две точки и всё. Такой код будет работать. При исполнении он выдаст:

Код
f1=3fa00000, f2=40300000
В точке вызова компилятор передаст параметры, которые есть наборы битов для представления констант 1.25 и 2.75 как float. А а в самой функции из этого же места прочтутся эти же самые наборы битов, но будут трактоваться как int'ы (от чего и напечатаны такие значения). Казалось бы, что поведение программы всё равно оказывается детерминированным. А на самом деле это не так. В случае i386 при передаче целых и плавающих значений используются одни и те же программные соглашения. В нашем случае размер int'а совпадает с размером float'а, а потому место, через которое передаются параметры (видимо это стек) совпадёт с местом, откуда они читаются. На архитектуре sparc v9 программные соглашения устроены таким образом, что для целых и плавающих значений используются разные правила передачи параметров. В этом случае параметры типа float передадутся на плавающих регистрах, а параметры типа int будут прочитаны с целочисленных регистров (и окажутся неинициализированными).

Ровно такая же бодяга происходит и при преобразовании типов над указателями на функции. Т.е. компилятор такую операцию разрешает, но всю ответственность перекладывает на программиста. Если программист даёт себе отчёт в том, что данная программа предназначена для конкретных программных соглашений по передаче параметров, то у него всё будет работать. Если программист считает, что если на одной архитектуре у него отработало, а значит будет работать везде - то сам дурак

Ну и такие же риски имеются, если с var_arg'ами работать так, как в начальных примерах твоей статьи - непосредственно через указатели

Добавлено через 1 минуту
Да, забыл сказать. Это пример работает только в Си, потому как с точки зрения Си++ функции с одним именем, но разными типами параметров - это разные функции
8
silentnuke
Android Programmer
139 / 140 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 23:13 49
такс всеравно не до конца пока улавливаю суть.
с указателем то ещё ладно, но для статической переменной откуда память то берется?
Закинул все это дело в вечный цикл, подождал минут в 20 в надежде что оно вылетит, но нет..
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
#include <iostream>
using namespace std;
 
class B
{
public:
    int* a;
    int b;
    void func2()
    {
        a=new int;
        *a=10;
        b=250;
        cout<<*a<<" "<<b<<endl;
    }
};
 
int main ()
{
    while(1)
    {
        B *p;
        p->func2();
        *p->a=2222;
        p->b=20;
        cout<<*p->a<<" "<<p->b<<endl;
    }
    return 0;
}
0
OstapBender
584 / 523 / 75
Регистрация: 22.03.2011
Сообщений: 1,585
15.07.2011, 23:37 50
Цитата Сообщение от silentnuke Посмотреть сообщение
B *p; p->func2(); *p->a=2222;
так ваще делать нельзя.

по идее должно вылететь.

побольше выделять попробуй:
C++
1
2
3
4
5
    int counter=0;
    while (1) {
        int* p = new int[40000];
        std::cout << "ok: " << ++counter << '\n';
    }
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
15.07.2011, 23:40 51
Цитата Сообщение от silentnuke Посмотреть сообщение
такс всеравно не до конца пока улавливаю суть.
с указателем то ещё ладно, но для статической переменной откуда память то берется?
Закинул все это дело в вечный цикл, подождал минут в 20 в надежде что оно вылетит, но нет..
Все переменные С++ распределяются на три вида по виду памяти:
static storage (глобальные и статические переменные), automatic storage (локальные перменные) и dynamic storage (динамические переменные). Для статических-глобальных объектов память рампределяет компилятор при трансляции. Они "живут" все время, пока работает программа. Локальные объекты "рождаются" в стеке, там же и "помирают" во время работы программы. А динамические объекты создаются явно во время работы программы в куче. И их надо явно "убивать".
Поскольку куча - 2 гига (виртуальная память), то выделяя по одному int, вы нескоро ее исчерпаете.
0
silentnuke
Android Programmer
139 / 140 / 10
Регистрация: 08.12.2010
Сообщений: 421
15.07.2011, 23:54 52
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Все переменные С++ распределяются на три вида по виду памяти:
static storage (глобальные и статические переменные), automatic storage (локальные перменные) и dynamic storage (динамические переменные). Для статических-глобальных объектов память рампределяет компилятор при трансляции. Они "живут" все время, пока работает программа. Локальные объекты "рождаются" в стеке, там же и "помирают" во время работы программы. А динамические объекты создаются явно во время работы программы в куче. И их надо явно "убивать".
Поскольку куча - 2 гига (виртуальная память), то выделяя по одному int, вы нескоро ее исчерпаете.
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
0
ValeryLaptev
Эксперт С++
1050 / 829 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
16.07.2011, 00:01 53
Цитата Сообщение от silentnuke Посмотреть сообщение
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
VS 2008 в отладочном режиме тут же выдала
Run-Time Check Failure #3 - The variable 'p' is being used without being initialized.
То есть, у тебя указатель не инициализирован, а ты пытаешься вызвать метод через него.
0
schdub
Эксперт С++
3038 / 1380 / 421
Регистрация: 19.01.2009
Сообщений: 3,685
Завершенные тесты: 1
16.07.2011, 00:02 54
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
динамические объекты создаются явно во время работы программы в куче
Если имеются ввиду операторы new/delete, то у Herb Sutter применяется термин "Free Store", а не "Heap".

Exceptional C++ - Memory Management - Part I
0
Evg
Эксперт CАвтор FAQ
19289 / 7148 / 528
Регистрация: 30.03.2009
Сообщений: 20,000
Записей в блоге: 30
16.07.2011, 00:08 55
Цитата Сообщение от silentnuke Посмотреть сообщение
я ж говорю я пока не понимаю откуда память для переменной b берется, ведь как я понимаю, она должна выделяться при создании объекта, а объект то не создается, или я что-то не так понимаю?
Указатель p не инициализировался, а потому там мусорное значение. Звёзды встали так, что этот мусор оказался валидным адресом. И по этому адресу обращение не сломалось, при этом ты записывал в поле a, а потому просто гадил в чью-то память. Опять-таки звёзды встали так, что это оказалось нефатальным.

То, что у тебя цикл бесконечный - по сути ничего не означает. Каждый раз переменная p у тебя лежала в одном и том же месте стека, а потому каждый раз в ней был записан один и тот же мусор. А следовательно ты каждый раз гадил в одну и ту же память. Т.е. что цикл из одной итерации, что из бесконечного количества - в данном случае роли не играет

Добавлено через 2 минуты
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
То есть, у тебя указатель не инициализирован, а ты пытаешься вызвать метод через него
Конкретное значение указателя роли не играет, ибо на вызове метода это никак не отражается (см. по ссылкам из поста #24). Реальная засада могла быть только при записи в поля a и b. Но, как уже писал выше, звёзды встали так, что мусорное значение оказалось валидным адресом, нагадив по которому ничего страшного не произошло
0
16.07.2011, 00:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.07.2011, 00:08

Указатели и ссылки
Экспериментируя с указателями пришел к вот таким выводам: int a;...

Ссылки, указатели
Доброго времени. Как, используя ссылки, указатели и, возможно, другие приемы...

Указатели и ссылки [С++]
Всем привет. я тут программу делаю. Цель: определить,принадлежит ли точка...


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

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

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