![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Competitor |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 440 Регистрация: 23.3.2005 Где: Tula Репутация: нет Всего: -1 |
Как передать char* s в функцию в качестве модифицируемого параметра, т.е. чтобы после выполнения следующего кода:
на экран выводилось "Привет". |
|||
|
||||
| _hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 16 Всего: 98 |
передавать char** (или ссылку на char*)
-------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
можно так:
т.е. передаешь ссылку на указатель. |
|||
|
||||
| Helicopterr |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 355 Регистрация: 20.8.2005 Где: Stavropol Репутация: 2 Всего: 3 |
Competitor
сделай так:
-------------------- people can fly |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
А так разве нельзя? Это сообщение отредактировал(а) Romikgy - 18.5.2006, 13:21 -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
нельзя
|
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
baronp, чего?
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
это был короткий ответ на твой предыдущий пост. Объясняю почему нельзя: хоть tem и является указателем, это еще не значит, что его изменение даст эффект за пределами функции. Изменить можно только то, на что он указывает, а изменение самого указателя изменит лишь его локальную копию в данной функции. Внешний же указатель s при этом не изменится. Поэтому я и посоветовал в своем первом посте использовать ссылку на указатель. Главное не забыть освободить память, которая выделяется в функции func, но это уже другой разговор. |
|||
|
||||
| gruy |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 4.6.2004 Репутация: нет Всего: 3 |
Romikgy, в твоем примере general при выходе из функции удалится.
|
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
никуда оно не удалится , эта строка прописывается в исходном коде проги baronp, Я хотел задать вопрос почему нельзя? Откуда это все ? я понимаю если функция была вызвана как константная тогда да, а здесь вчем трабла? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
запусти свой вариант, убедись что не работает. Поставь между tem и звёздочкой амперсанд в прототипе функции и убедись что работает. Еще раз подумай почему.
|
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Каюсь уже убедился, только нафига тогда придумали приставку const
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| likehood |
|
|||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
ты имеешь ввиду const перед указателем или const в конце прототипа функции?
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Путаешь теплое с мягким... Вот пример:
Как думаешь, изменится N после вызовы foo? Вот и с указателем то же самое: если переменная передается по значению, она копируется и меняется только ее копия (внутри функции), снаружи все сохраняется... То, что вместо int у тебя указатель, ничего не меняет: его значение меняется только внутри функции. -------------------- ... |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Это я уже понял, мне интересно на кой тогда делать такой вызвов void foo (const int a) Ведь всеравно , что внутри менялось в наружу не выдет? зачем надо было так извращатся то? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Я смотрю в С много чего есть , правда пользы от него маловато, зато когда начинаешь об этом читать, голова может сварится
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| likehood |
|
||||
|
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Польза все же есть, вот пример:
Если оставить все как есть, получим ошибку компиляции: нельзя изменить значение по указателю s в функции func. Если же const убрать, получим Best string. |
||||
|
|||||
| Fazil6 |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
не все так просто и очевидно. Ты написал функцию int fffff(char* s); теперь я пишу программу и применяю твою функцию. Я знаю, что часто указатель передается в функцию для того, чтобы туда был записан результат. Я не знаю как и что делает эта ф-я и я не знаю что будет лежать по этому указателю после вызова этой функции. А вот если ты напишешь функцию int fffff(const char* s); у меня никаких сомнений нет по поводу того зачем передается указатель. Тоже самое относится и к аргументам ссылкам. |
||||
|
|||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
И зачем? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
затем, что это аргумент для функции, а не буфер для результата. Затем, что передача ссылки(указателя) намного эфективнее чем передача значения при передаче классов/структур и классы обычно так и передаются |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
это с этим как то не соотносятся в чем эффективнее? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Fazil6 |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
хорошо. Начнем с конца.
допустим нам в функцию надо передать std::string можно так void fun(std::string str) а можно и так void fun(std::string* str) результат будет одинаковый и в первом и во втором случае внутри функции мы получим необходимую строку, но в первом случае будет создан еще один объект, в этот объект будут копироваться все значения полей (все, что определено в конструкторе копии), а во втором будет передано значение адреса и все. Вызов второго варианта намного быстрее.
прекрасно соотносится. В нашем 2-м варианте я не могу знать зачем передается указатель просто из соображений эфективности или для того, чтобы записать что-то по этому адресу, а если будет стоять const, то это значит, что функция говорит, что она не собирается изменять содержимое по этому адресу и буфером для результата это не является |
||||
|
|||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Функции вида void func(const int a) действительно бессмысленны. const нужно для ссылок и указателей, чтобы гарантировать, что мы с помощью этой ссылки или указателя не изменим значение.
НО для указателя - указываемое значение, а не значение самого указтеля. |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Окей здесь вышло недопонимание терминов, об этом я знал давно А с этим как то не совсем соглашусь, ты когда нибудь смотрел ассемблер код такой функции с const и без оной? Посмотри ... он ничем не отличается -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Именно это Fazil6 и говорит. const практически не влияет на сгенерированный код, это подсказка для программиста и компилятора.
-------------------- ... |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
я и не заявляю, что const влияет на эфективность. я говорю совершенно о другом. если аргументом функции является const std::string*, то я понимаю, что указатель передается только для того, чтобы не передавать сам объект по значению и данные менять не собираются, а если const не указан, то я буду предполагать, что внутри этой функции этот объект будут изменять и после вызова функции моя строка вполне возможно будет изменена. Т.е. в случае когда в аргументах функции встречается указатель на константу, то компилятору это значит "нельзя менять содержимое", а для программиста вызывающего эту функцию это говорит: "содержимое не будет меняться" |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 3 Всего: 106 |
Romikgy, раз уж ты о ассемблере заговорил, то наверняка понимаешь, что такое вызов cdecl. При очень плотной оптимизации, значения параметров с модификатором const могут не сохраняться дополнительно в стеке, а использоваться уже в другой функции. А теперь подумай, что будет, если ты вот такой параметр изменил: следующая по коду функция примет как будто тот же параметр, но на самом деле он будет изменен предыдущим вызовом. Это единственный случай, когда нужно помнить о const в параметрах типа void foo(int c). Остальное уже все рассказали, повторяться не буду.
PS: оптимизация в сторону скорости работает по такому принципу только если ты ставишь const, в остальных случаях, все необходимые параметры сохраняются в стеке отдельно. Поэтому не пытайтесь изголяться с преобразованиями типа *(TYPE*)&c, где c - константа, ни к чему хорошему это не приведет, особенно, если вы таки используете оптимизацию компилятора. Подробно по всем опциям оптимизации написано в MSDN'е. Это сообщение отредактировал(а) GremlinProg - 19.5.2006, 14:11 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Если честно то не сильно , я просто взял две фунции и посмотрел что получается на выходе.
не понял? Добавлено @ 15:17 Все более к этому склоняюсь здесь можно по подробнее , на что влияет и когда? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 3 Всего: 106 |
cdecl - то вызов функции с передачей параметров в стеке. Вызывающий оператор сам очищает стек после вызова, поэтому параметры, которые он передаёт функции он может использовать повторно. Это одно из преимуществ, которое и породило thiscall.
Под этим я и подразумевал:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
понятно , а как очистить стек из С++ с модификатором -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 3 Всего: 106 |
не понял вопроса, зачем тебе нужно его очищать?
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| UnrealMan |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Помимо сказанного выше другими, добавлю. Если рассматривать const для ссылок, то он играет существенную роль. Например, если у тебя есть функция: void Func(char *&p), ты не сможешь передать ей по ссылке константную строку или строку-массив const char s1[] = "Text"; char s2[] = "Text"; Чтобы передать s1 (или просто "Text") либо s2, тебе придётся написать перед & слово const: void Func(char *const &p). Заодно ты запрещаешь изменение указателя p в своей функции. Для того, чтобы запретить ещё и изменение данных по этому указателю, надо дописать const где-то перед * void Func(const char *const &p). В случае передачи классовых объектов по ссылке без const у тебя не пройдёт ни одно неявное преобразование типа (к типам данных классов):
Это сообщение отредактировал(а) UnrealMan - 20.5.2006, 10:48 |
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 3 Всего: 106 |
UnrealMan, хорошее замечание! Про неявное преобразование я не знал
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Нда, и неклассовых, кстати, тоже:
Правда, экономить на времени передачи параметров простейших типов, нагромождая их описанием const &, в большинстве случаев будет излишеством :-) Это сообщение отредактировал(а) UnrealMan - 20.5.2006, 11:32 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |