Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.02.2012, 16:58   #1
wir2ozz
Новичок
Джуниор
 
Регистрация: 13.02.2012
Сообщений: 1
По умолчанию *ptr++=0;

Здравствуйте!
Хочу разобраться со строчкой на C: *ptr++=0;
На одном из ресурсов дается следующее объяснение:

"Присвоить значение 0* переменной, на которую указывает ptr, затем увеличить значение указателя ptr так, чтобы он указывал на следующую переменную того же типа."

Не могу понять принцип работы этой операции. Объясните, кому не трудно и кто знает! Спасибо!
wir2ozz вне форума Ответить с цитированием
Старый 13.02.2012, 17:48   #2
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Я хоть и не знаток Си, но по описанию всё становится понятно. По-сути тут два действия:
1. присвоение текущему элементу массива (ссылка на этот элемент *ptr) значения "0"
2. увеличение указателя - т.е. указатель указывает не на текущий элемент массива, а на следующий. От типа переменных в массиве зависит на сколько увеличится указатель.
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 13.02.2012, 18:42   #3
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от wir2ozz Посмотреть сообщение
Здравствуйте!
Хочу разобраться со строчкой на C: *ptr++=0;
На одном из ресурсов дается следующее объяснение:

"Присвоить значение 0* переменной, на которую указывает ptr, затем увеличить значение указателя ptr так, чтобы он указывал на следующую переменную того же типа."

Не могу понять принцип работы этой операции. Объясните, кому не трудно и кто знает! Спасибо!
Нет, это неправильное объяснение.
Важно знать порядок вычисления выражений и приоритет операторов.

Для указанного вами выражения *ptr++=0; порядок вычисления следующий:
1) выполняется оператор ++
2) разыменовывается указатель с помощью оператора *
3) выполняется присваивание разыменованноку указателю значения 0 с помощью оператора =

Но этого недостаточно, чтобы понять, что в конечном итоге получится. Нужно еще знать, что является рузультатом выполнения каждой операции.
Результатом выполнения постинкриментного оператора ++ является значение его операнда до применения к нему инкримента. То есть значением является копия исходного значения. Причем полученное значение является rvalue , то есть значение, которое нельзя изменять. Чтобы было понятно, то, допустим, есть выражение x++++;. Это выражение можно представить как ( x++ )++.Сначала должно выполниться операция x++. Но так как полученное значение является rvalue и его менять нельзя, то в итоге получим ошибку компиляции. Такую же ошибку компиляции мы получим и для выражения ++x++;, так как сначала выполняется постинкримент, в результате которого получается rvalue, которое нельзя изменять. Но если вы напишите так ( ++x )++;, то компилятор скомпилирует этот код, так как значением прединкримента является lvalue, то есть значение, которое можно менять.

Теперь полученная копия исходного значения ptr разыменовывается с помощью оператора *, и этому разыменованному значению присваивается 0.

В этом объяснении термины rvalue и lvalue происходят от условного обозначения операндов в выражении присваивания:

lvalue= rvalue;

Например, x = 2;. Здесь x - это lvalue, то есть переменная, задающая область памяьти, которой можно присвоить значение, а 2 - это rvalue, ей значение нельзя присвоить.
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 13.02.2012 в 18:45.
Сыроежка вне форума Ответить с цитированием
Старый 13.02.2012, 21:34   #4
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
Для указанного вами выражения *ptr++=0; порядок вычисления следующий:
1) выполняется оператор ++
2) разыменовывается указатель с помощью оператора *
3) выполняется присваивание разыменованноку указателю значения 0 с помощью оператора =
Вот как раз вы и не понимаете приоритеты операций
У операции разыменования самый высокий приоритет. Потом выполняется присвоение, а уж потом инкремент.

Цитата:
Не могу понять принцип работы этой операции. Объясните, кому не трудно и кто знает! Спасибо!
Всю последовательность можно написать так:
Код:
*ptr = 0;
ptr++;
Получается что мы в ячейку, на которую ссылается указатель записываем ноль. А потом просто переходим к следующей ячейке памяти в оперативе.
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Старый 13.02.2012, 22:17   #5
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от MooNDeaR Посмотреть сообщение
У операции разыменования самый высокий приоритет. Потом выполняется присвоение, а уж потом инкремент.
Нет, у оператора разыменования и инкремента одинаковый приоритет, но выполнения происходит в порядке справа на лево. Потому сначала происходит инкремент (важно заметить, что он постфиксный), а затем уже разыменование.

Цитата:
Сообщение от MooNDeaR Посмотреть сообщение
Всю последовательность можно написать так:
Код:
*ptr = 0;
ptr++;
Выглядит это примерно так:
Код:
char* old = ptr;
ptr += 1;
*old = 0;
netrino вне форума Ответить с цитированием
Старый 14.02.2012, 13:00   #6
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
важно заметить, что он постфиксный
Вот именно. Поэтому и выполнится сначала разыменование, присвоение, а уже потом инкремент.
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Старый 14.02.2012, 15:35   #7
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Нет, у оператора разыменования и инкремента одинаковый приоритет,
Нет операций с одинаковым приоритетом. Иначе задачка про Буриданова осла получится. Если приоритеты равны, как их выбирать? Рандомно?
Прав MooNDeaR. Именно в этом порядке.
Разыменование, присвоение и постфиксный ++.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 14.02.2012, 18:27   #8
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию

Вот, мальчики, Вы все спорите, спорите...Возьмите и потестите дебагом в режиме Step into - и сразу будет понятно, кто прав. Можно же будет сразу отследить, что увидит компилятор на каждом шагу))))
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan
Blondy вне форума Ответить с цитированием
Старый 14.02.2012, 19:43   #9
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Цитата:
Нет операций с одинаковым приоритетом. Иначе задачка про Буриданова осла получится. Если приоритеты равны, как их выбирать? Рандомно?
Такие операции есть. Самые простые примеры: сложение и вычитание имеют один приоритет. Как они выбираются? Выполняются в порядке записи слева направо.

Цитата:
Вот, мальчики, Вы все спорите, спорите...Возьмите и потестите дебагом в режиме Step into - и сразу будет понятно, кто прав.
Не Step Into, а Trace Into - пошаговая трассировка.
Вадим Мошев вне форума Ответить с цитированием
Старый 14.02.2012, 21:44   #10
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
Можно же будет сразу отследить, что увидит компилятор на каждом шагу))))
В свое время приходилось работать с большой кучей строк через указатели, поэтому строчки вида *ptr++ = 0 для меня привычное дело и я уж точно знаю, что делает данная последовательность
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
JMP DWORD PTR [PAddress] - как узнать адрес Enkee Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 03.11.2011 13:14