crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Использование ссылок или указателей или вообще без них, плюсы и минусы их использования
ViGOur
  опции профиля:
сообщение 27.2.2008, 21:35
Сообщение #1


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


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

1 вариант:
void function( const int &rn)
{
   ...
}

2 вариант:
void function( const int *pn)
{
   ...
}

3 вариант:
void function( const int n)
{
   ...
}


+ 1 и 2 вариант: экономия времени и памяти на копировании, в отличии от 3 варианта.
- 3 вариант значение копируется во временную переменную и занимает дополнительную память

p.s. затеял эту тему из-за интереса, сколько + и - наберем... :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 17)
Litkevich Yuriy
  опции профиля:
сообщение 27.2.2008, 21:45
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


да, интересно, учитывая что она const.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrew Selivanov
  опции профиля:
сообщение 28.2.2008, 10:41
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 249
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 3

Спасибо сказали: 15 раз(а)




Репутация:   6  


Цитата(ViGOur @ 27.2.2008, 21:35) *
Сколько кода пересмотрел, код от кода разумеется различается, но заметил закономерность, используются в основном или ссылки или указатели, использование того и другого встречается редко.

1 вариант:
void function( const int &rn)
{
   ...
}

2 вариант:
void function( const int *pn)
{
   ...
}

3 вариант:
void function( const int n)
{
   ...
}


+ 1 и 2 вариант: экономия времени и памяти на копировании, в отличии от 3 варианта.
- 3 вариант значение копируется во временную переменную и занимает дополнительную память

p.s. затеял эту тему из-за интереса, сколько + и - наберем... :)


С точки зрения оптимизации в компиляторе (например -O2) для конкретного случая int-a и на разных компиляторах результаты будут разными. Я делаю как удобнее в конкретном случае. Можно ради интереса собрать эти три функции для MSVC 7,8 и GCC 3.x, 4.x (x386) и посмотреть, какой код сгенерится.

А вообще оптимизация в ее глобальном понимании - зло :) IMHO оптимизировать надо в первую очередь не код, а алгоритм, это даст наибольший выигрыш.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrew Selivanov
  опции профиля:
сообщение 28.2.2008, 11:22
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 249
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 3

Спасибо сказали: 15 раз(а)




Репутация:   6  


Яркий пример работы оптимизатора GCC 3.4.5 (-O2):
#include <cstdio>

int function1( const int &rn)
{
    int temp = rn + 2;
    return temp;
}

int function2( const int *pn)
{
    int temp = (*pn) + 3;        
    return temp;
}

int function3( const int n)
{
    int temp = n + 4;
    return temp;
}

int main()
{
    int a = 4;
    int f1 = function1(a);
    int f2 = function2(&a);
    int f3 = function3(a);
    
    printf("%d", f1);
    printf("%d", f2);
    printf("%d", f3);    
    
    return 0;
}


И вот во что это в конечном счете соптимизировалось :)
mov     [esp+8+var_8], offset unk_403000
mov     ecx, 6
mov     [esp+8+var_4], ecx
call    printf
mov     [esp+8+var_8], offset unk_403000
mov     edx, 7
mov     [esp+8+var_4], edx
call    printf
mov     [esp+8+var_8], offset unk_403000
mov     eax, 8
mov     [esp+8+var_4], eax
call    printf
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 28.2.2008, 11:26
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


- 1 и 2 варианты, в Qt, если невнимательно использовать сигналы и слоты, то при создании обьекта получателя сигнала в другом потоке, и при передаче в слот локальной переменной будут проблемы, в 3 варианте это не будет наблюдаться...
Пример:
void XClass::otherFunc()
{
   int n = 0;
   emit signalFunction( n); // для function( const int &rn)
   // или
   emit signalFunction( &n); // для function( const int *pn)
}


Сообщение отредактировал ViGOur - 28.2.2008, 11:28
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
rich
  опции профиля:
сообщение 15.3.2008, 18:45
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 123
Регистрация: 1.3.2008
Пользователь №: 109

Спасибо сказали: 6 раз(а)




Репутация:   0  


Цитата(Andrew Selivanov @ 28.2.2008, 10:41) *
С точки зрения оптимизации в компиляторе

внутренне(в компиляторе) ссылки могут реализовать при помащи указателей
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
0xF
  опции профиля:
сообщение 17.3.2008, 20:58
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 71
Регистрация: 12.11.2007
Пользователь №: 20

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата
внутренне(в компиляторе) ссылки могут реализовать при помащи указателей

А ссылка и указатель это одно и тоже по сути, просто синтаксис разный
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
0xF
  опции профиля:
сообщение 17.3.2008, 21:06
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 71
Регистрация: 12.11.2007
Пользователь №: 20

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата
void function( const int &rn)
void function( const int *pn)

ИМХО, так имеет смысл передавать только составные типы(если const), чтоб не копировать объект, а лишь перекинуть 4 байта адреса в ф-цию...

Правка:
Цитата
void function( const int *pn)

Это ещё для массивов может понадобиться :)

Сообщение отредактировал 0xF - 17.3.2008, 21:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.3.2008, 21:12
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


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

вроде так

Сообщение отредактировал Litkevich Yuriy - 17.3.2008, 21:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Admin
  опции профиля:
сообщение 17.3.2008, 22:03
Сообщение #10


Администратор
****

Группа: Администратор
Сообщений: 646
Регистрация: 9.10.2007
Из: crossplatform.ru
Пользователь №: 1

Спасибо сказали: 17 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 17.3.2008, 21:12) *
ссылка - псевдоним конкретной переменной, неможет указыват в никуда, т.е. всегда инициализируется конкретным значением;
Да ладно, а как тебе такой код:
int n = 1;
int &rn = n;
if( true)
{
   int x = 100;
   rn=x;
}
// Чему равна rn?
:)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.3.2008, 22:11
Сообщение #11


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


как я понимаю x'у
я имел ввиду следующий код:
int n = 1;
int &rn;

неинициализированная ссылка
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Admin
  опции профиля:
сообщение 17.3.2008, 22:13
Сообщение #12


Администратор
****

Группа: Администратор
Сообщений: 646
Регистрация: 9.10.2007
Из: crossplatform.ru
Пользователь №: 1

Спасибо сказали: 17 раз(а)




Репутация:   2  


Так не может быть, а так как я показал может быть, но вроде как инициализированная, а вроде как нет. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.3.2008, 22:28
Сообщение #13


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


в твоем примере она всегда инициализирована, нет момента когда она показывает в никуда
мало того n тоже равна 100, а точнее именно n, а не rn, это лишь псевдоним n
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
0xF
  опции профиля:
сообщение 17.3.2008, 23:28
Сообщение #14


Студент
*

Группа: Участник
Сообщений: 71
Регистрация: 12.11.2007
Пользователь №: 20

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy)
если я правильнопонимаю Си, то ссылка и указатель разные вещи:
указатель - переменная содержащая адрес, может указыват в никуда;
ссылка - псевдоним конкретной переменной, неможет указыват в никуда, т.е. всегда инициализируется конкретным значением;

Во-первых, в С нету ссылок, они появились только в С++
Во-вторых, как это "псевдоним"? Внутри это такой же адрес... Выходит, что ссылка - такой же указатель, который не может указывать в никуда, а только на нужную область памяти(там где переменная хранится) + немного другой синтаксис(не надо разыменовывать, чтоб сделать выборку значения, как при работе с указателями)

Ну и плюс ко всему, ссылка обязательно должна быть инициализирована, так что твой код(int n = 1; int &rn;) даже не соберется :)

Цитата(Admin)
int n = 1;
int &rn = n;
if( true)
{
int x = 100;
rn=x;
}
// Чему равна rn?

rn по-прежнему ссылается на n, а n тепер равна 100 :)

Сообщение отредактировал 0xF - 17.3.2008, 23:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.3.2008, 23:33
Сообщение #15


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата
даже не соберется

я его для того и привел, что ее инициализировать ее обязательно, а ссылка, может по праву считатся псевдонимом, если говорить я зыком литературным
т.к. в указаном примере n будет равна 100, а rn ее псевдоним
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 17.3.2008, 23:40
Сообщение #16


Активный участник
***

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

Спасибо сказали: 28 раз(а)




Репутация:   6  


Имхо, может по сути ссылки и указатели близки. Но вещи всеже разные, главное отличие в предназначении. Ссылки, как было сказано выше - псевдонимы переменных. Указатели же используются несколько шире, чем просто псевдонимы.
Не возьмусь судить о реализации в компиляторах, но вещи эти именно семантически, с точки зрения языка различны.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 18.3.2008, 8:45
Сообщение #17


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(0xF @ 18.3.2008, 2:28) *
Во-вторых, как это "псевдоним"? Внутри это такой же адрес... Выходит, что ссылка - такой же указатель, который не может указывать в никуда, а только на нужную область памяти(там где переменная хранится) + немного другой синтаксис(не надо разыменовывать, чтоб сделать выборку значения, как при работе с указателями)

Ссылка может быть, а может и не быть странслирована в указатель.
Например, если ссылка находится в локальной зоне видимости, нормальный компилятор просто не будет заводить для неё отдельную ячейку памяти (см. например, приведённый тобой код). :rolleyes:
То же самое с подставляемыми (inline) функциями.
Для временных объектов ссылка может вполне не быть указателем, а именно обозначать сам объект:
struct base_t {};
struct derived_t : base_t {};

int main() {
  const base_t& obj = derived_t();
}

В этом случае, obj может трактоваться компилятором так же, как если бы было объявлено const derived_t obj.
Смысла нет заводить здесь ещё и указатель. :rolleyes:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 18.3.2008, 8:49
Сообщение #18


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Собственно, кардинальное различие в том, что указатель всегда имеет "свою" память и язык позволяет получить на неё указатель.
А ссылка не обязана иметь свою память, и средствами языка ты не можешь узнать имеет или нет. :)

Какие-то манипуляции со ссылкой в языке всегда эквивалентны операциям над объектом которым она инициализирована.
И в языке нет прямого способа манипулировать чем-то, что-бы было ссылкой. :)

Сообщение отредактировал Tonal - 18.3.2008, 8:54
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 23.6.2025, 0:43