Консультация № 191251
29.07.2017, 14:35
0.00 руб.
0 18 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Код:
int nVar = 10;
int pVar = &nVar;
const int* pcVar = pVar; //это можно,
int* pVar2 = pcVar; //а это - нет

Встретила вышеуказанный пример, комментарии от автора примера. Не могу понять, почему нельзя.
Похоже не правильно трактую код:
1 строка: объявлена переменная nVar типа int, присвоено значение 10;
2 строка: здесь не понимаю, вроде бы объявлена переменная pVar типа int и в нее записан адрес переменной nVar... Разве в обычные переменные можно записать адрес другой переменной?
А если это указатель, а не обычная переменная, то где * ? Разве не должно быть:
Код:
int* pVar = &nVar;

3 строка: объявлен указатель pcVar на константный указатель pVar, т.е. присваивается адрес pVar;
4 строка: объявлен указатель pVar2 на указатель pсVar, т.е. присваивается адрес pсVar. Почему нельзя?
Посмотрите, пожалуйста, где я неправильно перевожу?

Обсуждение

давно
Академик
20764
1861
30.07.2017, 12:10
общий
Формально можно всё. Правда, в таком виде компилятор, наверное, оба присваивания (в строках 2 и 4) не пропустит (и будет прав), но можно сделать явное cast-преобразование как указателя в целое, так и указателя одного типа в указатель другого. Только это трюкачество, и скорее всего ничем не обоснованное.
Тем не менее начиная со стандарта C99 даже существует специальный тип intptr_t для хранения указателей в целом числе. Хотя void * как-то понятнее.
P.S. по-моему, вы читаете неподходящий учебник.
давно
Посетитель
401172
78
31.07.2017, 16:13
общий
Цитата: Хватов Сергей
оба присваивания (в строках 2 и 4) не пропустит (и будет прав)

Про 2-ю строку понятно.
А про 4-ю почему нельзя, не могли бы объяснить?
Не могу понять, что в pVar2 записывается? Адрес pсVar? Или что-то другое.
Цитата: Хватов Сергей
P.S. по-моему, вы читаете неподходящий учебник.

Может и так. Не могу найти подходящий для человека, у которого нет ит-подготовки и всегда много вопросов "почему"
давно
Мастер-Эксперт
425
4118
31.07.2017, 19:43
общий
Адресаты:
Цитата: pNod
Не могу понять, что в pVar2 записывается? Адрес pсVar? Или что-то другое.

Ничего туда не записывается - компилятор не даст.
Я думаю Вам поможет с такими штуками разобраться современный компилятор. Например у меня стоит GCC версии 5.4, там, по сравнению со старыми компиляторами, сообщения об ошибках очень даже хорошо понятны. Как раз в пятой версии разработчики очень хорошо потрудились над описаниями ошибок. В более ранних версиях GCC тексты ошибок (для новичков) были плохопонятны.

А книжку можете посмотреть такую:
Столяров - Введение в язык С++.
Не знаю Вашей подготовки, но эта книга не про программирование вообще, а про фишки С++ без упора на всевозможные стандарьгные библиотеки. Я думаю такая методичка поможет понять именно язык, а не "куда тут процедуру вставить...".
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
401172
78
01.08.2017, 16:21
общий
Цитата: Вадим Исаев ака sir Henry
Ничего туда не записывается - компилятор не даст.

У меня компилятор ошибку выдает "invalid conversion from `const int*' to `int*' " и я понимаю, что речь идет о том, что в строке
Код:
int* pVar2 = pcVar;

идет попытка удалить ограничение константности pcVar.
Я не понимаю другое, почему вдруг pcVar стал константным указателем?
Ведь в строке
Код:
const int* pcVar = pVar;   

константность добавляется указателю pVar, а не pcVar или я не права?
Цитата: Вадим Исаев ака sir Henry
А книжку можете посмотреть такую:
Столяров - Введение в язык С++.

Огромное спасибо за совет! Ищу именно такую литературу, которая позволила бы понять язык, а не рассчитывать на компилятор.
давно
Мастер-Эксперт
425
4118
01.08.2017, 17:47
общий
01.08.2017, 17:56
Адресаты:
Цитата: pNod
Я не понимаю другое, почему вдруг pcVar стал константным указателем?

Потому что в этой строке самым первым словом стоит const, что соответствует объявлению константы, т.е. неизмениемой величины. И если изменяемую область памяти (переменную) ещё можно переделать в неизменяемую, то вот потом, когда идёт попытка незменяемой области памяти опять превратить в изменяемую, тут уж компилятор падает в обморок, потому что совсем запутался в наших "семи пятницах на неделю".
pcVar непосредственно мы менять не можем, она константа, но можно поменять косвенным образом через изменение nVar, поскольку наша константа это, в конечном итоге, тот же адрес памяти, что выделен для nVar.
константность добавляется указателю pVar, а не pcVar

Нет, константа как раз относится именно к pcVar, а вот указателю pcVar присваивается указатель pVar (т.е. в эту область памяти, защищённую от изменения словом const, запихивается адрес pVar).
Если бы слово const стояло бы возле объявления pVar, тогда именно pVar была бы константа.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
401172
78
01.08.2017, 18:35
общий
Спасибо за разъяснения, была прямо противоположного мнения, отсюда и полное непонимание
Пойду осмысливать возможности.
За Столярова еще раз спасибо, читать начала, интересно + написано простым доступным языком!
Вы, случайно, не знаете, есть ли учебные ресурсы, которые позволяли бы изучаемую теорию на практике применять?
давно
Академик
20764
1861
01.08.2017, 19:25
общий
Адресаты:
есть формальное описание обоих стандартов: как plain c, так и c++
Они, правда, платные (опять же формально, но найти их бесплатно легко можно) Их читать тяжело, но это как бы закон, и вы до его изучения, похоже, дозрели. А учебники вам помогут мало: они сильно отстают. и пишут их те, кто... Но не буду об этом: сам мог быть таким.
давно
Посетитель
401172
78
01.08.2017, 20:51
общий
Цитата: Хватов Сергей
есть формальное описание обоих стандартов

Думаю, Вы правы, первоисточник всяко лучше большинства учебников, можно попробовать.
Спасибо за совет! Несмотря на то, что столько мучаюсь от опечаток, стилей и порядка преподнесения материала, такая дельная мысль самой в голову не пришла.
давно
Мастер-Эксперт
425
4118
02.08.2017, 06:20
общий
Адресаты:
Цитата: pNod
Вы, случайно, не знаете, есть ли учебные ресурсы, которые позволяли бы изучаемую теорию на практике применять?

Что-то такое с ходу вряд ли могу сказать. Право слово, лучше всего будет, если Вы сами определитесь, что Вы хотите решить с помощью программирования. Ну, например, расчёт АЗ реактора подводной лодки. Главное, чтобы Вы хорошо разбирались в предмете (я имею в виду не программирование, а именно алгоритм расчёта ). В этом случае Вы сначала описываете просто на бумажке (в текстовом файле) что Вам нужно сделать, разбиваете задачу на несколько (если это сложный расчёт) блоков-подзадач, т.е. чтобы каждый блок решал свою конкретную часть задачи от и до: от ввода исходных данных, проверки их на корректность, реализации алгоритма подзадачи, проверка результата на корректность. Главное, чтобы задача была именно практическая и интересная для Вас. В этом случае, можно просто заглядывать в учебник или интернет и смотреть, как то или иное решается на выбранном Вами языке программирования. Тогда Вы будете понимать код программы, потому что он отражает именно то, что Вы знаете.
Можно почитать книжку: Дейтл, Дейтл - Как программировать на С++. Там каждая лекция иллюстрируется небольшой, но близкой к практике задачкой.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
401172
78
02.08.2017, 09:29
общий
Цитата: Хватов Сергей
Они, правда, платные
да уж...стоимость с11 на сайте меня удивила правда черновик можно скачать бесплатно.
Цитата: Вадим Исаев ака sir Henry
разбиваете задачу на несколько (если это сложный расчёт) блоков-подзадач
мой любимый структурный подход к программированию
Цитата: Вадим Исаев ака sir Henry
Право слово, лучше всего будет, если Вы сами определитесь, что Вы хотите решить с помощью программирования.

То есть Вы считаете, что продуктивней не замахиваться глобально на полное изучение языка, а начинать решать задачи с помощью тех инструментов, которые знаю? Дело в том, что я пока только имею поверхностное представление о инкапсуляции и полиморфизме. К тому же, у меня впечатление, что перечитывая какие-то главы, я их тут же забываю, поскольку не применяю никак.
Моя сфера интересов - базы данных и платежные системы. Я очень хорошо разбираюсь в бухгалтерии, экономике и финансовом менеджменте.



давно
Мастер-Эксперт
425
4118
02.08.2017, 10:09
общий
02.08.2017, 10:11
Адресаты:
Цитата: pNod
К тому же, у меня впечатление, что перечитывая какие-то главы, я их тут же забываю, поскольку не применяю никак.

В этом нет абсолютно ничего удивительного. Теорию с первого раза запоминают только гении. Для справки: Сергей Хватов - один из них. Хорошо запоминается именно практика, поскольку она проходит через Вас, вызывая эмоции. Неважно, отрицательные или положительные, т.к. только эмоции способствуют крепкому запоминанию.
Цитата: pNod
То есть Вы считаете, что продуктивней не замахиваться глобально на полное изучение языка, а начинать решать задачи с помощью тех инструментов, которые знаю?

Поскольку я не Ваш психоаналитик (т.е. не беру с Вас деньги за просто так ), то на этот вопрос Вы можете ответить только сами. Совсем не важно, глобальная задача или некая локальная, после её проработки (это, естественно, ещё до писания какого-либо кода на языке программирования), у Вас будет список небольших подзадач. Делать можно начинать любую подзадачу, главное, чтобы у Вас для этого было:
- понятный путь решения;
- некие входные данные, которые требуются для реализации этого пути;
- и понимание, какой именно результат должен быть получен.
Цитата: pNod
Моя сфера интересов - базы данных и платежные системы. Я очень хорошо разбираюсь в бухгалтерии, экономике и финансовом менеджменте.

Так это же восхитительно! Скачайте с сайта Центробанка данные по курсу валют (к примеру доллар США) или курсу драгметаллов (для примера: ссылка для доллара. Обратите внимание, что в ссылке можно задавать конкретные даты). И попробуйте на основе этих данных составить прогноз курса доллара на завтра. Я когда-то такую игрушку делал, пользовалась бешеной популярностью у некоторых бизнесменов .
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
401172
78
02.08.2017, 10:12
общий
Цитата: Вадим Исаев ака sir Henry
И попробуйте на основе этих данных составить прогноз курса доллара на завтра.

Надо попробовать, спасибо за совет!
давно
Мастер-Эксперт
425
4118
02.08.2017, 10:30
общий
02.08.2017, 10:33
Адресаты:
Цитата: pNod
Дело в том, что я пока только имею поверхностное представление о инкапсуляции и полиморфизме.

Кстати, не заморачивайтесь подобными проблемами. Программирование - это всего лишь инструмент, который помогает что-то решить за сроки, более краткие, чем это делает калькулятор. Ну имеете поверхностное представление и что? По крайней мере Вы об этом слышали и знаете на какие слова искать информацию. Я, к примеру, не имею представления, как делать па-де-де и па-де-труа, так что же теперь и не ужинать вовсе? Или, если взять Вашу сферу, я понятия не имею, какие риски ждут трейдров в этом году на Форекс. Но я ведь могу об этом прочитать, не правда ли? И, естественно, через пять минут об этом забуду, т.к. это вне сферы моих интересов. А вот если я по этому поводу займусь практикой и меня из-за этого раз 15 обуют всевозможные тамошние жуки, тогда понимание будет 100-процентным.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Старший Модератор
17042
808
03.08.2017, 06:58
общий
Адресаты:
Оформите ответ?
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
давно
Мастер-Эксперт
425
4118
03.08.2017, 08:05
общий
Адресаты:
Так я же не эксперт по этой теме...
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Мастер-Эксперт
425
4118
03.08.2017, 08:33
общий
это ответ
Здравствуйте, pNod!
Начнём с того, что из всего списка переменных только самая первая (nVar) хранит именно какое-то значение. Этот момент существенный для понимания работы с остальными переменными.
Следующие три переменные всего лишь хранят адреса, указывающие на какой-то объект, в данном случае на переменную nVar. По крайней мере так должно быть.
С объявлением переменно №2, pVar, явная ошибка, скорее всего это опечатка. Компилятор сразу же укажет на ошибку в этой строке. Судя по тому, что ей присваивается адрес nVar объявление должно быть таким:
Код:
int * pVar = &nVar;

Третья переменная pcVar объявлена как константа, неизменяемая, потому что первым словом стоит "const". Мы не сможем менять именно у неё значение, обращаясь к ней как к динамической переменной:
Код:
*pcVar = 22;  // Здесь компилятор выдаст ошибку

но значение можно менять косвенным образом, поскольку это всего лишь указатель, присваивая значение переменной nVar. Поэтому смысл в таком объявлении константы совершенно теряется, если только речь идёт не о работе конкретно с адресами.
Для четвёртой переменной подпись в комментарии совершенно справедлива, т.к. при этом константа преобразовывается в не-константу. Компилятор подобного объявления не пропустит. Да и если рассудить с логической точки зрения - всё-таки можно там менять что-то или нельзя? Явная неоднозначность и она должна устранятся на момент написания алгоритма задачи, а не на момент программирования.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Старший Модератор
17042
808
03.08.2017, 13:36
общий
Адресаты:
Старший модератор - эксперт экспертов.
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
давно
Мастер-Эксперт
425
4118
03.08.2017, 13:47
общий
Адресаты:
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Форма ответа