Форум программистов, компьютерный форум CyberForum.ru

Инициализация строки - C++

Восстановить пароль Регистрация
 
 
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 10:47     Инициализация строки #1
Добрый день, такое дело: имеется инициализация
C++
1
char* str1 = "x"; // lvalue - char*, rvalue = const char[2]
такая инициализация есть темное наследие чистого Си, но вместе с этим rvalue приводится к char*

C++
1
const char str2[] = "y"; // lvalue - const char[], rvalue = const char[2]
таким образом, тип const char[] инициализируется типом char[2]

В силу последнего, можно полагать, что:
C++
1
const char str3[] = str2; // lvalue - const char[], rvalue = const char[2]
но происходит ошибка компиляции.

Можете объяснить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.05.2016, 10:47     Инициализация строки
Посмотрите здесь:

C++ Инициализация вектора
Инициализация переменных С++11 C++
C++ Инициализация указателей
C++ Инициализация массива. Длина строки
Инициализация дерева C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
16.05.2016, 10:57     Инициализация строки #2
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Можете объяснить?
"y" - строковой литерал, str2 - просто строка. Первым массив символов инициализировать можно, вторым - нет.
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 18:23  [ТС]     Инициализация строки #3
Renji, а что вобще есть строковый литерал по своей сути? Ведь "строковый литерал представляет последовательность символов, которые вместе образуют строку с завершающим нулем.".

Под это определение вполне может подпадать str3. И как вобще компилятор различает, производится ли инициализация "строковым литералом", ведь по сути просто сопоставляются типы (и там, и там - const char[]) и происходит инициализация. Ведь строковый литерал имеет тип const char[]
SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 972
16.05.2016, 18:33     Инициализация строки #4
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
const char str3[] = str2;
str2 - это указатель. разница между char *str и char arr[] - str можно "повернуть" на что угодно, те можно указывать на другое место в памяти или вообще в никуда str = 0, но менять содержимое нельзя. в случае char arr[] с точностью до наоборот указатель arr никуда кроме своего массива указывать не может, те присвоить ему что-либо нельзя, но зато можно менять содержимое области памяти.
thebat_ua
1 / 1 / 0
Регистрация: 04.04.2016
Сообщений: 22
16.05.2016, 18:43     Инициализация строки #5
На сколько я понимаю
C++
1
const char str2[] = "y"
равнозначно
C++
1
const char str2[] = {'y','\0'}
то есть масив с двумя элементами.
На сколько я знаю в c++ array = array2 нельзя делать.(разве что это клас контейнера, где перегружен оператор ==)

правильно (с точки зрения синтаксиса, а не логики) было бы наверное вот так

C++
1
const char str3[] = {str2[0], str2[1]}
SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 972
16.05.2016, 18:44     Инициализация строки #6
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
такая инициализация есть темное наследие чистого Си
только светлое настоящее С++ близко не подпускают к написанию ядра Linux, например, и много еще чего ответственного
Торвальдс о С++
еще в догонку
если почитать что говорили о С++ Столман, Кен Томпсон, Ритчи, то уверен сильно удивитесь.
лично мне С++ не нравится, я изучаю Java, а где Java "очевидно проседает" или нужны системные функции типа, то встраиваю Си код в Java.
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
16.05.2016, 18:54     Инициализация строки #7
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Renji, а что вобще есть строковый литерал по своей сути?
Явно прописанная в коде константа. А str2 это уже область памяти в которую мы ее помещаем.

Добавлено через 10 минут
Цитата Сообщение от SergioO Посмотреть сообщение
только светлое настоящее С++ близко не подпускают к написанию ядра Linux, например, и много еще чего ответственного Торвальдс о С++
Спросите Торвальдса почему его любимый Си до сих пор не позволяет безымянные аргументы функций и требует struct перед именем структуры даже вне декларации этой самой структуры. Спросите его какими веществами надо было упороться, чтобы void func() не было синонимом void func(void) (первое можно вызвать как func(1,2,3,4)).

Он просто новый язык учить не хочет. Все остальное - рационализация позыва "нафиг это новое, посижу на старом с рудиментами пятидесятилетней давности".
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 18:58  [ТС]     Инициализация строки #8
Цитата Сообщение от Renji Посмотреть сообщение
А str2 это уже область памяти
но ведь в данном случае литерал тоже находится в области памяти, в которую этот литерал был помещен
C
1
2
3
4
5
6
7
#include <stdio.h>
 
int main()
{
    printf("%p", "x");
    return 0;
}
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
16.05.2016, 19:03     Инициализация строки #9
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
но ведь в данном случае литерал тоже находится в области памяти, в которую этот литерал был помещен
Де-факто да, но синтаксически "x" и str2 отличаются. Я так полагаю, очередной привет из Си или его предшественников, оставшийся в целях обратной совместимости.
SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 972
16.05.2016, 19:16     Инициализация строки #10
Ferrari F1, если считаете Си темным наследием и склоняетесь к С++, то правильнее использовать string и string.c_str(), когда нужно преобразовать строку к char* с завершающим '\0'.

C
1
2
char* str1 = "x";
const char str2[] = "y";
это Си чистой воды
в С++
C++
1
2
3
4
5
6
7
8
const std::string str = "Constant";
std::string s; //объявили строку
std::getline(cin, s); //считали строку из потока
int N = s.length(); //длина строки
//"пробежались" по всем символам 
for (auto c: s){
}
// поиск подстроки, замена и тд
это светлое наследие С++
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 19:21  [ТС]     Инициализация строки #11
Цитата Сообщение от SergioO Посмотреть сообщение
считаете Си темным наследием
темным наследием чего?

Написав
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
такая инициализация есть темное наследие чистого Си
имелось в виду инициализация с игнорированием квалификатора типа, что не является правильным, язык целиком я не затрагивал
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
16.05.2016, 19:26     Инициализация строки #12
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
темным наследием чего?
Темным наследием C++. C++ сделан на основе C и некоторые странности получил по наследству. В частности, невозможность копирования массивов через str3=str2 (при том что если запихать массив в структуру, он прекрасно копируется).
Ferrari F1
16.05.2016, 19:31  [ТС]
  #13

Не по теме:

Цитата Сообщение от Renji Посмотреть сообщение
Темным наследием C++
Си не может быть наследием С++, т.к. первый появился раньше

SergioO
 Аватар для SergioO
89 / 178 / 61
Регистрация: 13.12.2015
Сообщений: 972
16.05.2016, 19:41     Инициализация строки #14
Цитата Сообщение от Renji Посмотреть сообщение
массивов через str3=str2
например в java тоже с копированием массивов "батва" ))
надо циклом for () для копирования проходить, например, поэтому С++ не одинок.
зато в С++ можно
C++
1
array<Elem,N> arr = arr2
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 19:49  [ТС]     Инициализация строки #15
Цитата Сообщение от Renji Посмотреть сообщение
при том что если запихать массив в структуру, он прекрасно копируется
скорее всего, копируются байты одной структурной переменной в другую, безразлично от внутреннего содержания. Механическое копирование байтов, короче говоря.
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
16.05.2016, 19:50     Инициализация строки #16
какие предшественники, какое наследие... вы о чем?
строковый литерал - это термин, которым обзывают последовательность символов, заключенных в двойные кавычки. все. в выражении
C++
1
char* str1 = "x";
str1 - это переменная
"x" - строковый литерал
эти понятия нужно различать
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 19:55  [ТС]     Инициализация строки #17
Цитата Сообщение от retmas Посмотреть сообщение
последовательность символов
эта последовательность символов представляет из себя символьный массив с нулем терминатором. таким образом, тип указатель на char инициализируется типом константный массив типа char.

Следовательно, всякий константый массив типа char по идее должен являться инициализатором
retmas
Жарю без масла
803 / 685 / 143
Регистрация: 13.01.2012
Сообщений: 1,580
16.05.2016, 20:00     Инициализация строки #18
исчо раз читаем выше, что такое строковой литерал

Добавлено через 1 минуту
подумайте, что есть литерал:
C
1
#define STR "str"
Добавлено через 2 минуты
исчо более доходчиво:
строковой литерал - набор буковок в тексте, заключенных в двойные кавычки
Renji
1535 / 983 / 240
Регистрация: 05.06.2014
Сообщений: 2,963
16.05.2016, 20:01     Инициализация строки #19
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
скорее всего, копируются байты одной структурной переменной в другую, безразлично от внутреннего содержания. Механическое копирование байтов, короче говоря.
Копируется то, что указано в конструкторе копирования. Хотя да, при программировании в стиле Си, конструктор копирования в большинстве случаев сводится к побайтовому копированию.
Цитата Сообщение от retmas Посмотреть сообщение
str1 - это переменная
"x" - строковый литерал
эти понятия нужно различать
const int N=10 - константа.
10 - числовой литерал.
Эти понятия надо различать - int array[10] внутри структуры разрешим, а int array [N] нельзя. А если нельзя, но очень хочется, то впилим #define N 10. Он, правда, нагадит во все неймспейсы, но это мелочи. Здравствуй простой и элегантный Си, давно не виделись.

Нет, не нужно их различать. По возможности литерал, константа и переменная должны быть взаимозаменяемы.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.05.2016, 20:02     Инициализация строки
Еще ссылки по теме:

Инициализация вектора C++
Инициализация матрицы C++
Инициализация C++

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

Или воспользуйтесь поиском по форуму:
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,912
Записей в блоге: 1
Завершенные тесты: 1
16.05.2016, 20:02  [ТС]     Инициализация строки #20
Цитата Сообщение от retmas Посмотреть сообщение
последовательность символов, заключенных в двойные кавычки
это для человека очевидно, что строковый литерал - это тупо закавыченный текст, т.е. мы определяем лишь визуально.
А с колокольни компилятора этот заковыченный текст - символьный массив.
Yandex
Объявления
16.05.2016, 20:02     Инициализация строки
Ответ Создать тему
Опции темы

Текущее время: 03:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru