Que signifie" statique " en C?

j'ai vu le mot static utilisé à différents endroits dans le code C; est-ce comme une fonction statique/classe en C# (où l'implémentation est partagée entre les objets)?

881
demandé sur jww 2009-02-21 09:47:52
la source

18 ответов

  1. une variable statique à l'intérieur d'une fonction garde sa valeur entre invocations.
  2. une variable globale statique ou une fonction est "vue" seulement dans le fichier qu'elle est déclarée dans

(1) est le sujet le plus étranger Si vous êtes un internaute novice, alors voici un exemple:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;

    a += 5;
    sa += 5;

    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;

    for (i = 0; i < 10; ++i)
        foo();
}

Cette affiche:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

ceci est utile pour les cas où une fonction doit garder un État entre les invocations, et vous ne voulez pas utiliser de variables globales. Attention, cependant, cette fonctionnalité doit être utilisée avec beaucoup de parcimonie - elle rend votre code non thread-sûr et plus difficile à comprendre.

(2) Est largement utilisé comme un "contrôle d'accès". Si vous avez un .c mise en œuvre de certaines fonctionnalités, il n'expose généralement que quelques fonctions "publiques" aux utilisateurs. Le reste de ses fonctions doit être faite static , de sorte que l'utilisateur ne sera pas en mesure d'y accéder. C'est l'encapsulation, une bonne pratique.

Citant Wikipedia :

dans le langage de programmation C, statique est utilisé avec des variables globales et fonctions pour définir leur portée à la contenant le fichier. Dans les variables locales, statique est utilisé pour stocker la variable dans la mémoire allouée statiquement au lieu de l'attribution automatique mémoire. Alors que la langue n'est pas dictent la mise en œuvre de soit type de mémoire allouée statiquement la mémoire est généralement réservée dans les données segment du programme à compiler le temps, tandis que le automatiquement la mémoire allouée est normalement implémenté comme une pile d'appels transitoires.

Voir ici et ici pour plus de détails.

et pour répondre à votre deuxième question, ce n'est pas comme dans C#.

en C++, cependant, static est également utilisé pour définir les attributs de classe (partagés entre tous les objets de la même classe) et les méthodes. En C, il n'y a pas de classe, donc cette caractéristique n'est pas pertinente.

1247
répondu Eli Bendersky 2014-08-12 18:25:29
la source

il y a une autre utilisation qui n'est pas couverte ici, et qui fait partie d'une déclaration de type de tableau comme argument à une fonction:

int someFunction(char arg[static 10])
{
    ...
}

dans ce contexte, ceci spécifie que les arguments passés à cette fonction doivent être un tableau de type char contenant au moins 10 éléments. Pour plus d'informations voir ma question ici .

193
répondu dreamlax 2017-05-23 14:55:03
la source

courte réponse ... ça dépend.

  1. les variables locales statiques définies ne perdent pas leur valeur entre les appels de fonction. En d'autres termes, ce sont des variables globales, mais portées à la fonction locale dans laquelle elles sont définies.

  2. les variables globales statiques ne sont pas visibles à l'extérieur du fichier C dans lequel elles sont définies.

  3. statique les fonctions ne sont pas visibles en dehors du fichier C dans lequel elles sont définies.

142
répondu cmcginty 2013-01-15 18:46:58
la source

Multi-fichier de la portée des variables exemple

A. c :

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/q/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c-files-while-gcc-does-not-69756/"a()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

principal.c :

#include <stdio.h>

int i = 0;
static int si = 0;

void a();    

