Использование модификатора static в c - PullRequest
3 голосов
/ 02 июля 2019

Я начинающий учиться в. Я знаю, что использование слова «static» делает функцию c и переменную локальной для исходного файла, в котором она объявлена. Но учтите следующее ...

test.h

static int n = 2;
static void f(){
    printf("%d", n);
}

main.c

#include <stdio.h>
#include "test.h"
int main()
{
    printf("%d", n);
    f();
    return 0;
}

Мой ожидаемый результат - появление сообщения об ошибке, поскольку функция f и переменная n являются локальными только для test.h? Спасибо.

Но вместо этого был вывод

2
2  

EDIT: Если это работает только для модуля компиляции, что это значит? И как я могу использовать статические, как я задумал?

Ответы [ 3 ]

7 голосов
/ 02 июля 2019

static делает вашу функцию / переменную локальной для единицы компиляции , то есть всего набора исходного кода, который читается при компиляции одного файла .c.

#include Использование файла .h немного похоже на копирование / вставку содержимого этого заголовочного файла в ваш файл .c.Таким образом, n и f в вашем примере считаются локальными для вашей единицы компиляции main.c.

Пример

module.h

#ifndef MODULE_H
#define MODULE_H

int fnct(void);

#endif /* MODULE_H */

module.c

#include "module.h"

static
int
detail(void)
{
  return 2;
}

int
fnct(void)
{
  return 3+detail();
}

main.c

#include <stdio.h>
#include "module.h"

int
main(void)
{
  printf("fnct() gives %d\n", fnct());
  /* printf("detail() gives %d\n", detail()); */
  /* detail cannot be called because:
     . it was not declared
       (rejected at compilation, or at least a warning)
     . even if it were, it is static to the module.c compilation unit
       (rejected at link)
  */
  return 0;
}

build (компилировать каждый .c затем ссылку)

gcc -c module.c
gcc -c main.c
gcc -o prog module.o main.o
1 голос
/ 02 июля 2019

Когда переменная или функция объявляются в области видимости файла (не внутри какой-либо другой пары { } фигурных скобок), и они объявляются static, они являются локальными для единицы перевода они находятся в.

Единица перевода - это формальный термин в C, который немного отличается от файла.Единицей перевода является один файл c и все файлы h, которые он включает.

Итак, в вашем случае переменная static является локальной для единицы перевода, состоящей из test.h и main.c.Вы сможете получить к нему доступ в main.c, но не в foo.c.

Это означает, что если у вас есть другой файл .c, включающий test.h, вы получите два экземпляра одной и той же переменной,с тем же именем.Это в свою очередь может привести к всевозможным сумасшедшим ошибкам.

Это одна из многих причин, по которой мы никогда не определяем переменные внутри заголовочных файлов.

(Чтобы избежать разработки программы для спагетти, мы не должны также объявлять переменные в заголовках, если они не квалифицированы как const).

1 голос
/ 02 июля 2019

Вы включили test.h в main.c.

Поэтому static int n и static void f() также будут видны внутри main.c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...