2015-03-18 2 views
2

У меня есть фрагмент кода C следующим образом:Переменный и постоянный с таким же именем

const int x = 5; 
void main() 
{ 
    int x[x]; 
    int y = sizeof(x)/sizeof(int); 
    printf("%d",y); 
} 

фрагмент кода будет компилироваться и работать правильно. Но я не понимаю, как различать x 'variable' и x 'const'.

+1

Почему вы не сэкономите свое горе и использовать разные, и значимые, идентификаторы? Стандарт определяет, что должно произойти, если два одинаковых имени находятся в пределах области действия. –

+0

Это не проблема в стиле кодирования, просто вопрос для укрепления моих знаний :) –

+1

В C нет синтаксиса, который позволяет вам получить доступ к 'const int x', после объявления' x [] 'в' main'. Объявление 'x []' скрывает 'const int x' до тех пор, пока' x [] 'находится в области видимости, что в этом примере будет« main ». – user3386109

ответ

9

Для C++ это рассматривается в draft C++ standard разделе 3.3.2Точка декларации:

Точка декларации на имя сразу после его полного описателя (раздел 8) и до его инициализаторе (если любой), за исключением , указанных ниже. [Пример:

int x = 12; 
{ int x = x; } 

Здесь второй x инициализируется собственным (неопределенным) значением. -end пример]

и:

[Примечание: имя из внешней области остается видимым до точки декларации имя, которое скрывает его [Пример:.

const int i = 2; 
{ int i[i]; } 

объявляет массив блоков с двумя целыми числами. -end пример] -end отметить ]

Так что в вашем случае:

int x[x]; 

сопзЬ Intx видна до закрытия ]. Для того, чтобы обратиться к сопзЬ междунарx после этого момента вы можете использовать qualified identifer:

::x 

Конечно возникает вопрос, почему бы не просто использовать различные имена и не приходится иметь дело с этими крайними случаями?

С

Эквивалентные котировки образуют draft C99 standard бы из раздела 6.2.1Области применения идентификаторов (курсив мой):

структуры, объединения и перечисления метки имеют область действия, начинается только после появления тега в спецификаторе типа, который объявляет тег . Каждая константа перечисления имеет область действия, которая начинается сразу после появления нулевого определителя в списке перечислителей . Любой идентификатор имеет область действия, которая начинается сразу после заполнения его декларатором.

и:

[...] В пределах внутреннего объема, идентификатор обозначает объект объявленных во внутреннем объеме; объект, объявленный во внешней области, является скрытым (и не видимым) во внутренней области.

нет никакого способа, чтобы сделать x в внешней области видимого в С.

+0

Итак, допустим, я определяю такую ​​переменную: int x = x; после этого, когда я использую y = x; что будет здесь? –

+0

@duong_dajgja, что было бы неопределенным поведением, так как значение «x» в этом случае неопределенно: см. [Изменен ли стандарт C++ в отношении использования неопределенных значений и неопределенного поведения в C++ 14?] (Http: // stackoverflow.com/q/23415661/1708801) ... Также [неопределенное поведение в C также] (http://stackoverflow.com/q/22416319/1708801) –

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