Перейти к содержимому

Const char c что это

  • автор:

Многоликий const

Ключевое слово const — одно из самых многозначных в C++. Правильно использование const позволяет организовать множество проверок ещё на этапе компиляции и избежать многих ошибок из числа тех, которые бывает трудно найти при помощи отладчиков и/или анализа кода.

Первая половина заметки рассчитана скорее на начинающих (надеюсь мнемоническое правило поможет вам запомнить, где и для чего используется const), но, возможно, и опытные программисты смогут почерпнуть интересную информацию о перегрузке методов по const.

Константы и данные

Самый простой случай — константные данные. Возможно несколько вариантов записи:

const int i(1); int const j(1); int const k=1;

Все они правильные и делают одно и тоже — создают переменную, значение которой изменить нельзя.

const int k=1; k = 7; // 

Константы и указатели

При использовании const с указателями, действие модификатора может распространяться либо на значение указателя, либо на данные на которые указывает указатель.

Работает (const относится к данным):

const char * a = "a"; a="b";

Тоже самое и тоже работает:

char const * a = "a"; a="b";

А вот это уже не работает:

char * const a = "a"; a="b"; // 

Если бы операция присвоения изменяла бы не указатель, а данные:

*a = 'Y';

то ситуация была бы диаметрально противоположной.

Существует мнемоническое правило, позволяющее легко запомнить, к чему относится const. Надо провести черту через "*", если const слева, то оно относится к значению данных; если справа — к значению указателя.

Ну и конечно, const можно написать дважды:

const char * const s = "data";

Константы и аргументы/результаты функций

C функциями слово const используется по тем же правилам, что при описании обычных данных.

Константы и методы (перегрузка)

А вот с методами есть одна тонкость.

Во-первых, для методов допустимо использование const, применительно к this. Синтаксис таков:

class A < private: int x; public: void f(int a) const < x = a; // >;

Кроме того, этот const позволяет перегружать методы. Таким образом, вы можете писать оптимизированные варианты методов для константных объектов.

И ещё… я собрался в отпуск… возможно, не смогу ответить на комментарии до понедельника-вторника. Не сочтите за невнимание 🙂

В чем разница const char* и char const*?

Подскажите почему выводится тип в формате char const * __ptr64 а не в том как обычно принято записывать const char* ?
Есть ли между ними хоть какая то разница и почему именно так?

#include #include int main() < const char ch = 'a'; auto c_ptr = &ch; char const* another_c_ptr = &ch; std::cout 
  • Вопрос задан более года назад
  • 454 просмотра

Комментировать
Решения вопроса 0
Ответы на вопрос 1
Developer, ex-admin

Между const char * и char const * - разницы нет. Допустимо использовать обе записи.
Но кроме самих данных, на которые указывает указатель, можно делать константным и сам указатель, как написал Adamos.

Ответ написан более года назад

evgeniy8705

gleendo @evgeniy8705 Автор вопроса

res2001 А есть какая то причина почему компилятор выводит запись именно в таком формате а не так как обычно пишут разработчики, т.е сначала const а потом char*

Adamos

Я, на самом деле, был искренне уверен, что звездочка не играет и это обозначение константного указателя. Просто действительно никогда не сталкивался с такой "вывернутой" записью.

gleendo, Вообще без понятия.
К тому же от компилятора к компилятору строка, возвращаемая typeid().name() может различаться для одного и того же типа. И не факт, что в другом компиляторе const не будет указан в первой позиции.

Разработчики так пишут, видимо, потому что в книжках это наиболее частая запись. Но я встречал и второй вариант в реальных проектах.

Const char c что это

Что нужно. Как правильно копировать значение строк.

Re: Значение string в const char* как.

От: dilmah
Дата: 11.05.11 08:04
Оценка:

Здравствуйте, Alexys, Вы писали:

A>День добрый!
A>Подскажите пожалуйста, как к const char* присвоить значение из string .
A>

A>const char* s_; A>for (int i = 0; i//2. шаг. (в дебагге s_ уже пустой ((( ) A> < A>char* value = "1"; A> string sValue(value); A> s_ = sValue.c_str(); A>> //1 шаг. (дебаггом смотрим, значение занеслом, переменная s_ содержит "1" A>

A>Что нужно. Как правильно копировать значение строк.

у тебя же sValue разрушается на каждой итерации цикла -- указатель который ты из него выделил c_str тоже перестает быть валидным

Re: Значение string в const char* как.

От: Uzumaki Naruto
Дата: 11.05.11 08:05
Оценка:

1. Когда указываете указатеоль — это указатель — это адрес — адрес ячейки памяти — если его не проинициализировать — то он будет указывать х.з. знает куда.
2. Если есть указатель на блок памяти — то вполне логично, что нужно выделить под этот блок память — сделать это можно двумя пустями — на стеке — например char _s[255] или в куче malloc или char * _s = new char [255]
3. копирование строк осуществляется командой strcpy

итак из вашего кода мы получаем

char _s[2]; \\ два байта — первый под 1, другой под \0 — символ конца строки
const char* value = "1";
strcpy (&_s[0], value);

4. зачем вам цикл? что бы выполнить одну и туже операцию 5 раз ?

Re: Значение string в const char* как.

От: Valen
Дата: 11.05.11 08:05
Оценка:

Здравствуйте, Alexys, Вы писали:

A>Что нужно. Как правильно копировать значение строк.
A>

A>std::string s_; A>for (int i = 0; i//2. шаг. (в дебагге s_ уже пустой ((( ) A> < A>char* value = "1"; A> string sValue(value); A> s_ += sValue.c_str(); A>> //1 шаг. (дебаггом смотрим, значение занеслом, переменная s_ содержит "1" A>

Если правильно понял, то нужно сделать deepcopy. или через string, или ручками выделить память для char* s_ и вызвать strcat.

Re[2]: Значение string в const char* как.

От: Alexys
Дата: 11.05.11 08:08
Оценка:

Здравствуйте, Uzumaki Naruto, Вы писали:

UN>1. Когда указываете указатеоль — это указатель — это адрес — адрес ячейки памяти — если его не проинициализировать — то он будет указывать х.з. знает куда.
UN>2. Если есть указатель на блок памяти — то вполне логично, что нужно выделить под этот блок память — сделать это можно двумя пустями — на стеке — например char _s[255] или в куче malloc или char * _s = new char [255]
UN>3. копирование строк осуществляется командой strcpy

UN>итак из вашего кода мы получаем

UN>char _s[2]; \\ два байта — первый под 1, другой под \0 — символ конца строки
UN>const char* value = "1";
UN>strcpy (&_s[0], value);

UN>4. зачем вам цикл? что бы выполнить одну и туже операцию 5 раз ?

Цикл для наглядности.
Под циклом подразумевается хождение по N записям (или в бд или по xml, без разницы) и вытаскивать значения в переменную массива струткуры.
Просто облегчил, для наглядности минимальный пример.

Re: Значение string в const char* как.

От: kvser
Дата: 11.05.11 08:08
Оценка:

Здравствуйте, Alexys, Вы писали:

A>День добрый!
A>Подскажите пожалуйста, как к const char* присвоить значение из string .
A>

A>const char* s_; A>for (int i = 0; i//2. шаг. (в дебагге s_ уже пустой ((( ) A> < A>char* value = "1"; A> string sValue(value); A> s_ = sValue.c_str(); /// s_ - указывает на внутренний массив sValue, который гарантированно не меняется до следующего вызова не константного члена  A>> //1 шаг. после этого шага sValue уничтожается вместе со всеми своими внутренними данными A>

Используйте:
1) Можно использовать strcpy(s_, sValue.c_str()); В s_ будет записано sValue.size() байт + 1 для завершающего нуля.
2) Использовать sValue.copy(s_, sValue.size(), 0); После в s_ не будет завершающего нуля
Общий минус этих двух способов в том, что перед копированием необходимо следить, чтобы s_ указывало на выделенную память достаточного размера для размещения sValue.c_str();
3) Не использовать const char* s_, а обходитьяс только std::srting объектами.
Если необходимо затем вызывать синхронную(блокирующую)системную функцию, принимающую const char* s_, то передавать в нее конечное вычисленное значение sValue.c_str() Если вызываемая функция будет использовать данные в отдельном потоке, который может завершится прежде, чем для sValue будет вызван деструктор, то придется копировать.

Re[3]: Значение string в const char* как.

От: Uzumaki Naruto
Дата: 11.05.11 08:13
Оценка:

const char ошибки

91. inline const char* Q_strrchr (const char *s, char c) < return strrchr( s, c ); >
92. inline int Q_strcmp (const char *s1, const char *s2) < return strcmp( s1, s2 ); >
93. inline int Q_stricmp( const char *s1, const char *s2 ) < return stricmp( s1, s2 ); >
94. inline const char* Q_strstr( const char *s1, const char *search ) < return strstr( s1, search ); >
95. inline char* Q_strupr (char *start) < return strupr( start ); >
96. inline char* Q_strlower (char *start) < return strlwr( start ); >
При компиляции выдает: strtools.h(91) : error C2440: return: невозможно преобразовать 'const char *' в 'char *'
1> В результате преобразования теряются квалификаторы
1>strtools.h(94) : error C2440: return: невозможно преобразовать 'const char *' в 'char *'
1> В результате преобразования теряются квалификаторы
Visual C++ 2008 Express Edition
Как зафиксить?

#1
17:17, 18 ноя 2010

13bit
А если через преобразование типа к (const char*)?

#2
17:22, 18 ноя 2010
#3
17:26, 18 ноя 2010

13bit
У меня компилируется ваш пример, без ошибок. Вы какой заголовочный файл подключаете для использования str* функций?
p.s. Не слушай нижнего товарища, который тебе предлагает какой-то недокод.

#4
17:26, 18 ноя 2010

13bit
Ну вот например у тебя есть так:

const char text1="Hello!"; char* text2=0;

И пишешь вот так:

text2=( char*)text1;
const char text1=0; char* text2="Hello!";
text1=( const char*)text2;

Может быть это совсем не то что тебе нужно, но мало ли.

#5
17:34, 18 ноя 2010

У меня здесь header-файл, вообще не понимаю откуда она тут лезет, эта ошибка.

#6
17:35, 18 ноя 2010

Это из краденной беты Source Engine. Просто хочу движок скомпилить и вот эта лабуда мешает.

#7
17:41, 18 ноя 2010

13bit
Прикол в том, что ты сам исправил уже, видимо :). То, что ты показал в первом посте, отличается от оригинального strtools.h, который я только что посмотрел. Ты же сам добавил const квалификаторы, как это нужно.

#8
17:47, 18 ноя 2010

Да, но почему всеравно дает ошибку? Может надо какие-нибудь дополнительные header \ lib файлы к солюшену прикрутить?

#9
17:54, 18 ноя 2010
#10
17:59, 18 ноя 2010

13bit
Там в отладочной сборке макросы подстановки срабатывают, т.е. ты пишешь Q_strstr, например, а компилятор заменяет этот вызов на вызов функции _Q_strstr, которая не была поправлена. Одно из решений - закомментировать вот этот код выше так:

#ifdef _DEBUG /* #define Q_memset(dest, fill, count) _Q_memset (__FILE__, __LINE__, (dest), (fill), (count)) #define Q_memcpy(dest, src, count) _Q_memcpy (__FILE__, __LINE__, (dest), (src), (count)) #define Q_memmove(dest, src, count) _Q_memmove (__FILE__, __LINE__, (dest), (src), (count)) #define Q_memcmp(m1, m2, count) _Q_memcmp (__FILE__, __LINE__, (m1), (m2), (count)) #define Q_strlen(str) _Q_strlen (__FILE__, __LINE__, (str)) #define Q_strcpy(dest, src) _Q_strcpy (__FILE__, __LINE__, (dest), (src)) #define Q_strrchr(s, c) _Q_strrchr (__FILE__, __LINE__, (s), (c)) #define Q_strcmp(s1, s2) _Q_strcmp (__FILE__, __LINE__, (s1), (s2)) #define Q_stricmp(s1, s2 ) _Q_stricmp (__FILE__, __LINE__, (s1), (s2) ) #define Q_strstr(s1, search ) _Q_strstr (__FILE__, __LINE__, (s1), (search) ) #define Q_strupr(start) _Q_strupr (__FILE__, __LINE__, (start)) #define Q_strlower(start) _Q_strlower (__FILE__, __LINE__, (start))*/ #else

#11
18:01, 18 ноя 2010

Я в Release компилировал.

#12
18:04, 18 ноя 2010

13bit
А кусок кода, который использует эти функции и который вываливается с ошибкой можешь показать? Просто твой приведенный пример верный.

#13
18:08, 18 ноя 2010

inline void Q_memset (void *dest, int fill, int count) < memset( dest, fill, count ); >
inline void Q_memcpy (void *dest, const void *src, int count) < memcpy( dest, src, count ); >
inline void Q_memmove (void *dest, const void *src, int count) < memmove( dest, src, count ); >
inline int Q_memcmp (void *m1, void *m2, int count) < return memcmp( m1, m2, count ); >
inline int Q_strlen (char const *str) < return strlen ( str ); >
inline void Q_strcpy (char *dest, char const *src) < strcpy( dest, src ); >
inline const char* Q_strrchr (const char *s, char c) < return strrchr( s, c ); >\\ на это ругается
inline int Q_strcmp (const char *s1, const char *s2) < return strcmp( s1, s2 ); >
inline int Q_stricmp( const char *s1, const char *s2 ) < return stricmp( s1, s2 ); >
inline const char* Q_strstr( const char *s1, const char *search ) < return strstr( s1, search ); >\\ тут тоже ругается
inline char* Q_strupr (char *start) < return strupr( start ); >
inline char* Q_strlower (char *start)

  • Alexander K
  • Постоялец

#14
18:12, 18 ноя 2010

Зачем возвращаемое значение const char* ? Поставь просто char*, а лучше посмотри что возвращают функции strrchr и strstr.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *