Доброе время суток, Иван! Ссылки объявляются следующим образом: bool flag=true; bool &b=flag; Указатели могут так: bool flag=true; bool *p; p=&flag; cout<<*p; Ссылки должны инициализироваться сразу при объявлении, иначе компилятор укажет на ошибку! Ссылки не могут указывать на тип данных, то есть вот так нельзя: bool &f=bool; Ссылки не могут указывать на значение NULL: char &f=NULL; //ошибка, однако! И, наконец, ссылки не могут изменяться! Удовлетворен ответом? Ответ отправлен: 24.05.2004, 13:17 Отправитель: Sedric Отвечает CrackLab
Здравствуйте, Иван! Ссылка родственна указателю. Ссылку можно использовать тремя способами. 1) Ссылку можно передать в функцию 2) Ссылку можно возвратить из функции 3) Можно создать независимую ссылку. На практике в основном используется первый вариант. Разницу между ссылкой и указателем лучше всего показать на примере двух программок: 1) Передача параметра-указателя void myfunc(int *x) { *x = 10; } int main() { int a = 0; myfunc(&a); // Теперь а = 10 !!! return 0; } Думаю смысл и синтаксис должен быть вам понятен. 2) Передача параметра-ссылки: void myfunc(int &x) { x = 10; } int main() { int a = 0; myfunc(a); // Теперь а = 10 !!! return 0; } Для объявления параметра ссылки перед именем переменной в списке параметров функции ставится знак амперсанда. Теперь внутри
функции уже нет необходимости обращаться к значению передаваемого параметра с помощью оператора * (*x = 10;). Нужно просто писать x = 10; Также когда из функции main вызываем функцию myfunc уже не надо получать адрес переменной с помощью оператора &. Компилятор сам все сделает за вас и автоматически передаст адрес переменной в функцию myfunc. И повторюсь, что теперь внутри функции myfunc компилятор автоматически использует переменную на которую указывает параметр ссылка, для доступа к переменной уже не надо писать оператор *. Получается что ссылка является скрытым указателем. При передаче параметра-ссылки как и в случае указателя передается адрес переменной, но программист работает со ссылкой как с обычной переменной, а не как с указателем. Можно сказать что ссылка сделана для упрощения работы с указателями. При передаче параметра-ссылки копия объекта как и в случае передачи указателя
не создается. Короче если одним словом ссылки призваны заменить указатели и упростить работу с указателями на переменные, а с точки зрения внутренней работы программы - ссылка это тот же указатель. Просто программисту меньше нужно думать и писать =) Хотя кому как... Я предпочитаю все-таки указатели... Привык я к ним...
Ответ отправлен: 24.05.2004, 15:31 Отправитель: CrackLab Отвечает vitya
Добрый день, Иван! Ссылка всегда привязана к конкретному объекту. Ответ отправлен: 24.05.2004, 10:04 Отправитель: vitya Отвечает bocha
Приветствую Вас, Иван! Над ссылкой нельзя производить никаких действий кроме инициализации, т.к. последующие действия с ней будут производиться над объектом, на который эта ссылка указывает. С указателем, в отличие от ссылки, кроме инициализации можно производить следующие действия: присваивание, сложение/вычитание целого числа, вычитание указателя. Данные действия не приведут к изменению объекта, на который ссылается указатель, чтобы изменить объект необходимо произвести разыменование, а затем определенное над объектом действие. Ссылки чаще всего используют для перегрузки операторов, в остальных случаях в основном используют указатели. Кроме того, указатель сам может быть объектом, например итераторы в STL, сами, не будучи указателями, используются как указатели. Ссылка же так и остается ссылкой, псевдонимом, альтернативным именем уже созданного объекта. Указатель
может указывать в пустоту, быть равным нулю, ссылка - нет. С точки зрения машинного представления ссылка и простой указатель - это адрес некоей области памяти в выполняемой программе. Ссылку можно рассматривать как постоянно разыменованный константный указатель (не путать с указателем на константу).
#include using namespace std; class A{ static int nref; int a; public: A(){nref++; a = nref;} void fn1(){cout << a << " ";} }; int A::nref = 0; void gfn(A *a){ cout << "g "; a->fn1(); } void main(){ A* a = new A[5]; // указатель A& ar //ссылка = *a; //необходимо инициализировать // A& ar2; //так нельзя a->fn1(); ar.fn1();//тоже, что и a->fn() gfn(a); gfn(&ar);//тоже, что и gfn(a) (a+4)->fn1(); (*(a+4)).fn1(); (&ar+4)->fn1(); a[4].fn1(); //последние четыре
строки эквивалентны delete[] a; a = new A;//осторожно - утечка газа ar = *a; //попытка зажечь спичку, ar ссылается на освобожденную область памяти ar.fn1();//еще одна попытка суицида - объекта, на который ссылается ar, уже не существует }
Ответ отправлен: 25.05.2004, 11:48 Отправитель: bocha Отвечает barsik
Здравствуйте, Иван! Указатель занимает память, ссылка нет Ответ отправлен: 24.05.2004, 11:31 Отправитель: barsik Отвечает Fess
Приветствую Вас, Иван! Я предполагаю, что с самой сущностью указателей и ссылок вы знакомы, поэтому отвечать на вопрос буду конкретно. Говорить буду в основном о ссылках, и о их особенностях, т.к. в их использовании есть несколько ньюансов. Различия в следующем. Ссылка не может быть неинициализирована, а указатель может (конечно, плохой стиль кодинга, лучше присваивать NULL, но компилятор терпит, отсилы warning выкинет) см. приложение(1). Также ссылка не может быть изменена см приложение(2) т.е. ссылка, единожды сославшаяся на объект (a), не может потом ссылаться на другой объект(b). Если это произойдет, объект а присвоит значение объекта b. Существуют некоторые подводные камни при использовании ссылок см. приложение(3). Так делать нельзя никогда! Подведу небольшой итог: ссылку следует использовать, когда доподлинно известно, что объект, на который она указывает существует,
и будет существовать на протяжении всего времени жизни ссылки (зато, если вы используете ссылку, не нужно будет потом проверять её на равенство нулю, как с указателями); также когда известно, что ссылка будет на протяжении всего своего времени жизни указывать на один и тот же объект; ну и последнее, ссылку используют тогда, когда использование указателей невозможно или нежелательно (очень сильно зависит от контекста программы). Во всех остальных случаях используют указатели. Надеюсь понятно. Adios!
Приложение: Ответ отправлен: 25.05.2004, 15:18 Отправитель: Fess
Вопрос № 1632
По поводу другого вопроса немного уточню. Мне нужно связать модуль на С++ с программой на Pascal. Т.е. из Pascal вызвать функцию, написанную на С++. Задача такая: Ввести с клавиатуры строку, состояшщую из числа. Проверить: целое или вещественное это число. Находится ли оно в границах для целых (вещественных) чисел. Если использовать модули С++, то их нужно перекомпилировать. Fess посоветовал использовать typeid из typeinfo, но я же получаю в функцию строку, и эта процедура выводит мне char*. Насчет диапазонов. Мне нужно узнать входит ли введенное число в границы целых или вещественных чисел. Если использовать if и границы значений, прописанных в модулях: если перевести строку с числом большим, чем может хранить int, то что произойдет; и где прописаны эти значения, это константы?
Доброе время суток, Knave! Инуитивный способ: строка в смысле char*? Тогда попробуй найти в ней запятые и точки. "45,41" содержит в себе запятую, значит её преобразуешь во float или double. "4541" не содержит, значит её преобразуешь в int или long. Несколько домороченый способ, но работать должен. Границы значений int/long/short(целых) прописаны в limits.h, float/double (вещественных) в float.h ищи что-то типа INT_MAX, LONG_MIN. Подключай хедеры к проге и юзай. Твоё число, если оно выходит за пределы int, при переводе в int может преобразиться в другое число. Т.е. то, что не поместится, просто срежется.
Ответ отправлен: 26.05.2004, 17:10 Отправитель: Fess Отвечает vitya
Доброе время суток, Knave! Делайте так:
Приложение: Ответ отправлен: 24.05.2004, 16:01 Отправитель: vitya Отвечает www
Приветствую Вас, Knave! Если хочешь связать модуль на С++ с программой на Pascal пиши dll на C++ - и будет тебе счастье!
Ответ отправлен: 24.05.2004, 19:39 Отправитель: www
Вопрос № 1633
У меня снова вопрос. Задача такая: С клавиатуры вводится последоватльность из n символов s1...sn. Группа символов, разделенная пробелами и не содержащая пробелов внутри себе, называется словом. Найти количество слов, у которых первый и последний символы совпадают между собой. Мне нужно сделать все это с динамической памятью. Я написал программу, все все правильно, но она не работает (cм. приложение).
Доброе время суток, Knave! 1)Программа не компилировалась из-за отсутствия string.h, который содержит функции работы со строками в т.ч. и strlen. 2)Не рекомендуется использовать в программах на с++ одновременно потоковый в/в, функции из stdio и небуферизированый в/в на одно устройство 3)Если в задании не указано конкретно, что результат входа нужно где-то запоминать, зачем его вообще запоминать? Насколько я понимаю, необходимо просто получить и обработать строку неограниченой длины. 4)Отдельно стоящий символ - это слово или нет? Я считаю, что слово, но вот так-ли считает твой преподаватель :)? Если преподаватель считает, что это не так, добавь счетчик символов в слове, при входе в новое слово сбрасывай его, по достижении конца слова проверяй счетчик, после проверки начала-конца добавь проверку "внутри" и в ней увеличивай счетчик 5)Строчная
и прописная буквы эквивалентны или нет? Я считаю, что нет. 6)Табуляция - это пробел или нет? Я считаю, что пробел.
#include int main(){ int ch, first = 0, last = 0, cw_firs_equ_last = 0, in_word = 0; cout << "Enter string: "; while((ch=cin.get()) != '
'){//берем символ и это не конец :) if(in_word && (ch == ' ' || ch == ' ' )){//конец слова in_word = 0; if(first == last)cw_firs_equ_last++; }else if(!in_word && ch != ' ' && ch != ' '){//новое слово in_word = 1; first = ch; } last = ch; } if(in_word && first == last)cw_firs_equ_last++;//корректно обработать последний символ перед '
' cout << "cw_firs_equ_last = " << cw_firs_equ_last;//выводим число совпадений return 0; }
По поводу предыдущего вопроса №1632: #include MAX_INT... 1) удаляешь все пробелы 2)смотришь знаковое-ли число, если да - то удаляешь знак 3)проверяешь порядок числа, если цифр больше, чем порядок MAX_INT -err, если порядки равны, смотришь первую цифру, если она больше, чем у MAX_INT -err если равна, повторяешь просмотр для следующей цифры и т.д., пока не найдешь меньшую, если не нашел, или в это время встретилась большая цифра - значит не судьба (быть числу положительным знаковым целым)
Ответ отправлен: 25.05.2004, 11:44 Отправитель: bocha Отвечает CrackLab
Приветствую Вас, Knave! Исправленный вариант программы смотрите в приложении. Словом считается группа символов длинной > 2 и не содержащая пробелов внутри себя.
Приложение: Ответ отправлен: 24.05.2004, 15:11 Отправитель: CrackLab Отвечает vitya
Приветствую Вас, Knave! Пишите на C++ - е. Смотри приложение:
Приложение: Ответ отправлен: 24.05.2004, 15:57 Отправитель: vitya Отвечает www
Здравствуйте, Knave! Пользуйся отладчиком и будет тебе счастье! (См. приложение).
Приложение: Ответ отправлен: 24.05.2004, 19:38 Отправитель: www
Форма отправки вопроса
Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+
или отправлять вопросы с сайта по адресу:
http://rusfaq.ru/cgi-bin/Message.cgi.