Каква е употребата на static/extern в изходните файлове?

Имам много смесена представа какво се случва, когато компилирам много файлове - най-вече когато става въпрос за видимостта на нещата от един файл в друг. От това, което прочетох, static ограничава обхвата на променлива или функция до самия файл. extern прави обратното. От това бих очаквал да мога и просто да чета глобален extern от всеки файл. Това обаче не работи на практика, както се вижда по-долу.

main.c:

#include <stdio.h>

int main(void){
    printf("%d\n", b); // b is extern global
    return 0;
}

A.C:

static int a = 40;

b.c:

extern int b = 20;

Дори не мога да компилирам:

> gcc main.c a.c b.c -o test
b.c:1:12: warning: ‘b’ initialized and declared ‘extern’ [enabled by default]
 extern int b = 20;
            ^
main.c: In function ‘main’:
main.c:4:20: error: ‘b’ undeclared (first use in this function)
     printf("%d\n", b); // b is extern global

person Pithikos    schedule 15.01.2015    source източник
comment
Добра идея е да имате всичките си външни променливи в .h файлове и да ги включите в необходимите .c файлове   -  person Gopi    schedule 15.01.2015


Отговори (3)


Вие правите всичко погрешно. Когато пишем extern int b, това означава, че е декларирана променлива с цяло число, наречена b. И можем да правим тази декларация толкова пъти, колкото е необходимо. (не забравяйте, че декларацията може да бъде направена произволен брой пъти). Чрез екстерниране на променлива можем да използваме променливите навсякъде в програмата, при условие че знаем декларацията им и променливата е дефинирана някъде.

Правилният начин е

main.c:

#include <stdio.h>

extern int b;   //declaration of b
 int main(void){
    printf("%d\n", b); // using b 
    return 0;
}

b.c:

int b = 20;   //definition here

и компилирайте като gcc main.c b.c -o test

Пропуснах a.c, тъй като не правеше нищо в този пример. За да разберете повече за екстерните, вижте този сайт. Има много добро съдържание http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

person Ankur    schedule 15.01.2015
comment
Благодаря, това беше най-простото обяснение на групата :) - person Pithikos; 15.01.2015
comment
Добре дошли, радваме се да помогнем :) - person Ankur; 15.01.2015
comment
extern int b; защо имаме нужда от extern тук глобалните променливи са extern по подразбиране - person Gopi; 15.01.2015
comment
Погледнете връзката, която показах, и коментирайте от R.Sahu - person Ankur; 15.01.2015
comment
@Shan Какъв коментар и дори ако премахнете extern, кодът ви не се променя, така че защо го имате и какво е значението да го имате? - person Gopi; 15.01.2015
comment
@Gopi провери Съжалявам отговора на R Sahu. И дори ако премахнете extern, вашият код не се променя какво означава? - person Ankur; 15.01.2015
comment
@Shan Вярно, extern е зададено по подразбиране. Изричното обаче прави нещата по-ясни - така че в този случай това е просто конвенция. - person Pithikos; 16.01.2015

Променлива може да се използва, ако е декларирана или дефинирана.

В main.c няма декларация за b. Можете да добавите

extern int b;

в main.c, за да може компилаторът да използва b. Това декларира на компилатора, че b е дефиниран някъде другаде и е от тип int.

В b.c можете да премахнете думата extern. Освен ако не е квалифицирано с static, по подразбиране е extern.

int b = 20;

Дори в b.c можете да използвате декларация в горната част на файла и да я дефинирате в долната част.

extern int b;

//
// ... code that uses b
//

int b = 20;

Редът extern просто декларира променливата. Последният ред дефинира променливата.

person R Sahu    schedule 15.01.2015

Когато имате променлива extern, компилаторът знае, че декларацията за тази променлива е тук, а дефиницията е някъде другаде.

Така че можете да направите както е показано по-долу

някои.з

   extern int b;  /* Declare the variable */

b.c

   int b = 20;  /* Define the variable */

main.c

    #include<some.h>

    int main()
    {
       printf("%d\n",b);  /* Use the variable b */

       return 0;
    }

С това сега файлът main.c знае декларацията на b, тъй като има some.h файл.

person Gopi    schedule 15.01.2015
comment
включително some.h не е необходимо предполагам - person Ankur; 15.01.2015