Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 26.08.2011, 12:52   #1
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
Злость специально для дениса

Для начала разбирёмся с указателями:
Указатель - это тип данных указывающий на на переменную, объект или функцию - в памяти. Он отвечает за адреса и доступ к значению по адресу.
Размер указателя составляет 4 байта. Указатель также поддерживает все арифметические операции(кроме умножения). Чтобы понять зачем нужны указатели, надо рассмотреть программку, реализующую подсчёт суммы элементов массива:
int sum(int* inLeft, int* inRight)
{
if(inLeft == inRight)
return *inLeft;
else
return *inRight + sum(inLeft, --inRight);
}

Для девятиэлементного массива mas вызов функции будет иметь такой вид:
int massum = sum(&mas[0], &mas[8]);
А теперь с конца: если у имеется некая переменная, получить её адрес можно применением к ней оператора взятия адреса &.
Именно результатом взятия адреса и может быть инициализирован указатель (инициализировать его значением переменной не получится, потому что это означало бы, что мы хотим получить доступ к произвольной области памяти, что есть unsafe. Формально компилятором это выражается в невозможности привести тип A к типу "указатель на А"). А дальше всё довольно прямолинейно: если есть желание работать с адресом, предоставляемым указателем, можно использовать его (указатель) безо всяких дополнительных символов (причём, разумеется, применение оператора взятия адреса к указателю будет расцениваться как адрес его самого и интерпретироваться компилятором как "указатель на указатель на А"); если же необходимо получить доступ к значению, на которое он всеми силами указывает, нужно применить оператор доступа по значению ("звёздочка"; если говорить правильно, разыменовывание). При этом к "звёздочке" можно применять арифметические операторы и совершать изменение значения самой переменной. Для оператора взятия адреса такой возможности нет. Сущность, которая подвергается взятию адреса, должна быть rvalue, то есть стоять справа от знака "равно" (такой способ, как
int** new_pointer = ++&old_pointer дело тоже не спасает).
Ну а теперь про ссылки:
Ссылка - тип данных которого не было в C, который те же функции, что и указатель, но в таком локальном контексте. Ссылка практически идентична указателю, она тоже занимает 4 байта, только функция разыменования выведена на первый план и взятие значения теперь осуществляется без дополнительных звёздочек и амперсандов, а адрес получается только соответствующим оператором &. Ещё одна особенность ссылки в том, что её нельзя не инициализировать. Если оставить в коде строку int* i; , то компилятор максимум, что из себя выжмет, так это предупреждение. Если же подобным образом поступить со ссылкой: int& i;, то тут у него появится шанс схватить программиста за рукав. Такая особенность языка C++: ссылки и соответствующие им переменные - это одно целое. И ещё она не поддерживает арифметические операции.
Теперь настала пора переписать уже набивший оскомину код вычисления суммы массива, только уже в более модном стиле, на ссылках:

int sum(int& inLeft, int& inRight)
{
if(&inLeft == &inRight)
return inLeft;
else
{
int* right_temp = &inRight;
right_temp--;
int& new_right = *right_temp;
return inRight + sum(inLeft, new_right);
}
}
Сразу стало заметно, насколько больше "мусора" в этой реализации. А всё потому, что ссылки не поддерживают арифметические операции. Ссылка прикрепляется к переменной "намертво", без возможности "перепрыгивания" на соседний или совсем отдалённый объект. И именно поэтому для процедуры обновления адресов пришлось прибегать к указателям.
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 26.08.2011, 12:52   #2
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

Однако, наверное, основное назначение ссылки - передача параметров в функцию. В C++ дело вот в чём: существует 2 типа передачи, по значению и по адресу. В передаче параметра по значению (выглядит примерно так: int func(int par)) сама функция получает не что иное, как копии передаваемых параметров. В большинстве случаев именно это и требуется, однако для объектов, хранящих своё состояние (тут прямо почувствовалось, как разговор перешёл в тему объектно-ориентированного программирования), типа матриц, копия должна быть обязательно сконструирована, а это бывает (абсолютно всегда) затруднительно. При передаче же по адресу (выглядит так: int func(int& par) либо так: int func(int* par)) передаётся не сама сущность, а её адрес. И ссылка, безусловно, облегчает работу с такими параметрами: в отличие от указателя, разыменовывается она автоматически.

Подводя итог, можно скопировать всё написанное в окошко редактирования ещё раз (ведь так он всегда подводится) и описать всё то, что очень сподручно знать про саму суть указателей и ссылкок:

указатель /* */ ссылка
Объявление
int* pointer /* */ int& ref
без инициализации /* */ только с инициализацией
Взятие адреса
pointer /* */ &ref

Разыменовывание
*pointer /* */ ref

Арифметические операции с адресом
(--pointer++) += 3; // сложение и вычитание /* */ не предусмотрено

Инициализация
pointer1 = pointer2; /* */ ref1 = ref2;
pointer = &ref; /* */ ref = *pointer;
pointer = &val;/* */ ref1 = val;

Вот вам ответ денис на то что в дословном переводе означает дебильный,заученный,нечего не умеющий объяснять малолетка.
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 26.08.2011, 12:53   #3
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

Можете меня забанить за переход на личности.
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 26.08.2011, 12:58   #4
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

А про крышечку:
знак^ - по моему в pascal это XOR
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 26.08.2011, 13:13   #5
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

И ещё что касается опыта преподавания. Это изъян всех работ - откуда ему взяться, если все требуют опыта.
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 26.08.2011, 13:38   #6
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от V@Programmer Посмотреть сообщение
int sum(int* inLeft, int* inRight)
{
if(inLeft == inRight)
return *inLeft;
else
return *inRight + sum(inLeft, --inRight);
}
Ужас какой-то... Рекурсия для каждого элемента...
Код:
int sum(int* inLeft, int* inRight)
{
    int s =0;
    while( inLeft != inRight)
       s += *inLeft++;
   return s + *inRight;
}
Так не проще ?

Последний раз редактировалось An1ka; 26.08.2011 в 13:44.
An1ka вне форума
Старый 26.08.2011, 14:20   #7
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

проще )))))))))))))
просто я старался с указателями в стиле C, а с ссылками в стиле C++.
Делаю бд, программы,
icq 640743615 дамы!

Последний раз редактировалось V@Programmer; 26.08.2011 в 15:04.
V@Programmer вне форума
Старый 26.08.2011, 16:30   #8
SnX
Форумчанин
 
Регистрация: 30.10.2009
Сообщений: 114
По умолчанию

Цитата:
Размер указателя составляет 4 байта.
Не везде.

Цитата:
А про крышечку:
знак^ - по моему в pascal это XOR
Это разыменование указателя, если стоит после переменной, и указатель, если перед ней.

А для чего эта тема?
SnX вне форума
Старый 26.08.2011, 18:30   #9
V@Programmer
На форуме меня нет
Пользователь
 
Аватар для V@Programmer
 
Регистрация: 03.08.2011
Сообщений: 56
По умолчанию

А для чего эта тема?
----------------------------------------
это ответ Sinedd'у за оскорбления
----------------------------------------

Вот вам ответ денис на то что в дословном переводе означает дебильный,заученный,нечего не умеющий объяснять малолетка.
Делаю бд, программы,
icq 640743615 дамы!
V@Programmer вне форума
Старый 27.08.2011, 13:01   #10
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

рекомендую отправить этот поток сознания в "Свободное общение"
f.hump вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Специально для тех кто любит резиновые дизайны megarazum HTML и CSS 5 13.02.2011 10:52
Прививки против гриппа делают специально - чтобы продавать противогриппные средства? Alar Свободное общение 27 13.01.2010 14:35
составить функцию для вычисления значения y=P(x) многочлена для заданного аргумента x KASPEER Помощь студентам 2 12.01.2010 15:03