2012-06-15 2 views
20

Я сделал 2 проекта, первый в C и второй в C++, оба работают с одинаковым поведением.статические и внешние глобальные переменные в C и C++

C Проект:

header.h

int varGlobal=7; 

main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "header.h" 

void function(int i) 
{ 
    static int a=0; 
    a++; 
    int t=i; 
    i=varGlobal; 
    varGlobal=t; 
    printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t); 
} 

int main() { 
    function(4); 
    function(6); 
    function(12); 
    return 0; 
} 

проект C++:

header.h

int varGlobal=7; 

main.cpp

#include <iostream> 
#include "header.h" 
using namespace std; 

void function(int i) 
{ 
    static int a=0; 
    int t=i; 
    a++; 
    i=varGlobal; 
    varGlobal=t; 
    cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl; 
} 

int main() { 
    function(4); 
    function(6); 
    function(12); 
    return 0; 
} 

Я читал, что глобальные переменные ехЬегп по умолчанию и в C и статического по умолчанию в C++; так почему же работает код C++?

Я имею в виду int varGlobal = 7; такой же, как static int varGlobal = 7;, и если он статичен, то он может использоваться только в объявленном файле, не так ли?

+0

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

ответ

63

Глобальные переменные не являются extern или static по умолчанию на языках C и C++. Когда вы объявляете переменную как static, вы ограничиваете ее текущим исходным файлом. Если вы объявите его как extern, вы говорите, что переменная существует, но объявлена ​​где-то в другом месте, и если вы ее не объявили в другом месте (без ключевого слова extern), вы получите сообщение об ошибке (символ не найден).

Ваш код сломается, когда у вас будет больше исходных файлов, включая этот заголовок, при времени ссылки у вас будет несколько ссылок на varGlobal. Если вы объявите его static, то он будет работать с несколькими источниками (я имею в виду, он будет компилировать и связывать), но каждый источник будет иметь свой собственный varGlobal.

Что вы можете сделать в C++, что вы не можете в C, чтобы объявить переменную как const на заголовок, например:

const int varGlobal = 7; 

И включают в нескольких источниках, не нарушая вещи время ссылки. Идея состоит в том, чтобы заменить старый стиль C #define на константы.

Если вам нужна глобальная переменная видна на нескольких источниках и не const, объявим его как extern на заголовке, и объявить его снова, на этот раз без экстерном keywork, на исходном файле:

Заголовок Включается несколько файлов:

extern int varGlobal; 

В одном из исходных файлов:

int varGlobal = 7; 
+3

Как я только что открыл, существует * разница между C и C++, но она применима только к объектам ** const **: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp? topic =% 2Fcom.ibm.xlcpp8l.doc% 2Flanguage% 2Fref% 2Fconst_cv_qualifier.htm –

+0

Если вы собираетесь размещать вещи в заголовках, некоторые компиляторы/линкеры будут жаловаться на многократно определенные символы. Пример: 'const int varGlobal = 7;' Поскольку вы объявляете его 'const', его можно рассматривать как глобальную константу, но некоторые компиляторы не настолько умны. То, что всегда работает, заключается в объявлении вещей 'static const' в заголовочном файле, например: static const int varGlobal = 7;' Таким образом, даже если компилятор глуп, он не добавит символ к внешнему таблица символов и компоновщик никогда не будут видеть многозначные символы. – steveha

+0

@steveha Объявление константы как «static const» приведет к раздражающим предупреждениям о файлах, содержащих заголовок, но не использует константу (конечно, в зависимости от вашего компилятора и предупреждений). – fbafelipe

6

Когда вы заголовок #include, это как если бы вы поместили код в исходный файл. В обоих случаях переменная varGlobal определена в источнике, поэтому она будет работать независимо от того, как она объявлена.

Также, как указано в комментариях, переменные C++ в области файлов не являются статическими в области охвата, хотя они будут назначены статическому хранилищу. Если переменная была членом класса, например, она должна была быть доступна для других единиц компиляции в программе по умолчанию, а члены, не являющиеся членами класса, ничем не отличаются.

+3

Кроме того, OP ошибочен в предположении, что глобально объявленная переменная по умолчанию статична в C++. Они имеют внешний * linkage *, как и в C. Глобальные переменные имеют статическую * продолжительность * в C и C++, хотя, поэтому это может сбивать с толку. – nos

+0

Итак, правила применяются для * .c файлов * .cpp, но не для * .h файлов? Спасибо! – Cristi

+0

Я ошибся ... Спасибо! – Cristi

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