2010-08-19 2 views
4

Я пытаюсь понять объявления массива, константы и их результирующие типы переменных.C: объявить постоянный указатель на массив постоянных символов

Следующая разрешено (мой компилятор):

 char s01[] = "abc" ; // typeof(s01) = char* 
const char s02[] = "abc" ; // typeof(s02) = const char* (== char const*) 
char const s03[] = "abc" ; // typeof(s03) = char const* (== const char*) 

В качестве альтернативы, мы можем объявить размер массива вручную:

 char s04[4] = "abc" ; // typeof(s04) = char* 
const char s05[4] = "abc" ; // typeof(s05) = const char* (== char const*) 
char const s06[4] = "abc" ; // typeof(s06) = char const* (== const char*) 

Как получить результирующую переменную типа const char* const? Не допускаются (мой компилятор) следующее:

const char s07 const[] = "abc" ; 
char const s08 const[] = "abc" ; 
const char s09[] const = "abc" ; 
char const s10[] const = "abc" ; 
const char s11 const[4] = "abc" ; 
char const s12 const[4] = "abc" ; 
const char s13[4] const = "abc" ; 
char const s14[4] const = "abc" ; 

Благодаря

+0

Я не полностью уверен, что C поддерживает const ptr * const, что делает C++. – Puppy

+0

@DeadMG: Он делает. –

+0

Ниже приведен очень полезный инструмент: http://cdecl.ridiculousfish.com/?q=declare+bar+as+constant+pointer+to+array+of+constant+char; http://cdecl.ridiculousfish.com/?q=declare+bar+as+constant+pointer+to+constant+char – celavek

ответ

9
const char *const s15 = "abc"; 
+0

Полезно читать справа налево, чтобы понять, что является постоянным. Например. 'char * const s15' означает постоянный указатель на символ. 'char const * s15' означает указатель на константу-char. 'char const * const s15' означает константу-указатель-константу-char. Попробуй! Справа налево! –

+2

@PP: Правило справа налево не применяется ни при каких обстоятельствах. например 'int blah [5] [2]'. Лучшее резюме того, как читать деклараторы, которые я когда-либо находил, находится здесь: http://msdn.microsoft.com/en-us/library/1x82y1z4.aspx. –

+6

@PP: Это не право налево больше, чем слева направо, это ** наизнанку **. – Gilles

5

s01 и др не действительно указатель типов, они типы массивов. В этом смысле они уже действуют немного как const указатели (вы не можете повторно назначить s01, чтобы указать, например, на другое место).

3

Применение cdecl:

cdecl> declare foo as constant pointer to array of constant char 
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension' 
     (maybe you mean "pointer to object") 
const char (* const foo)[] 
cdecl> declare foo as constant pointer to array 4 of constant char 
const char (* const foo)[3] 
cdecl> declare foo as constant pointer to constant char 
const char * const foo 

Указатели на массивы редко используются в C; обычно функции API ожидают указатель на первый элемент.

6

Ваши первые typeof комментарии не совсем правильные. Тип s01 - char [4], а типы s02 и s03 - const char [4]. При использовании в выражении, а не в субъекте либо операторов &, либо sizeof, они будут оценивать значения r 0 0, char * и const char * соответственно, указывая на первый элемент массива.

Вы не можете объявить их таким образом, чтобы они распадались на rvalue, которое само является const-квалифицированным; на самом деле не имеет смысла иметь const-qual rvalue, так как rvalues ​​не могут быть назначены. Это как сказать, что вы хотите константу 5, которая имеет тип const int, а не int.

Смежные вопросы