void m() {
    i++;
    si++;
    puts("m()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

int main() {
    m();
    m();
    a();
    a();
    return 0;
}

Compilation :

gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o

Sortie :

m()
i = 1
si = 1

m()
i = 2
si = 2

a()
i = 3
si = 1

a()
i = 4
si = 2

interprétation

  • il y a deux variables distinctes pour si , une pour chaque fichier
  • il y a une seule variable partagée pour i

comme d'habitude, plus la portée est petite, mieux c'est, déclarez toujours les variables static si vous le pouvez.

dans la programmation C, les fichiers sont souvent utilisés pour représenter les" classes", et les variables static représentent les membres statiques privés de la classe.

Quelles sont les normes à dire sur le sujet

C99 N1256 projet 6.7.1 "de Stockage de classe prescripteurs", dit que static est une "catégorie de stockage spécificateur".

6.2.2/3 "Liens de identificateurs" dit static implique internal linkage :

si la déclaration d'un identifiant de portée de fichier pour un objet ou une fonction contient le spécificateur de classe de stockage statique, l'identificateur a une liaison interne.

et 6.2.2 / 2 dit que internal linkage se comporte comme dans notre exemple:

dans l'ensemble des unités de traduction et des bibliothèques qui constituent un programme complet, chaque déclaration d'un identificateur particulier avec lien externe indique le même objet ou la même fonction. Au sein d'une unité de traduction, chaque déclaration d'un identifiant avec lien interne indique le même objet ou fonction.

où "l'unité de traduction est un fichier source après prétraitement.

comment GCC le met en œuvre pour ELF (Linux)?

avec la reliure STB_LOCAL .

si nous compilons:

int i = 0;
static int si = 0;

et démonter la table de symboles avec:

readelf -s main.o

la sortie contient:

Num:    Value          Size Type    Bind   Vis      Ndx Name
  5: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    4 si
 10: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 i

si la liaison est la seule différence significative entre eux. Value est juste leur offset dans la section .bss , donc nous nous attendons à ce qu'il diffère.

STB_LOCAL est documenté sur la spécification ELF à http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html :

STB_LOCAL les symboles locaux ne sont pas visibles à l'extérieur du fichier objet contenant leur définition. Local symboles de le même nom peut exister dans plusieurs fichiers sans interférer les uns avec les autres

ce qui en fait un choix parfait pour représenter static .

Variables sans statique sont STB_GLOBAL , et le spec dit:

lorsque l'éditeur de liens combine plusieurs fichiers objet déplaçables, il ne permet pas de définir plusieurs symboles STB_GLOBAL avec le même nom.

qui est cohérent avec les erreurs de lien sur plusieurs définitions non statiques.

si nous activons l'optimisation avec -O3 , le symbole si est entièrement enlevé de la table de symboles: il ne peut pas être utilisé de l'extérieur de toute façon. Pourquoi garder les variables statiques sur la table de symboles quand il n'y a pas d'optimisation? Peut-on les utiliser pour quelque chose? Peut-être que pour le débogage.

Voir aussi

Essayez-le vous-même

exemple sur github pour vous de jouer avec.

47
la source

cela dépend:

int foo()
{
   static int x;
   return ++x;
}

la fonction retournerait 1, 2, 3, etc. --- la variable n'est pas sur la pile.

A. c:

static int foo()
{
}

Cela signifie que cette fonction n'a de portée que dans ce fichier. Donc ... c et B. c peut avoir différents foo() s, et foo n'est pas exposé à des objets partagés. Donc si vous avez défini foo dans un.c vous ne pouviez pas y accéder depuis b.c ou depuis tout autre endroit.

In la plupart des bibliothèques C toutes les fonctions "privées" sont statiques et la plupart des fonctions "publiques" ne le sont pas.

33
répondu Artyom 2017-03-28 20:13:57
la source

les gens n'arrêtent pas de dire que "statique" en Do a deux significations. J'offre une autre façon de le voir qui lui donne un sens unique:

  • L'application du terme "statique" à un élément force cet élément à posséder deux propriétés: a) il n'est pas visible en dehors du champ d'application Actuel; B) il est persistant.

la raison pour laquelle il semble avoir deux significations est que, en C, chaque élément auquel "statique" peut s'appliquer a déjà une signification ces deux propriétés , donc il semble comme si cet usage particulier implique seulement l'autre.

par exemple, tenir compte des variables. Les Variables déclarées en dehors des fonctions ont déjà une persistance (dans le segment de données), de sorte que l'application "statique" ne peut que les rendre non visibles en dehors du champ d'application actuel (Unité de compilation). Au contraire, les variables déclarées à l'intérieur des fonctions ont déjà une non-visibilité en dehors de la portée actuelle (fonction), donc l'application "statique" ne peut que les rendre persistantes.

appliquer "statique" aux fonctions revient à l'appliquer aux variables globales - le code est nécessairement persistant (du moins dans le langage), de sorte que seule la visibilité peut être modifiée.

NOTE: ces commentaires ne s'appliquent qu'à C. En C++, appliquer 'static' aux méthodes de classe donne vraiment au mot clé un sens différent. De même pour l'extension C99 array-argument.

18
répondu PMar 2016-04-27 16:47:26
la source

static signifie des choses différentes dans des contextes différents.

  1. vous pouvez déclarer une variable statique dans une fonction C. Cette variable n'est visible que dans la fonction mais elle se comporte comme une globale en ce sens qu'elle n'est initialisée qu'une seule fois et qu'elle conserve sa valeur. Dans cet exemple, chaque fois que vous appelez foo() il affichera un nombre croissant. La variable statique n'est initialisée qu'une seule fois.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
    
  2. une autre utilisation de la statique est lorsque vous mettez en œuvre une fonction ou une variable globale dans un .C file mais ne veulent pas que son symbole soit visible en dehors du .obj généré par le fichier. par exemple

    static void foo() { ... }
    
12
répondu m-sharp 2011-11-17 17:43:25
la source

De Wikipedia:

dans le langage de programmation C, statique est utilisé avec des variables globales et des fonctions pour définir leur portée au fichier contenant. Dans les variables locales, static est utilisé pour stocker la variable dans la mémoire statically attribuée au lieu de la mémoire automatiquement attribuée. Bien que le langage ne dicte pas la mise en œuvre de l'un ou l'autre type de mémoire, la mémoire statiquement attribuée est généralement réservé dans le segment de données du programme au moment de la compilation, alors que la mémoire automatiquement attribuée est normalement implémentée comme une pile d'appels transitoires.

11
répondu OscarRyz 2009-02-21 09:52:18
la source

je déteste répondre à une vieille question, mais je ne pense pas que quelqu'un ait mentionné comment K&R l'explique dans la section A4.1 de "The C Programming Language".

En bref, le mot statique est utilisé avec deux significations:

  1. Statique est l'une des deux classes de stockage (l'autre étant automatique.) Un objet statique garde sa valeur entre invocations. Les objets déclarés en dehors de tous les blocs sont toujours statiques et ne peuvent pas être en fait automatique.
  2. mais, lorsque le static mot-clé (grande emphase sur le fait qu'il est utilisé dans code comme un mot-clé) est utilisé avec une déclaration, il donne cet objet Lien interne de sorte qu'il ne peut être utilisé à l'intérieur de cette unité de traduction. Mais si le mot-clé est utilisé dans une fonction, il change la classe de stockage de l'objet (l'objet ne serait visible à l'intérieur de cette fonction de toute façon). Le contraire de static est le mot-clé extern , qui donne un objet de liaison externe.

Peter Van Der Linden donne ces deux significations dans "Expert C Programming":

  • à l'intérieur d'une fonction, conserve sa valeur entre les appels.
  • Au niveau de la fonction, visible uniquement dans ce fichier.
6
répondu nobism 2016-04-12 06:34:46
la source

Si vous déclarez une variable dans une fonction statique, sa valeur ne seront pas stockées sur la pile d'appel et sera toujours disponible lorsque vous appelez la fonction de nouveau.

Si vous déclarez une variable globale statique, sa portée sera limitée dans le fichier dans lequel vous avez déclaré. C'est un peu plus sûr qu'un global régulier qui peut être lu et modifié tout au long de votre programme.

5
répondu Sam Hoice 2009-02-21 09:52:48
la source

en C, la statique a deux significations, selon la portée de son utilisation. Dans le contexte global, lorsqu'un objet est déclaré au niveau du fichier, cela signifie que cet objet n'est visible à l'intérieur du fichier.

à toute autre portée, il déclare un objet qui conservera sa valeur entre les différents moments où la portée particulière est inscrite. Par exemple, si un int est supprimé dans le cadre d'une procédure:

void procedure(void)
{
   static int i = 0;

   i++;
}

la valeur de " i " est initialisé à zéro lors du premier appel à la procédure, et la valeur est conservée à chaque fois que la procédure est appelée. si' i ' était imprimé, il produirait une séquence de 0, 1, 2, 3,...

5
répondu schot 2010-09-25 17:07:06
la source

si vous déclarez ceci dans un mytest.fichier c:

static int my_variable;

alors cette variable ne peut être vue que de ce fichier. La variable ne peut pas être exportée ailleurs.

Si vous déclarez à l'intérieur d'une fonction, la valeur de la variable conserve sa valeur, chaque fois que la fonction est appelée.

une fonction statique ne peut pas être exportée de l'extérieur du fichier. Ainsi, dans un *.c fichier, vous vous cachez les fonctions et les variables si vous déclarer statique.

4
répondu ant2009 2009-03-18 19:49:02
la source

il est important de noter que les variables statiques dans les fonctions sont initialisées à la première entrée dans cette fonction et persistent même après que leur appel a été terminé; dans le cas de fonctions récursives la variable statique est initialisée seulement une fois et persiste aussi bien sur tous les appels récursifs et même après que l'appel de la fonction a été terminé.

si la variable a été créée en dehors d'une fonction, cela signifie que le programmeur est seulement capable d'utiliser la variable dans le fichier source la variable a été déclarée.

3
répondu Starhowl 2014-05-01 10:30:15
la source

aussi pour noter que static peut être utilisé de 4 façons différentes.

to create permanent storage for local variables in a function.
to specify internal linkage.
to declare member functions that act like non-member functions.
to create a single copy of a data member.
2
répondu amrx 2016-01-07 02:03:28
la source

Une variable statique est une variable spéciale que vous pouvez utiliser dans une fonction, et il enregistre les données entre les appels, et il ne le supprime pas entre les appels. Par exemple:

void func(){
    static int count; // If you don't declare its value, the value automatically initializes to zero
    printf("%d, ", count);
    count++;
}

void main(){
    while(true){
        func();
    }
}

La sortie:

0, 1, 2, 3, 4, 5, ...

2
répondu Yagel 2017-03-28 20:16:23
la source

les variables statiques en C ont la durée de vie du programme.

si elles sont définies dans une fonction, elles ont une portée locale, c'est-à-dire qu'elles ne peuvent être consultées qu'à l'intérieur de ces fonctions. La valeur des variables statiques est conservée entre les appels de fonction.

par exemple:

void function()
{
    static int var = 1;
    var++;
    printf("%d", var);
}

int main()
{
    function(); // Call 1
    function(); // Call 2
}

Dans le programme ci-dessus, var est stocké dans le segment de données. Sa durée de vie est l'ensemble du programme C.

après appel de fonction 1, var devient 2. Après l'appel de fonction 2, var devient 3.

la valeur de var n'est pas détruite entre les appels de fonctions.

si var avait entre variable non statique et variable locale, il serait stocké dans le segment de pile dans le programme C. Puisque le cadre de la pile de la fonction est détruit après le retour de la fonction, la valeur de var est également détruite.

Les variables statiques initialisées sont stockées dans le segment de données du programme C tandis que les variables non initialisées sont stockées dans le segment BSS.

une autre information sur la statique: si une variable est globale et statique, elle a la durée de vie du programme C, mais elle a la portée du fichier. Il est visible que dans ce fichier.

essayer ceci:

fichier1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

fichier2.c

    extern int x;
    func()
    {
        printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
    }

run gcc -c file1.c

gcc -c file2.c

maintenant, essayez de les lier en utilisant:

gcc -o output file1.o file2.o

cela donnerait une erreur de linker puisque x a la portée du fichier file1.c et le linker ne serait pas en mesure de résoudre la référence à la variable x utilisée dans file2.C.

, les Références:

  1. http://en.wikipedia.org/wiki/Translation_unit_ (programmation)
  2. http://en.wikipedia.org/wiki/Call_stack
2
répondu Sahil Manchanda 2017-03-28 20:21:46
la source

une valeur variable statique persiste entre les différents appels de fonction et son champ d'application est limité au bloc local une var statique initialise toujours avec la valeur 0

1
répondu Jonathon 2014-03-23 09:48:32
la source

il y a 2 cas:

(1) variables locales déclarées static : attribuées en segment de données au lieu de pile. Sa valeur se maintient lorsque vous appelez la fonction à nouveau.

(2) variables ou des fonctions Globales déclarées static : Invisible en dehors unité de compilation (à savoir les locaux de symboles dans la table des symboles lors de la liaison).

1
répondu Jonny Kong 2018-06-03 16:01:49
la source

Autres questions sur c syntax static