Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru


RusFAQ.ru: Программирование на C / C++

Выпуск № 515
от 27.05.2004, 17:40

Администратор:
Имя: Nick.Box
URL: Информационный ресурс
ICQ: 365124
[censored], [censored]
О рассылке:
Задано вопросов: 1648
Отправлено ответов: 3284
Активность: 199.2 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

Sedric
Статус: Доверительный
Общий рейтинг: 136.5
[Подробней >>]
CrackLab
Статус: Доверительный
Общий рейтинг: 140
[Подробней >>]
vitya
Статус: Профессиональный
Общий рейтинг: 109.24
[Подробней >>]
 
bocha
Статус: Доверительный
Общий рейтинг: 145.71
[Подробней >>]
barsik
Статус: Доверительный
Общий рейтинг: 114.28
[Подробней >>]
Fess
Статус: Доверительный
Общий рейтинг: 122.68
[Подробней >>]
 
www
Статус: Начальный
Общий рейтинг: 123.33
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 1630. Привет всем экспертам! У меня есть к вам вопрос. В C++ есть ссылки и указатели. А в чём их отличия?... (ответов: 6)
Вопрос № 1632. По поводу другого вопроса немного уточню. Мне нужно связать модуль на С++ с программой на Pascal. Т.... (ответов: 3)
Вопрос № 1633. У меня снова вопрос. Задача такая: С клавиатуры вводится последоватльность из n символов s1...sn. Гр... (ответов: 4)

Вопросов: 3, ответов: 13


 Вопрос № 1630

Привет всем экспертам! У меня есть к вам вопрос. В C++ есть ссылки и указатели. А в чём их отличия?



Вопрос отправлен: 24.05.2004, 09:53
Отправитель: Иван

[Следующий вопрос >>] [Список вопросов]

Отвечает Sedric

Доброе время суток, Иван!
Ссылки объявляются следующим образом:
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, то что произойдет; и где прописаны эти значения, это константы?



Вопрос отправлен: 24.05.2004, 13:09
Отправитель: Knave

[Следующий вопрос >>] [Список вопросов]

Отвечает Fess

Доброе время суток, 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м. приложение).


Приложение:


Вопрос отправлен: 24.05.2004, 13:08
Отправитель: Knave

[Следующий вопрос >>] [Список вопросов]

Отвечает bocha

Доброе время суток, 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.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (24)
C / C++ (15)
Perl (2)
Builder / Delphi (17)
Pascal (21)
Basic / VBA (2)
Java / JavaScript (4)
PHP (12)
Криптография (6)
WinAPI (8)
Радиоэлектроника (9)
Пользователю
Windows 95/98/Me (36)
Windows NT/2000/XP (49)
"Железо" (30)
Поиск информации (16)
Администратору
Windows NT/2000/XP (22)
Linux / Unix (9)
Юристу
Гражданское право (10)
Семейное право (8)
Трудовое право (9)
КоАП (7)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование
Профессиональная WEB-Студия B.I.T.


Яндекс цитирования
© 2001-2004 Россия, Москва. Авторское право: Калашников О.А.

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное