|
Автор: Briska
Дата : 21-02-02, Чтв, 18:11:15
|
товариши и товарищи (Женс) я тyт понимаешb пытаюсь yчить C так yж надо для кyрсa я на. а не помочь ли мне? Спасибки
|
[ 22-02-02, Fri, 1:14:01 Отредактировано: Briska ] |
|
|
Автор: Большой Грызь
Дата : 21-02-02, Чтв, 18:15:10
|
Ок.. что такое поинтер.. Давай сначала - с азов самых Что такое обычные переменные и как они в памяти хранятся ты знаешь? |
----------------------------- Quod erat demonstrandum! |
|
|
Автор: Briska
Дата : 21-02-02, Чтв, 18:17:27
|
примерно ------------------------- Qуод ерат демонстрандум!
|
|
|
Автор: Большой Грызь
Дата : 21-02-02, Чтв, 18:28:37
|
Бриска, подпись мою хоть бы не переводил
Рассматривай память, как массив байтов. Ячейка в памяти - ячейка в массиве. Адрес ячейки - индекс в массиве:
0000 => 00 0001 => 13 0002 => 1A .... 12F0 => F2 12F1 => E0 ...
И так далее (адреса и значения ячеек в hex написал).
Когда ты определяешь переменную, скажем: int i; то ей отводится определенное место по определенному ардесу в памяти. По сути, обращение к какой-то переменной - это обращение к такой-то ячейке по такому-то адресу памяти. В примере с i, переменная i занимает два байта (так определен тип int). Или другой пример: char st[11] = "The string"; Переменная st займет 11 байт в памяти. Допустим, что переменная была определена по адресу 3400. Тогда ячейки памяти будут содержать следующие значения по следующим адресам:
3400 => 'T' (код ASCII указанной буквы) 3401 => 'h' 3402 => 'e' 3403 => ' ' 3404 => 's' 3405 => 't' 3406 => 'r' 3407 => 'i' 3408 => 'n' 3409 => 'g' 340A => 0
Пока понятно? |
----------------------------- Quod erat demonstrandum! |
|
|
Автор: Briska
Дата : 21-02-02, Чтв, 18:33:47
|
Лана Тёма Спасибки тебе огромное, но труба зовет а значит бyдет yтро, которого как говорится без мyдреного вечера не бывает! и по сей причине я yдаляюсь, но вернусь и мы еше продолжим ету интелектуалную беседy! Sleep tight |
[ 22-02-02, Fri, 1:39:24 Отредактировано: Модератор ] |
|
|
Автор: Большой Грызь
Дата : 21-02-02, Чтв, 18:41:15
|
Оки Остальное завтра. То есть непосредственно уже о поинтерах и с чем их едят |
----------------------------- Quod erat demonstrandum! |
|
|
Автор: ВиТаля
Дата : 22-02-02, Птн, 13:28:21
|
Мне тоже интересно Рассказывай, рассказывай |
|
|
Автор: Briska
Дата : 22-02-02, Птн, 18:14:05
|
ны ВОт я и пришел , как и обешал, пока я вроде во все вьезжаю, поехали далше.
|
[ 23-02-02, Sat, 2:32:19 Отредактировано: Briska ] |
|
|
Автор: ВиТаля
Дата : 22-02-02, Птн, 19:21:41
|
А чаво в ICQ не появляешся? |
|
|
Автор: Briska
Дата : 22-02-02, Птн, 19:31:25
|
Виталя, я всегда в ICQ, но меня все реже бывает ы компутера и поетому я прячусь
|
|
|
Автор: Большой Грызь
Дата : 22-02-02, Птн, 19:38:47
|
Дальше, так дальше Для начала ситуация: тебе надо написать процедуру, которая получит, как параметры, две строки, сравнит их, а затем вернет 0, если они равны, 1, если первая строка "больше" или -1, если вторая "больше" (такая функция уже есть - strcmp в strings.h, но как пример - пойдет). Один из способов взять да скопировать все содержание этих двух строк в локальные переменные этой функции. Но есть пара неприятных моментов - во-первых строки могут быть любой длины и внутри функции ты не можешь знать, сколько именно места тебе потребуется. Во-вторых - а зачем копировать-то? Это лишняя операция. А вот если бы ты мог прочитать содержимое той строки непосредственно с того места в памяти, гда она находится, то тогда не надо ни копировать, ни заботиться о лишнем месте в памяти под это копирование. Встает вопрос: если указанная функция вызывается из десяти различных мест и ей каждый раз передаются разные строки, то как ей указать куда в памяти смотреть. Вот для этого и существуют специальный тип переменных, называемый поинтером - указателем. Такая переменная хранит в себе именно адрес чего-либо.
Возьмем тот же пример: char st[11] = "The string"; st располагается по адресу 3400.
Определим еще одну строку: char st2[15] = "Another string"; Допустим, st2 располагается по адресу 3500.
Теперь определим переменную типа поинтер на char: char *pst;
Теперь можно этой переменной присвоить адрес какой-то другой переменной: pst = st; // pst = 3400 после выполнения этой строки pst = st2; // pst = 3500 после выполнения этой строки
Обычно для того, чтобы указать, что нужно взять адрес переменной, а не ее значение, надо перед названием переменной ставить &. Исключения составляют массивы - перед ними не надо ставить & - именно так, как было в предыдущем примере. С амперсендом вот другой пример: int i; int *pi; pi = &i;
Запись pi = &i, означает "взять адрес переменной i и засунуть его в переменную pi.
Теперь пара примеров, как работают поинтеры:
char ch; // временная переменная типа char pst = st; // pst = 3400 после выполнения этой строки ch = *pst; // ch = "T" - значение той ячейки памяти, на которую указывал поинтер pst pst++; // pst = 3401 после выполнения этой строки ch = *pst; // ch = "h" - значение той ячейки памяти, на которую указывает поинтер pst теперь pst += 6 // pst = 3407 после выполнения этой строки *pst = 'o'; // запись по адресу 3407 символа 'o' printf (st); // напечатает "The strong" так как с помощью поинтера изменили соответсвующую букву.
|
----------------------------- Quod erat demonstrandum! |
|
|
Автор: Дядя Фёдор
Дата : 22-02-02, Птн, 20:58:14
|
да... удобная штука этот поинтер! Жалко только это дело под джавку не реализовали!)))
Грызь... очень полезная инфа! Спасибо! |
_______________________________________ Все беды в мире от непрофессионализма! (Кто-то Умный) |
|
|
Автор: Илья Товбейн
Дата : 10-04-02, Срд, 21:41:50
|
Ужасная штука этот пойнтер. Есть такая хорошая шутка: "Как выгледет самая ужасная вещь в современном программировании в 2-х символах?" - "*&".
В java есть другие и намного лучшеи механизмы. |
|
|
Автор: Рафаэль
Дата : 20-04-02, Сбт, 12:36:04
|
Как не приятно чуствовать себя полным ИДИОТОМ!!! |
|
|
Автор: Большой Грызь
Дата : 20-04-02, Сбт, 19:55:09
|
Рафаэль Ну это всегда так, когда речь заходит в каком-то профессиональном направлении. Будь то врачи или будь то программисты |
----------------------------- Quod erat demonstrandum! |
|
|
Автор: eliuha
Дата : 16-07-02, Втр, 21:34:36
|
ага в java.lang.String.* есть метод equails(String)
|
Нет кайфа без лайфа Хоть фейсом об тейбл. |
|
|
Автор: Briska
Дата : 30-09-04, Чтв, 19:21:18
|
да уж.. да и в самои Java есть references to Objects. делает то же самое фактичиски но не для простых data types. int, char, double and float.
И вот прошло не мало времени с тех пор, и я шас сам в етом деле разбираться начал
Тёмке спасибо anyway! |
Тот самый Бриска из далекого и туманного...
|
|
|
Автор: Tarlog
Дата : 01-10-04, Птн, 17:12:55
|
да... удобная штука этот поинтер! Жалко только это дело под джавку не реализовали!)))
Это еще пол беды, пойнтеры не очень нужны, когда есть референсы. Но вот задачка: как передать функции переменную by reference? Чур в учебники не заглядывать! |
[ 01-10-04, Fri, 23:13:24 Отредактировано: Tarlog ] |
|
|
Автор: Большой Грызь
Дата : 01-10-04, Птн, 17:58:10
|
void func (int ¶m) { param = 12345; //vyshel zaychik pogulyat }
int main () { int x; func(x); // ta-dam.. x equals to "zaychik" now } |
Жизнь человека немного стоит по сравнению с его делом. Но чтобы делать дело, надо жить. (Э. Хемингуэй) |
|
|
Автор: Tarlog
Дата : 02-10-04, Сбт, 00:12:24
|
Большой Грызь На Java, а не C++. |
|
|
Автор: Тигра
Дата : 06-10-04, Срд, 05:16:28
|
на джаве все объекты передаются by reference а все типы by value. если нужно передать значения by reference то их оборачивают объектом (который уже передастся by reference ) и измняют его |
|
|
|
Автор: Tarlog
Дата : 06-10-04, Срд, 08:56:09
|
Тигра Ну в целом правильно мыслишь. Только не до конца В Java все передается by value. Будь это простой тип или референс к объекту. В отличие от С++ на Java "сам объект" вообще никуда никогда не передается. Тут главное отличие не в том, что на Java нет пойнтеров, т.к. на Java есть пойнтеры, а в том, что на Java нет пойнтеров на простые типы (и в том числе пойнтеров на пойнтер). |
|
|
Автор: Lisopoval
Дата : 06-10-04, Срд, 10:50:09
|
Знач так. Формально на Яве пойтеров таки нет на уровне языка. Есть референсы, и отношение к ним как ко всем примитивным типам - аллокация на стэке, передача по значению и т.д. Все, что создано new, есс-но, не копируется под ковром при передаче параметров, однако все имеющееся референсы (параметры, локальные, глобальные или из других классов) учитываются при Garbage Collection.
По-поводу пойнтеров - хорошо, что их нет в Яве и хорошо, что они есть в Си. Кесарю кесарево. |
|
|
Автор: Tarlog
Дата : 31-10-04, Вск, 12:42:57
|
ну зачем тебе поинтер на поинтер?
Что-бы изменит String внутри функции.
I like Java , but the employers seem to be keen on C/C++ just as much if not more.
Я работаю программистом на Java и у нас набирают народ. |
|
|
Автор: Gunslinger
Дата : 19-11-04, Птн, 13:56:48
|
int & foo () { int a = 10; return a; }
void main() { cout << foo(); }
Каков будет результат и почему. |
Выбор всегда остаеться за нами. Всегда - за нами. Мы идем вперед, мы торопимся, но хватит ли нам отваги прервать движение, остановиться, превозмогая страх, и повернуться спиной к опасности или счастью, которые всегда впереди, и лицом к выбору, который всегда, вечно, неумолимо и невидимо остаеться за нами. (ц.) H.L.Oldie |
|
|
Автор: Tarlog
Дата : 20-11-04, Сбт, 02:27:39
|
Подозреваю, что зависит от компайлера и от ОС. По идее напечатает 10, но даст warning при компеляции. Возможно, что напечатает junk, а не 10. В среде дебаггинга вероятность напечатанья 10 очень велика. Что будет на сервере, сказать затрудняюсь. Подозреваю, что программа может даже вылететь или напечатает junk.
Причина: программа напечатает число по адрессу в который было занесено число 10. Сам адресс находится в stack, но уже за пределами его используемой части. Т.е. 10 там возможно еще сидит (точно сидит если речь идет а дебагере или скажем ДОСе), а возможно и нет. |
|
|
Автор: Тигра
Дата : 20-11-04, Сбт, 02:45:32
|
пишет 10. возвращается из функции не аддресс а конкретное значение, а значения (если иначе не указанно ) возвращаются By value. То есть в стеке образуется какая-то ячейка со значением результата функции в каторую переписывается значение переменной a |
|
|
|
Автор: Tarlog
Дата : 20-11-04, Сбт, 03:59:20
|
а значения (если иначе не указанно ) возвращаются By value
Тигра Так ведь указано by reference:
int & foo ()
|
|
|
Автор: Тигра
Дата : 20-11-04, Сбт, 06:21:52
|
да , незаметил. но в данном случае не важно. всё равно 10 напишет. в стеке этот участок уже типа свободен, но так как первое действие после выхода из функции это считыванье из того самого аддресса то значение ещё там. Но вообще на мой взгляд так не пишут, если это будет бежать в многопоточной среде, то хрен его знает что оно выдаст |
|
|
|
Автор: Gunslinger
Дата : 21-11-04, Вск, 00:39:45
|
Автор: Тигра в стеке этот участок уже типа свободен, но так как первое действие после выхода из функции это считыванье из того самого аддресса то значение ещё там.
О... Это то что я искал.
Все знают что это не правильно и так не пишут. Интересно было, если это не правильно, и везде написано что это не правильно. то почему это работает. И вообще это хороший пример для проверки программистов. У нас в фирме я услышар реплику одного "программиста" и долго смеялся. "Причем здесь стак, стак это там где функции сидят..."
Кстати работает и не в дебагге. Проверял в gcc. |
Выбор всегда остаеться за нами. Всегда - за нами. Мы идем вперед, мы торопимся, но хватит ли нам отваги прервать движение, остановиться, превозмогая страх, и повернуться спиной к опасности или счастью, которые всегда впереди, и лицом к выбору, который всегда, вечно, неумолимо и невидимо остаеться за нами. (ц.) H.L.Oldie |
|
|
Автор: Тигра
Дата : 21-11-04, Вск, 01:57:46
|
я тоже шутки раде прогнал на VS.NET и увидел ту же десятку. но это всё фигня, бросай С++ и переходи на С# или на Java, с этими языками такие вопросы просто не возникают. Я щас пишу 2 проэкта на С# и один на Java и так сказать сердце радуется что этих грёбаных поинтеров нету |
|
|
|
Автор: Gunslinger
Дата : 21-11-04, Вск, 02:10:19
|
Да я бы с радостью. Но работа у меня все равно на с++. |
Выбор всегда остаеться за нами. Всегда - за нами. Мы идем вперед, мы торопимся, но хватит ли нам отваги прервать движение, остановиться, превозмогая страх, и повернуться спиной к опасности или счастью, которые всегда впереди, и лицом к выбору, который всегда, вечно, неумолимо и невидимо остаеться за нами. (ц.) H.L.Oldie |
|
|
Автор: Тигра
Дата : 21-11-04, Вск, 02:44:16
|
это точно , хотя до того как я начал писать на Джаве мне нравился С++ |
|
|
|
Автор: Tarlog
Дата : 21-11-04, Вск, 15:06:24
|
Кстати работает и не в дебагге. Проверял в gcc.
Тут в основном вопрос о сегментации памяти. В дебагере сегментации проводится в очень определенном участке памяти, а в ОС не обязательно. Собственно в такой программе это не заметно, но если бы там был скажем большой (около 64К) массив в функции, т.е. что-то вроде int & foo () { char b[655535]; int a = 10;
return a; }
void main() { cout << foo(); }
щансы получить 10 уменьшаются в несколько раз. Т.к. а уже не влезает в сегмент, а значит требуется новый сегмент, который возвращается сразу после выхода из функции. |
|