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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.63
Snaiffer
2 / 2 / 0
Регистрация: 13.03.2011
Сообщений: 18
#1

Что происходит при char *str = ""? - C++

09.10.2012, 13:54. Просмотров 4436. Ответов 15
Метки нет (Все метки)

Объясните, пожалуйста, что происходит при
C++
1
const chat *str = "hello"
Т.е. тут явно у нас присутствует только объявления указателя str, но как выделяется память для строки "hello"?

И второй вопрос:
Почему компилятор выводит предупреждение, если написать предыдущую строчку без const?
C++
1
chat *str = "hello"
C++
1
warning: deprecated conversion from string constant to ‘char*[-Wwrite-strings]
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.10.2012, 13:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Что происходит при char *str = ""? (C++):

Что происходит когда например "char* g="fdgag";"? - C++
Сабж. Я понял создается динамический массив с помощью malloc() и поэтому к нему не обратится таким образом: g. Я прав?

Ошибка 6 error C2664: strtok: невозможно преобразовать параметр 1 из "const char *" в "char *" - C++
string s = "555 44 55 66";//размер строки заранее неизвестен char* p = strtok(s.c_str(), ' '); не нравится такое...

error C2664: strcmp: невозможно преобразовать параметр 1 из "char (*)[20]" в "const char *" - C++
for(int i = 0; i< 5; i++) { wr_struc (list); if (strcmp(&list.Sostav,osn_sostav)==0 && strcmp(&list.MestoVkomande,attack)==0...

ошибка при роботе с файлом "expresion str! = NULL" - C++
не знаю почему, но выдает постоянно эту ошибку вот нужная часть кода char pass; FILE *file; file=fopen("pas.txt","r+t"); ...

Вывести на экран фразу "Мне n лет", учитывая что при некоторых значениях n слово "лет" надо заменить на "год" - C++
дано натуральное число n. Вывести на экран фразу "Мне n лет", учитывая что при некоторых значениях n слово "лет" надо заменить на "год" или...

IntelliSense: несовместимые типы операндов ("char" и "const char *") - C++
привет всем! при таком коде: void main() { ifstream fin; ofstream fout; fin.open("input.txt"); ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
-=ЮрА=-
Заблокирован
Автор FAQ
09.10.2012, 14:09 #2
Цитата Сообщение от Snaiffer Посмотреть сообщение
const char *str = "hello"
- (конечно если есть ; вконце этой строки) - это объявление строкового литерала и такая запись равносильна такой
C++
1
const char str[] = "hello"
В результате такого объявления компилятор выделяет память под число символов в кавычках и к этому блоку автоматически пристыковывает \0 (т.е обнулять конец не следует)

Цитата Сообщение от Snaiffer Посмотреть сообщение
char *str = "hello"
ругается потому как строковые литералы подразумевают константность но поверь и такой код отработает(правда он не кашерен с точки зрения компиляторов строго работающих в стандарте)
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
09.10.2012, 20:33 #3
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
он не кашерен с точки зрения компиляторов строго работающих в стандарте
Я бы сказал, что он не кошерен с точки зрения программиста, который забьёт на это предупреждение, а потом попробует изменить получившуюся "неконстантную строку". Поэтому советовал бы обращать внимание на сообщения компилятора.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
это объявление строкового литерала и такая запись равносильна такой
Не согласен с этим. В первом случае строка будет расположена в read-only памяти, и в момент присваивания указатель сохранит только адрес этих данных. Во втором же случае строку будет скопирована в массив (да, имеет место массив, а не указатель), сама строка скорее всего даже не сохранится в read-only памяти. Попытка изменить строку в первом случае (посредством снятия константности, например), скорее всего, приведёт к попытке программы, во втором же случае не должна вызвать проблем.
-=ЮрА=-
Заблокирован
Автор FAQ
09.10.2012, 20:49 #4
Цитата Сообщение от silent_1991 Посмотреть сообщение
Во втором же случае строку будет скопирована в массив (да, имеет место массив, а не указатель), сама строка скорее всего даже не сохранится в read-only памяти.
- любой массив это совокупность ячеек области памяти другое дело что да конст компилятор может запихнуть в страницы со служебной адресацией, а не конст зашить в общедоступную память, но в любом случае есть массив и указателем на него является str. Так что возможно различие в адресации, а так одно и тоже (теже яйца но с боку)
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
09.10.2012, 20:53 #5
-=ЮрА=-, согласен, с точки зрения программиста, которому надо просто где-то сохранить строку, известную на стадии компиляции, разницы никакой. Но о подобных различиях стоит знать хотя бы потому, что константная строка будет загружена вместе с приложением (поскольку хранится в исполняемом файле), а для заполнения массива вызываются подряд несколько (и довольно много для большой по объёму строки) операций записи в память. Это надо иметь ввиду.
С другой стороны, вряд ли кто-то будет "Войну и мир" таскать в исходнике и сохранять в массив, так что это совершенно не критично.
-=ЮрА=-
Заблокирован
Автор FAQ
09.10.2012, 21:02 #6
Цитата Сообщение от silent_1991 Посмотреть сообщение
С другой стороны, вряд ли кто-то будет "Войну и мир" таскать в исходнике и сохранять в массив, так что это совершенно не критично.
- именно.
При этом любой компилятор имеет жестко лимитированный максимальный объём хранимых конст данных - так что при попытке сохранить как конст текстовик Войны и мира вот таким труюком скажем
char * str;
#include "VoinaImir.txt";
в котором будет что то вроде str = (char *)"........30 Мб книги";
после линковки мы увидим замечательное ничем неубиваемое сообщение от компилятора что памяти не хватает и чтобы не делали, всё равно упрёмся в макс размер 5-6 Мб и всё.
silent_1991
Эксперт С++
4963 / 3039 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
09.10.2012, 21:11 #7
-=ЮрА=-, да это-то понятно, "Война и мир" давно является собирательным названием, я его для пущего эффекта применил))
Evg
Эксперт CАвтор FAQ
17621 / 5845 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
09.10.2012, 21:13 #8
Цитата Сообщение от Snaiffer Посмотреть сообщение
Объясните, пожалуйста, что происходит при
http://www.cyberforum.ru/blogs/18334/blog97.html далее раздел 4

Цитата Сообщение от Snaiffer Посмотреть сообщение
Почему компилятор выводит предупреждение, если написать предыдущую строчку без const?
Там же, раздел 5.2

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
это объявление строкового литерала и такая запись равносильна такой
Бред сивой кобылы. Можешь на это не отвечать, т.к. спорить с тобой всё равно не буду
panicwassano
09.10.2012, 21:14
  #9

Не по теме:

народ ну вы в личку рамситесь

-=ЮрА=-
09.10.2012, 21:16
  #10

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
-=ЮрА=-, да это-то понятно, "Война и мир" давно является собирательным названием, я его для пущего эффекта применил))
да, я понял это, я умею смеяться
Своим постом я хотел лишний раз пользователям подчеркнуть что существует предел размеру конст переменных и чтобы они имели это ввиду. С другой стороны тома войны и мира можно прекрасно сохранить ресурсами приложения, правда это тема уже отдельной беседы и к данной теме имеет лишь факультативное отношение...

rangerx
1933 / 1542 / 141
Регистрация: 31.05.2009
Сообщений: 2,912
09.10.2012, 22:02 #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
это объявление строкового литерала и такая запись равносильна такой
А эти записи тоже равносильны?
C++
1
2
3
4
5
6
7
8
9
10
11
const char* func1() {
 
    const char* s = "text";
    return s;
}
 
const char* func2() {
 
    const char s[] = "text";
    return s;
}
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
09.10.2012, 22:18 #12
Имя массива в любом случае константный указатель, в то время как указатель на константные данные можно изменить, что бы он указывал на другую область памяти.
Snaiffer
2 / 2 / 0
Регистрация: 13.03.2011
Сообщений: 18
12.10.2012, 10:27  [ТС] #13
Благодарю всех за разъяснение данного вопроса.
Особенно благодарен Evg. Его статья дает исчерпывающию информацию по топику.
Тему можно считать закрытой.
-=ЮрА=-
Заблокирован
Автор FAQ
12.10.2012, 12:04 #14
rangerx, вот такие записи идентичны,
C++
1
2
const char* s1  = "text";
const char s2[] = "text";
речь шла именно об этом
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main()
{
    const char* s1  = "text";
    const char s2[] = "text";
    cout<<s1<<endl;
    cout<<s2<<endl;
    return 0;
}
http://codepad.org/TDMqKPXw
Output:
1
2
text
text
Добавлено через 5 минут

Не по теме:

rangerx, жду разъяснений раз уж начали детальный разбор...

ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
12.10.2012, 12:20 #15
-=ЮрА=-, Неверно. Они не могут быть идентичны, потому что первое - просто присваивание адреса строкового литерала, а второе - создание массива и копирование символов из строкового литерала в него.

http://liveworkspace.org/code/f503ca...4f0e86a7b1cd4f

C++
1
2
3
4
5
6
7
8
9
10
11
const char* func1() {
 
    const char* s = "text";
    return s;
}
 
const char* func2() {
 
    const char s[] = "text";
    return s;
}
Какой код корректный, если перефразировать rangerx. Или оба корректны?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.10.2012, 12:20
Привет! Вот еще темы с ответами:

Не открывается библиотека 'stdafx.h' и "char" не работает с параметром "char*" - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;cstring&gt; using namespace std; int one(char fam) //...

Невозможно преобразовать параметр 2 из "char" в "const char *" - C++
Ошибка strcpy: невозможно преобразовать параметр 2 из &quot;char&quot; в &quot;const char *&quot; //удаления из первой строки всех символов, встречающихся...

Несовместимые типы операндов "char" и "const char*" - C++
В чем проблема?

Error C2440: return: невозможно преобразовать "const char *" в "const char (&)[6]" - C++
Вроде все правильно а все равно не работает. Подскажите в чем ошибка #include &lt;iostream&gt; template&lt;typename T&gt; inline const T...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
12.10.2012, 12:20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru