Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Указатели

10K
12 июня 2007 года
АлРАД
58 / / 30.08.2006
что такое указатель найти и прочитать не сложно, но интересно другое...

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

Заранее спасибо!
4.0K
12 июня 2007 года
ApokALEXIS
112 / / 23.08.2006
Допустим есть набор обьектов. дакн критерий, скоторый определяет, над которым из них проводятся операции

тогда можно
 
Код:
Switch (i)
{
1: ptr = &Obj1; break;
2: ptr = &Obj2; break;
3: ptr = &Obj3; break;
...
n: ptr = &Objn; break;
}

//и теперь можно делати тот самый блок операций используя *ptr вместо имени обьекта.

Это намного проще, чем
 
Код:
1: /*блок операций используя Obj1*/; break;


Всё же удобнее использовать функции, но ведь они тоже используют адреса и указатели:)
24K
12 июня 2007 года
>DiN<
38 / / 08.06.2007
Указатели удобно применять для динамических структур, таких как: очереди, стеки, связные списки, деревья и т.д.
4.3K
12 июня 2007 года
flat
142 / / 27.12.2005
Цитата:

хотелось бы знать в чем преимущество работы указателями над простой работой с объектами по ссылке, ну или просто с переменными?


Главное преимущество работы с указателями - скорость. Например, надо передать в функцию какой-нибудь параметр, если передавать саму переменную, то на самом деле передастся копия этой переменной и все действия, производящиеся в функции, будут манипулировать именно копией, а не самой переменной. Это во-первых. А во-вторых, представь, что функцию надо передать объект очень большого размера, будет тратиться время на создание копии, а если это функция вызывается в цикле - заметное снижение производительности. Если же передается указатель - копия не создается, работа идет непосредственно с переменной. Быстро и классно :)
Правда существует опасность непреднамеренно изменить данные, но эту проблему можно решить с помощью квалификатора const.

Теперь, что касается ссылок. Язык C, как известно, является подмножеством C++. Понятие ссылки было введено в С++, в С были только указатели. По сути, ссылки и указатели это почти одно и то же. Передавая ссылку в функцию, передается именно ссылка, а не копия данных. Отличие только в синтаксисе. С ссылкой нужно работать точно так же, как непосредственно с переменной, для удобства программиста.

4.0K
12 июня 2007 года
ApokALEXIS
112 / / 23.08.2006
[QUOTE=>DiN<;197262]Указатели удобно применять для динамических структур, таких как: очереди, стеки, связные списки, деревья и т.д.[/QUOTE]

Не удобно - необходимо =)
350
12 июня 2007 года
cheburator
589 / / 01.06.2006
Принципиальное отличие ссылки от указателя: ссылка - по сути псевдоним для некоторого объекта. Т. е.
1) Мы обязаны задать объект, на который ссылается ссылка, при инициализации ссылки (при объявлении переменной-ссылки или в конструкторе объекта, если переменная является членом класса).
2) "Перевести" ссылку на другой объект (сделать так, чтобы она ссылалась на другой объект) физически невозможно. Конструкция типа
 
Код:
int a;
int b;
int &int_ref = a;
.....
int_ref = b;

Будет работать не так, как ожидают некоторые - она не сделает так, что int_ref будет ссылаться на b, вместо этого она присвоит значение b переменной, на которую она ссылается, т. е. переменной a.
Посему, ссылки по своей сути всегда константны.
А вот указатель может быть как константным, так и модифицируемым, причем независимо от объекта, на который он указывает.
Т. е. для указателя возможны 4 варианта:
 
Код:
int *int_ptr;  // Модифицируемый указатель на модифицируемый объект
const int *int_ptr;  // Модифицируемый указатель на константный объект
int * const int_ptr;  // Константный указатель на модифицируемый объект
const int * const int_ptr;  // Константный указатель на константный объект

А вот для ссылки возможны только 2 варианта:
 
Код:
int &int_ref;  // Ссылка на модифицируемый объект
const int &int_ref;  // Ссылка на константный объект

Запись типа
 
Код:
int & const int_ref;

Не имеет смысла по вышеуказанным причинам. Такой код либо не компилируется (выдается ошибка), либо, как минимум, warning.
Из-за того, что мы обязаны инициализировать ссылку при ее объявлении, мы не всегда можем использовать ссылки. Например, если ссылку нужно проинициализировать разными значениями в зависимости от условия, код
 
Код:
int a;
int b;
...
int &int_ref;  // Ошибка: мы обязаны инициализировать ссылку
if (условие)
  int_ref = a;
else
  int_ref = b;

Не будет работать по двум причинам - переменная-ссылка не инициализирована при объявлении (выдается сообщение об ошибке) и запись int_ref = a будет выполнять присваивание вместо "перевода" ссылки. В таком случае без указателей не обойтись.
Преимущество указателей перед передачей параметра по значению такое же, как преимущество ссылки перед передачей по значению.
Код:
class A
{
// Содержимое класса
};

void SomeFunction(A a);

void SomeFunc2()
{
  A a;
  SomeFunction(a);
}

1. При таком вызове производится создание копии объекта, что может быть времяемким, а то и вовсе невозможным (некоторые объекты бывают принципиально некопируемыми по своей логике; другие объекты могут выполнять нетривиальное копирование, в результате чего копия может не совпадать с оригиналом - все зависит от копи-конструктора).
2. В функцию передается именно копия объекта, а не исходный объект. Тем самым, функция может менять содержимое, но менять она будет копию, а не исходный объект.
А вот если функцию объявить подобным образом:
 
Код:
void SomeFunction(A &a)
или
void SomeFunction(A *a)

1. Не тратится время на создание копии объекта.
2. Передаваться будет ссылка (указатель) на исходный объект, в результате чего вызываемая функция может модифицировать его.
Для запрета модификации можно, к примеру, объявить параметр как ссылку на константный объект (A const &a) или указатель на константный объект (A const *a).
370
13 июня 2007 года
koval
443 / / 29.08.2005
Есть штучка разработанная компанией мелкософт - называется молель СОМ, здесь все и построено на указателях. Програмирование графики - прямая работа с памятью и без указателей никуда.
З.Ы. Когда начинал учить СИ еще в прошлом веке тоже не понимал нах.. эти указатели нужны, но когда доехал понял что это просто крутая штука и без нее никуда!
10K
13 июня 2007 года
АлРАД
58 / / 30.08.2006
Спасибо всем!

Особенно cheburator и flat

кажется понял.
Теперь я понял, почему в VB так мало работают с указателями. Там объекты в функции можно передавать только по ссылке и ссылки причем не требуют сразу же экземпляр класса, как тут... - там немного упрощено для написания

еще раз спасибо!
294
24 июня 2007 года
Plisteron
982 / / 29.08.2003
Добавлю: К указателям применимы операции ++ и --, а также индексирования []. При этом первые две изменяют значение указателя не на 1, а на sizeof(тип_данных_указателя), т.е., например, для int указатель будет изменяться на 4 (в 32-разрядных системах). Оператор [] с указателем работает как с массивом, т.е. в C/C++, имя пременной-массива без квадратных скобок будет означать указатель на первый элемент. Иными словами
 
Код:
int x[100];
int *px1 = x;
int *px2 = &x[0]; // px2 == px1
int t1 = px2[2];
int t2 = *(px1 + 2); // t1 == t1
8.9K
25 июня 2007 года
Kulti
77 / / 29.07.2006
Цитата: cheburator

Из-за того, что мы обязаны инициализировать ссылку при ее объявлении, мы не всегда можем использовать ссылки. Например, если ссылку нужно проинициализировать разными значениями в зависимости от условия, код
 
Код:
int a;
int b;
...
int &int_ref;  // Ошибка: мы обязаны инициализировать ссылку
if (условие)
  int_ref = a;
else
  int_ref = b;

Не будет работать по двум причинам - переменная-ссылка не инициализирована при объявлении (выдается сообщение об ошибке) и запись int_ref = a будет выполнять присваивание вместо "перевода" ссылки. В таком случае без указателей не обойтись.


А разве нельзя было использовать тринарный оператор?

 
Код:
int &int_ref = (условие) ? a : b;
309
26 июня 2007 года
el scorpio
1.1K / / 19.09.2006
Kulti
Так тоже делается и очень хорошо работает. Но называется "условное присваивание"
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог