2016-03-29 7 views
0

Я написал ниже код (Только для понимания цели). Вне основного, int b; означает предварительное определение. Внутренний основной int b = 16 является локальной переменной. Внутри функциональной переменной b имеется внутренняя связь (область файла). Выходной сигнал равен 16 и 0. Я читал, что память выделяется для условно определенных переменных только тогда, когда они инициализируются. Итак, вот мой вопрос внутри функции, printf печатает значение b и выделяет ли память при вызове printf? В случае, если это так, могу ли я сказать, что память назначается предварительно определенным переменным, когда они впервые доступны (независимо от того, были ли они инициализированы или доступны)? Или я ошибаюсь?Предварительное определение и распределение памяти

int b; 
int b; 
void f1(int a1); 
int main() 
{ 
    int b=16; 
    printf("b=%d\n",b); 
    f1(5); 
    return 0; 
} 

void f1(int a1) 
{ 
    printf("b = %d\n",b); 
} 

Отредактировано: Добавление больше ясности: Я понимаю, что переменная внутри функции отличается от такового в основном. Также известно, что локальная переменная находится в стеке. Мой вопрос здесь в отношении предварительного определения. int b был объявлен дважды, и он принят в C, потому что это предварительное определение. Если это фактическое определение, то несколько определений не допускаются, и, следовательно, это не принимается. Есть несколько вопросов относительно предварительного определения (About Tentative definition). Согласно одному из них «C имеет специальное правило« предварительное определение », которое допускает несколько определений для одной и той же переменной, если они все совпадают, и не более одного имеет инициализатор. Компилятор C за кулисами объединяет все предварительные определения в единое определение ". Так что, чтобы перефразировать мой вопрос:

Сохраняется ли память, если переменная определена только как условно, но не используется? (предполагая, что компилятор не оптимизирует код). Похоже, что в конце единицы перевода память распределяется по указанному выше вопросу. Или выделена ли память только тогда, когда она используется в первый раз (в данном случае в заявлении printf)?

+0

Is 'int b; int b; 'разрешено? : O – Downvoter

+0

* «Предварительное определение становится полным определением, если достигнут конец единицы перевода, и определение не появилось с инициализатором для идентификатора« *.Таким образом, последнее предварительное определение становится фактическим с глобальной областью и нулевой инициализацией. –

+0

@cad: Как они идентичны: да. Не уверен, что это верно, если это, например, 'typedef int it; это b; ', приходилось искать в стандарте, но я все равно избегал бы этого, как ад. – Olaf

ответ

0

Это две разные переменные.

Для глобального int b; память выделяется при первой загрузке программы в память. Он выделяется в глобальной памяти программы и может быть легко доступен из любой точки программы.

Для main() местный int b=16; выделяется в стеке в функциональной структуре main(). Его можно получить непосредственно из этой функции. Любое другое требует либо того, чтобы main() передал адрес переменной или некоторую сложную арифметику указателя в стеке.

тамошних bшкур глобальный b, потому что они имеют такое же имя, так что вы не можете использовать глобальные одну из этой функции (некоторые языки позволяют это, C не делает), но это так. Это разные переменные, и двоичный код вашей программы (то есть фактические инструкции) не изменился, если вы изменили имя.

0

См. Этот ответ, который объясняет, почему int b; инициализируется нулем.

Does gcc automatically initialize static variables to zero?

int b; в основной находится в стеке и равен 16. В функции f1 единственный b символ, который находится в рамках это один объявлен в области видимости файла, и это ноль инициализируется, потому что это то, что говорит стандарт должен быть.

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