24.09.2017, 18:45 [+3 UTC]
в нашей команде: 2 128 чел. | участники онлайн: 3 (рекорд: 21)

:: РЕГИСТРАЦИЯ

:: консультации

:: задать вопрос

:: все разделы

:: правила

:: новости

:: участники

:: доска почёта

:: форум

:: блоги

:: поиск

:: статистика

:: наш журнал

:: наши встречи

:: наша галерея

:: отзывы о нас

:: поддержка

:: руководство

Версия системы:
7.41 (25.02.2017)

Общие новости:
23.02.2017, 09:51

Форум:
24.09.2017, 16:39

Последний вопрос:
24.09.2017, 14:40

Последний ответ:
24.09.2017, 15:05

Последняя рассылка:
24.09.2017, 14:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
15.08.2009, 18:53 »
Витек Сахаров :)
Прикольный портал... Чувствуется рука профессионалов. Так держать!
07.08.2012, 12:02 »
VladimirNick
Да, спасибо. Примерно так и сделал. В модуле формы в процедуре установки видимости налоговой закладки (по умолчанию она выключена) вставил проверку контрагента. При выборе нужного контрагента налоговая закладка включается, в нужное поле подтягивается необходимый код таможенного органа. [вопрос № 186491, ответ № 271388]

РАЗДЕЛ • С / С++

Создание программ на языках C и C++.

[администратор рассылки: Андрей Кузнецов aka Dr_Andrew (Старший модератор)]

Лучшие эксперты в этом разделе

Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 238
solowey
Статус: 6-й класс
Рейтинг: 81
Хватов Сергей
Статус: Академик
Рейтинг: 70

Перейти к консультации №:
 

Консультация онлайн # 191147
Раздел: • С / С++
Автор вопроса: pNod (1-й класс)
Отправлена: 13.06.2017, 18:33
Поступило ответов: 1

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Читаю учебник по С++, встретила следующее выражение:
while( *p1++ = *p2++ ){}.
Я читаю это так:
- берем значение по адресу, на которое указывает p2
- увеличиваем на единицу
- присваиваем полученное вместо значения по адресу p1
- p1 увеличиваем на единицу...
Сомневаюсь, что я права. Посмотрите, пожалуйста! smile

Состояние: Консультация закрыта

Ответ # 275089 от Лысков Игорь Витальевич (Старший модератор)

Здравствуйте, pNod!
- берем значение по адресу, на которое указывает p2
- увеличиваем на единицу указатель p2
- присваиваем полученное вместо значения по адресу p1
- p1 увеличиваем на единицу...
- продолжаем копировать байты, пока записанный байт не будет равен 0x00,
т.о., мы скопируем строку вместе с завершающим нулем.


Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 13.06.2017, 18:59

5
нет комментария
-----
Дата оценки: 13.06.2017, 20:08

Рейтинг ответа:

+2

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 191147
pNod
1-й класс

ID: 401172

# 1

= общий = | 13.06.2017, 19:32 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Игорь Витальевич, спасибо, можно на примере для понимания?:
char FI[2] = { a, b };
char *p1, *p2;
p1 = NULL;
p2 = FIO;
while( *p1++ = *p2++ )
{
cout << p1;
}

Получается:
- берем адрес a
- записываем в указатель p1
- печатаем a
- p2 увеличиваем на единицу, т.е. сдвигаем на один char и он сейчас указывает на b
- p1 также увеличиваем на единицу, т.е. сдвигаем на один char... в этот момент здесь пусто или мусор?
- берем b
- записываем в указатель p1
- печатаем b
- p2 увеличиваем на единицу, т.е. сдвигаем на один char и он сейчас указывает на завершающий ноль
- цикл завершен когда в p1 запишется завершающий ноль?

• Отредактировал: pNod (1-й класс)
• Дата редактирования: 13.06.2017, 19:33

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 2

 +1 
 
= общий = | 13.06.2017, 19:56 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

char FI[3] = { 'a', 'b', 0 }; //во-первых, если a и b - символы, а не define-ы, то надо брать в кавычки,
//во-вторых, мы хотим копировать строку, а не массив байт, в конце нужен 0
char s[256];
char *p1, *p2;
p1 = s; //просто NULL нельзя, памяти-то нет, будет вылет. Надо дать либо адрес массива символов, либо запросить динамическую память
p2 = FI; //теперь p2 - указатель на массив FI
//можно было записать и так:
p2 = "ab"; //без массива FI

/* так писать нельзя, копируем побайтно, и пытаемся вывести всю строку (у которой предполагается в конце 0!)
while( *p1++ = *p2++ )
{
cout << p1;
}
*/
//делаем так:
while( *p1++ = *p2++ ); //сначала скопируем всю строку
cout << s; //затем строку выводим

Получается:
- берем символ по адресу p2
- записываем по адресу, куда указывает указатель p1
- p2 увеличиваем на единицу, т.е. сдвигаем на один char и он сейчас указывает на b
- p1 также увеличиваем на единицу, т.е. сдвигаем на один char... в этот момент здесь пусто или мусор? (считаем, что мусор)
- проверяем символ на 0, если не 0, то продолжаем копировать
- цикл будет завершен, когда копируемый символ будет равен ноль
- выводим всю строку

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

• Отредактировал: Лысков Игорь Витальевич (Старший модератор)
• Дата редактирования: 14.06.2017, 10:29

pNod
1-й класс

ID: 401172

# 3

= общий = | 13.06.2017, 20:08 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Теперь все ясно, спасибо! Столько ошибок понаделала в таком маленьком примере, стыдно smile

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 4

= общий = | 13.06.2017, 20:13 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Стыдно не хотеть учиться. Ошибки - дело поправимое.
Обращайтесь, если что smile smile

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 5

= общий = | 13.06.2017, 20:14 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Спасибо! smile

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 6

= общий = | 14.06.2017, 10:33 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Небольшая неточность во фрагменте:

while( *p1++ = *p2++ ); //сначала скопируем всю строку
cout << p1; //затем строку выводим
Дело в том, что указатель p1 в конце копирования строки будет указывать
на завершающий 0. Чтобы вывести полученную строку, надо указать начальный адрес строки, т.е. s
cout << s;

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 7

= общий = | 14.06.2017, 16:40 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Да, точно, указатель же сдвинулся при копировании до завершающего нуля!

Игорь Витальевич, а вот по поводу этого фрагмента:

© Цитата: Лысков Игорь Витальевич
/* так писать нельзя, копируем побайтно, и пытаемся вывести всю строку (у которой предполагается в конце 0!)
while( *p1++ = *p2++ )
{
cout << p1;
}


интересно в Си можно было бы так побайтно символы вывести:

while( *p1++ = *p2++ )
{
printf("%с\n", p1);
}

скопировал - напечатал...?

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 8

 +1 
 
= общий = | 14.06.2017, 16:49 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Да все можно. Только не надо забывать, что p1 после сохранения очередного байта указывает на следующий символ

while( *p1++ = *p2++ )
	{ 
		printf("%c", *(p1-1));
	}
Ну или так:
cout << *(p1-1);

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

• Отредактировал: Лысков Игорь Витальевич (Старший модератор)
• Дата редактирования: 14.06.2017, 16:50

Хватов Сергей
Академик

ID: 20764

# 9

 +1 
 
= общий = | 14.06.2017, 17:00 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Строго говоря, это не совсем так. Гарантируется только то, что адреса значений источника и приёмника будут вычислены до того, как будут подвинуты указатели. Но компилятор все остальные действия волен задавать в любом порядке. Например, сначала будет присвоено, а уже потом подвинуты оба указателя.
В данном случае это несущественно, но всякие трюки (например, когда в обеих частях один и тот же указатель) могут плохо кончится.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 10

= общий = | 14.06.2017, 17:05 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Хватов Сергей:

В трюкачество вдаваться не будем... smile

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 11

= общий = | 14.06.2017, 17:28 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Аааа...понятно, использовать такой вариант не буду, раз нет уверенности в том, что находится в данный момент по адресу и что думает по этому поводу конкретный компилятор. smile
Лучше проще, но лучше!

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.14646 сек.

© 2001-2017, Портал RFPRO.RU, Россия
Авторское право: ООО "Мастер-Эксперт Про"
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.41 от 25.02.2017
Бесплатные консультации онлайн