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

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

23.12.2019, 12:00. Показов 4486. Ответов 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
12930 / 6798 / 1819
Регистрация: 18.10.2014
Сообщений: 17,198
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru