Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518

Почему std::cout выводит только 1 символ?

23.12.2019, 12:00. Показов 4643. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет
Почему выводит только 1 символ?

C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
    char ar[] = "12345";
    volatile char* p = ar;
    std::cout << "'" << p << "'\n";
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.12.2019, 12:00
Ответы с готовыми решениями:

Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит второй cout
Подскажите почему после первого cout программа не останавливается для ввода строки, а выводит второй cout. Это фрагмент со структурами: ...

Почему функция putchar(); выводит только первый символ?(Короткий код)
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; int main() { int c; c=getchar(); putchar(c); getch(); }

Почему gcc ругается на std::cout?
Проблема такая: работаю на Mac, установил Xcode, запускаю gcc в командной строке. Имеется элементарная программка: #include...

27
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,223
23.12.2019, 12:05
Лучший ответ Сообщение было отмечено hoggy как решение

Решение

Цитата Сообщение от eva2326 Посмотреть сообщение
Почему выводит только 1 символ?
Потому что оператор вывода строки требует на вход const char *. Ваш указатель типа volatile char* невозможно преобразовать к const char * - из-за volatile. Поэтому оператор вывода строки здесь неприменим. Вместо него здесь срабатывает другой подходящий оператор: оператор для вывода значений типа bool.

Так что у вас на самом деле нет никакого "выводит только 1 символ". Ни одного из ваших символов этот код не выводит вообще. Он выводит значение true, которое по умолчанию выводится как 1. Вы можете поменять строку на "abc", но выводиться все равно будет 1.
5
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 12:35
TheCalligrapher,
А какая связь между volatile и bool? На каком основании происходит подобное преобразование?
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
23.12.2019, 13:03  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ваш указатель типа volatile char* невозможно преобразовать к const char * - из-за volatile.
а по-моему очень даже возможно...

C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
    char arr[] = "abc";
    volatile char* text = arr;
    
    const char* out = (const char*) text;
    
    std::cout << out << '\n';
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 15:03
Цитата Сообщение от Undisputed Посмотреть сообщение
А какая связь между volatile и bool? На каком основании происходит подобное преобразование?
Любой указатель конвертируется в bool неявно. У char volatile * связь не с bool, а с тем, что стандартная перегрузка для char const * не подходит, потому что cv-квалификаторы не могут сниматься неявно.
http://eel.is/c++draft/conv.bool#1
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 15:13
DrOffset,
Спасибо, я почитал об это на SO, но до конца не понял почему это так. В bool можно, а в const char* нельзя, почему?
Нашёл информацию что чтение из адреса объектов которые определены как volatile через указатель который не является volatile это UB. Вот думаю может по этой причине неявный каст не проходит... Если причина в этом, то возникает ещё один вопрос, почему подобное чтение должно приводить к UB?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 15:16
Цитата Сообщение от Undisputed Посмотреть сообщение
В bool можно, а в const char* нельзя, почему?
По той же причине, по которой const char * нельзя в char *, volatile, как и const, неявно не снимаются.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 15:28
DrOffset,
Ага, это по правилам так. только вот логика этого правила к сожалению мне не понятна
Когда преобразование из const char* в char* тут логика понятна т.к исходный объект менять нельзя (например, в случае строкового литерала), это ок.
Но какие проблемы может создать преобразование указателя с квалификатором volatile в указатель подобного типа но без volatile?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 15:35
Цитата Сообщение от Undisputed Посмотреть сообщение
Когда преобразование из const char* в char* тут логика понятна т.к исходный объект менять нельзя (например, в случае строкового литерала), это ок.
Но какие проблемы может создать преобразование указателя с квалификатором volatile в указатель подобного типа но без volatile?
Точно такие же. Например, при попытке записи через такой указатель. Т.е. если у нас были причины объявить некую переменную как volatile (например она связана непосредственно с каким-то регистром или зарезервированным участком памяти, который использует аппаратура непосредственно), то использование для доступа к ней обычного, не-volatile, указателя может нарушить все гарантии, которые нам дает volatile для этой переменной.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 15:48
If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with a non-volatile-qualified type, the program behavior is undefined.
Нашёл на SO, вроде из стандарта. Сейчас пока не могу точно проверить, пишу с телефона, копаться в стандарте не удобно...)

Добавлено через 13 минут
DrOffset,
Спасибо что старался, но до меня все равно не дошло ))
По сути volatile это барьер для оптимизации, и если передать этот адрес в оператор вывода для чтения как это происходит для обычных строк то проблем быть не должно, контекст ведь поменяется. Там где мы сформировали volatile переменную будет барьер, а в операторе вывода просто вывод данных (тоже проблем нет). А если бы в операторе была бы запись, то полагаю тоже не было бы проблем. Просто в барьерном контексте считались бы обновлённые данные. Где и что тут может нарушиться я не понял ;( надеюсь смог передать свою мысль
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 16:22
Цитата Сообщение от Undisputed Посмотреть сообщение
адрес в оператор вывода для чтения как это происходит для обычных строк то проблем быть не должно, контекст ведь поменяется.
Ты должен понять, что оператор вывода и его конкретные действия тут не при чем. Правила, которые мы обсуждаем, введены не из-за оператора вывода же.

Добавлено через 15 минут
Цитата Сообщение от Undisputed Посмотреть сообщение
до меня все равно не дошло
Знаешь почему так происходит? Потому что ты пытаешься налету понимать концепции, которые надо усваивать сидя в тишине и желательно при этом думая, а не дискутируя на форуме и не читая ответы с телефона, сидя в транспорте или еще где

volatile - это в первую очередь отказ компилятора от любых предположений насчет этой памяти. Одно и таких предположений - это неизменность извне, как следствие - кеширование:
Вот пример:
C++
1
2
3
4
int mul(volatile int * p)
{
    return *p * *p;
};
Этот код, благодаря отказу от предположения, что *p не может измениться прямо в процессе выполнения функции (например изменяется прерыванием), делает чтение из *p каждый раз, при каждом обращении.
А эта функция:
C++
1
2
3
4
int mul(int * p)
{
    return *p * *p;
};
может закешировать значение, и в дальнейших операциях использовать его, а не запрашивать его каждый раз через указатель.

Понятно, что сам по себе этот код не имеет особого смысла, однако он демонстрирует разницу и в некоторых задачах эта разница существенна (т.е. когда нам нужно каждый раз получать самое актуальное значение, которое есть по указателю).
2
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 16:41
DrOffset,
Думаю я понял. Во втором случае значение по адресу p внутри функции mul может быть прочитано всего 1 раз несмотря на то что у нас два чтения. но где то в другом потоке значение p может быть изменено и по идее второе чтение должно дать результат отличный от первого чтения. Но второго чтения не будет ибо данные закешированы. О таком кейсе я не подумал (в голове крутился пример только с одним чтением поэтому я не видел проблем).

Кстати раз уж разговор о volatile, скажи плиз на что он влияет когда указывается для метода (там где noexcept)? Аргументы/поля/локальные переменные/что-то другое?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 16:43
Цитата Сообщение от Undisputed Посмотреть сообщение
на что он влияет когда указывается для метода
На this влияет
С тех же позиций, как на любой другой указатель.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 16:53
DrOffset,
Спасибо. А какой в этом смысл? Поля могут быть закешированы как в предыдущем примере?
И говоря про this имеется ввиду обращение к полям с явным использованием this или для обращений без явного использования this volatile тоже будет действовать?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 16:59
Цитата Сообщение от Undisputed Посмотреть сообщение
явным использованием this или для обращений без явного использования this
Это одно и то же Синтаксический сахар.

Цитата Сообщение от Undisputed Посмотреть сообщение
Поля могут быть закешированы как в предыдущем примере?
Да, могут.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 17:08
DrOffset,
Спасибо. Если ты ещё поведаешь суть const volatile вместе то было бы круто )
Один говорит что данные могут быть изменены а другой что не могут быть изменены. Я нахожу это противоречивым ))
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2019, 17:14
Цитата Сообщение от Undisputed Посмотреть сообщение
Один говорит что данные могут быть изменены а другой что не могут быть изменены.
Один говорит, что данные могут быть изменены извне, а другой, что данные не могут быть изменены из программы.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 17:29
DrOffset,
Интересно. Но разве можно поменять значения вне программы? Если да, то как (хотя бы в общих чертах)? Полагаю это может пригодится в каких то implementation-defined фичах
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
23.12.2019, 17:31  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
int mul(int * p)
{
    return *p * *p;
};
может закешировать значение
Даже если и закэширует, что с того?
Вы привели пример ситуации, когда ни волатильность, ни кэширование никак не влияют ни на логику работы самой функции, ни на итоговую логику вообще всей остальной программы. Можно просто считать, что компилятор сумел улучшить код функции так хорошо, что она начала работать со скоростью света, и значения попросту не успевают изменяться.

Цитата Сообщение от Undisputed Посмотреть сообщение
почему подобное чтение должно приводить к UB?
Волатильность используется тогда, когда значения данных не просто могут, а должны изменяться откуда то извне. На этом основывается логика работы программы.
C++
1
2
3
4
5
6
// значение по адресу p не просто может, оно обязано изменяться извне
while(*p != EXIT) 
{
    // основная работа
    ...
}
Если снять волатильность, тогда компилятор сможет закэшировать *p, и грош цена такому циклу.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
23.12.2019, 17:52
eva2326,
По факту если на момент второго чтения значение на которое указывает p будет другим (отличным от первого чтения), то этот код не даст корректный результат (без volatile)

А мой вопрос DrOffset у был немного другой )

Добавлено через 16 минут
DrOffset,
Нашёл пример. const volatile вместе может использоваться например для доступа к разделяемой памяти в режиме чтения
При этом для других процессов эта разделяемая память может быть вполне модифицируемой
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.12.2019, 17:52
Помогаю со студенческими работами здесь

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++ 2005 Express Edition. Образ диска...

Почему cout не выводит первым 0?
Напишите программу, которая запрашивает двузначное число и выводит его цифры в обратном порядке. #include &lt;iostream&gt; using...

Cout 16х выводит почему?
#define _CRT_SECURE_NO_WARNINGS #include &lt;iostream&gt; using namespace std; class MyString { private: char* Buffer; ...

Cout выводит только первые 3-4 символа
Код записывает несколько слов в два двоичных файла, потом записывает их из файла в два указателя и должен выводить их на экран, но выводит...

В чем разница std::cout и просто cout?
Ребят ,подскажите на простом языке для чайников . В чем разница std::cout и просто cout?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru