Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 26.02.2020
Сообщений: 5

Проблема со строками символов типа char

26.02.2020, 04:15. Показов 2353. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Простите, но так и не могу понять, почему так можно:

char s[100] = "123";

а так нельзя:

char s[100];
s = "123";

Возникает следующая ошибка компиляции:

[Error] incompatible types in assignment of 'const char [4]' to 'char [100]'

Но, ведь, в первом случае тоже происходит назначение: 'const char [4]' to 'char [100]'
У кого хватит терпения, прошу пояснить.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.02.2020, 04:15
Ответы с готовыми решениями:

Работа со строками типа char
Все доброго времени суток! Есть программа, представляет из себя меню, в котором есть процесс работы с типом char. В данном процессе...

проблема с переменной типа char
int count(char a){ int c=0; int words=0; while(a!='\0'){ if(a==' ')++words; } return words; } очень примитивный вопрос... ...

проблема с массивом типа CHAR
нужно выполнить функцию fopen() . которая кушает на вход указатель на массив char в качестве пути к файлу ну и режим работы с файлом. ...

10
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
26.02.2020, 09:32
Лучший ответ Сообщение было отмечено MaxGor как решение

Решение

Цитата Сообщение от MaxGor Посмотреть сообщение
Но, ведь, в первом случае тоже происходит назначение: 'const char [4]' to 'char [100]'
нет.
в первом случае это инициализация массива.
https://en.cppreference.com/w/... ialization
а во втором присваивание одному массиву другого. что запрещено.
используйте std::copy/memcpy/strcpy/etc.
1
Just Do It!
 Аватар для XLAT
4188 / 2643 / 654
Регистрация: 23.09.2014
Сообщений: 8,874
Записей в блоге: 3
26.02.2020, 09:33
если сильно хочется можно так:
C++
1
2
3
const char* s = "123";
...
            s = "321";
0
0 / 0 / 0
Регистрация: 26.02.2020
Сообщений: 5
26.02.2020, 17:51  [ТС]
Большое спасибо за ответ и ссылку. Я внимательно прочитал. Но вопрос остался.
В выражении

char s[100] = "123";

в любом случае сначала создается то, что слева от знака присваивания, а потом ему присваивается то, что справа.
При инициализации на момент присваивания слева уже должен быть создан массив s[100],
а потом ему присваивается значение "123". Кстати, еще остается вопрос: должны ли мы трактовать значение "123"
как массив? Да, это константная последовательность символов, но массив ли?
И тогда, простите, все-таки остается все тот же вопрос: почему первый случай допустим, а второй - нет?

случай 1
char s[100] = "123";

случай 2
char s[100];
s = "123";

Кстати, мое мнение таково, что оба эти случая не должны быть допустимыми. Строго говоря, массив
char s[100]
не является строкой, а остается массивом отдельных однотипных сущностей - символов.
Работать с массивом можно только по индексам его элементов.
Я долго пытаюсь разобраться в этих тонкостях, и мое мнение таково, что в таком строгом
формально-лингвистическом построении, как язык программирования,
просто не должно быть подобных двусмысленностей.
Прошу, кому не лень, высказать свое мнение. Мне очень важно мнение специалистов.
Заранее благодарен.

Добавлено через 12 минут
В дополнение к предыдущему (не успел добавить в основной текст).

В первом случае s является указателем на первый элемент созданного массива.
Во втором случае s также является указателем на первый элемент массива. Так в чем же разница?
Мы, ведь, можем делать так, как подсказал здесь уважаемый XLAT:

char* s = "123";
...
s = "321";
0
0 / 0 / 0
Регистрация: 26.02.2020
Сообщений: 5
01.03.2020, 22:05  [ТС]
Здравствуйте. Все-таки очень прошу продолжить эту тему и внести ясность. Такие фундаментальные вопросы требуют понимания. Прошу помочь мне разобраться.
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4573 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
01.03.2020, 23:26
MaxGor, давайте я попробую объяснить
Случай 1: char s[100] = "123";
Здесь происходит инициализация массива из 100 символов таким образом, что первые три - '1', '2', '3'. Все последующие - двоичные нули. И, что самое главное, это происходит во время компиляции программы!
Случай 2: s = "123";
Эта операция происходит во время выполнения программы! И подразумевает, что s - указатель, т.е. переменная, в которой лежит адрес строки char.
Тут есть ещё такая деталь. Строка, заданная подобным образом, считается константой и, к слову, в коде размещается в сегменте readonly.
Поэтому строковый литерал можно присваивать только указателям типа const char*
На что и было указано XLAT-ом

Добавлено через 8 минут
И ещё. В первом случае s не является указателем, а массивом из 100 элементов.
Хотя и численно равно адресу первого элемента.
0
0 / 0 / 0
Регистрация: 26.02.2020
Сообщений: 5
02.03.2020, 00:09  [ТС]
Уважаемый liv.
Большое спасибо. Вы натолкнули меня на новый взгляд на проблему.
Но, все-таки. Опять, возвращаемся к случаю 1:
Случай 1: char s[100] = "123";
Полностью согласен с Вами, что инициализация происходит во время компиляции. Однако, при запуске программы, все ее объекты распределяются в памяти, то есть, ничем не отличаются от динамически распределяемых, только распределяются в памяти без нашего ведома сразу при запуске программы. (А иначе, как с ними работать?) И вот здесь (простите за настойчивость непонятливого) s опять-таки есть указатель на массив char[100]. Поэтому после запуска программы, т.е. уже при ее выполнении, этот объект s , по сути становится тем же, что и в случае 2:
случай 2
char s[100];
s = "123";
который считается незаконным.

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

Поэтому прошу Вашей помощи отобразить рассматриваемые случаи в виде схем (квадратики, стрелочки) для этапа компиляции и для этапа выполнения программы, после ее загрузки в память и размещения в памяти всех ее объектов.

Очень благодарен Вам за поддержку этой беседы.
0
Just Do It!
 Аватар для XLAT
4188 / 2643 / 654
Регистрация: 23.09.2014
Сообщений: 8,874
Записей в блоге: 3
02.03.2020, 08:14
MaxGor,

Нужно различать константный указатель и указатель на константу.

1.
C++
1
char s[] = "qwerty";
Константный указатель: можно менять содержимое объекта, но нельзя менять значение самого указателя.

2.
C++
1
const char* p = "12345";
Указатель на константу: нельзя менять содержимое объекта, на который указывает указатель.
Содержимое строки размещаяется в памяти "READ ONLY"

3.

C++
1
const char * const с = "987abc";
Константный указатель на константу: совокупность первых двух.

Теперь там где вы пишете про указатель
добавьте термин КОНСТАНТНЫЙ(ая, ое) по смыслу (либо константный сам указатель, либо константное содержимое).

После такого уточнения свойства тех или других типов строк, можно надеется, станут очевидными.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
02.03.2020, 08:41
Цитата Сообщение от MaxGor Посмотреть сообщение
При инициализации на момент присваивания
Вы так неосторожно манипулируете понятиями "присваивание" и "инициализация", что это никуда не годится.
Следует их четко различать.
Инициализация - это задание значения объекту в процессе его создания.
Присваивание - это операция над уже живым объектом, смена его значения на новое.
Лучше всего видна разница на константах:
C++
1
2
3
const int v = 10; // это инициализация, задать значение при создании константы - разрешено
 
v = 12; // это присваивание, здесь оно запрещено, т.к. нельзя менять константный объект
Таким образом, фраза "При инициализации на момент присваивания" лишена смысла. И пусть вас не смущает, что в обоих случаях используется один и тот же знак `=`: его смысл меняется в зависимости от контекста (издержки минималистичности синтаксиса).
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
02.03.2020, 10:35
MaxGor, отвлекись от строк. твой вопрос не про строки, а про массивы.
он полностью аналогичен вопросу
C++
1
2
3
4
5
//почему так можно
int array[]={1,2,3,4};
//а так нельзя
int array[100];
array={1,2,3,4};
0
0 / 0 / 0
Регистрация: 26.02.2020
Сообщений: 5
02.03.2020, 21:48  [ТС]
Здравствуйте. Ситуация значительно прояснилась для меня. Большое спасибо всем, кто нашел время и проявил терпение для разъяснений.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.03.2020, 21:48
Помогаю со студенческими работами здесь

Условие типа if( масив типа char[x] [y] != переменная типа char) не срабатывает
Создал функцию ChangeWay(). Все, кроме if(map !=ar) (обе переменные типа char) работает нормально, а когда выполнение доходит до этого...

работа с массивом символов типа Char
Пытаюсь разобраться со следующим заданием. Допустим есть некоторая строка большой длины, требуется удалить все пробелы справа. Пытаюсь...

Ввод символов в переменную типа char
Почему после ввода больше 1-го символа выбивает default? #include <iostream> #include <conio.h> #include <math.h> using...

Удаление символов из строки типа char
Существует ли какая-либо функция для удаления элементов строки char? Или придется "сдвигать" массив в цикле? Может быть есть еще...

Датчик случайных символов для типа Char
Здравствуйте, как можно создать функцию для ввода случайных символов(тип char), чтобы заполнить массив?


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru