O que significa "estático" em C?

1138

Eu já vi a palavra staticusada em diferentes lugares no código C; é como uma função / classe estática em C # (onde a implementação é compartilhada entre objetos)?

jww
fonte
6
Relacionado: Static (keyword) @ Wikipedia
Palec
15
Qual é o motivo para remover "em um programa C" do final do título, @Lundin? É um pouco redundante na presença da tag c , mas me permite ver a categorização mais rapidamente, sem inspecionar as tags. Essa redundância é muito confortável quando chego à pergunta de uma direção que também pode conter perguntas sobre outros idiomas, por exemplo, pesquisa estática ou no Google.
Palec
5
@Palec Existe uma política de SO em que os itens presentes na lista de tags são redundantes no título. O site anexará automaticamente C ao site real. Um Google para "C estático" fornece essa resposta como principal hit. A razão pela qual isso foi alterado é porque essa pergunta agora faz parte das perguntas frequentes do idioma SO C e todas as postagens adicionadas são um pouco polidas.
Lundin 23/05
1
@Lundin Eu prefiro manter "C" no título, porque o SO anexa apenas uma tag ao título (a mais comum?). E se algum dia a "sintaxe" chegar a mais perguntas do que C (já que é uma coisa entre idiomas)? Eu prefiro usar o comportamento explícito :-) Edit: ah, mas há uma questão meta dizendo o contrário: meta.stackexchange.com/questions/19190/...
Ciro Santilli郝海东冠状病六四事件法轮功
1
Esta é uma explicação que encontrei no Quora. Definitivamente vale a pena ler!
Nalzok

Respostas:

1520
  1. Uma variável estática dentro de uma função mantém seu valor entre invocações.
  2. Uma variável global estática ou uma função é "vista" apenas no arquivo declarado em

(1) é o tópico mais externo se você é um novato, então aqui está um exemplo:

#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();
}

Isso imprime:

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

Isso é útil nos casos em que uma função precisa manter algum estado entre as invocações e você não deseja usar variáveis ​​globais. Cuidado, no entanto, esse recurso deve ser usado com moderação - torna seu código não seguro para threads e mais difícil de entender.

(2) É amplamente utilizado como um recurso de "controle de acesso". Se você tem um arquivo .c implementando alguma funcionalidade, normalmente expõe apenas algumas funções "públicas" para os usuários. O restante de suas funções deve ser feito static, para que o usuário não possa acessá-las. Isso é encapsulamento, uma boa prática.

Citando a Wikipedia :

Na linguagem de programação C, estática é usada com variáveis ​​e funções globais para definir seu escopo para o arquivo que contém. Nas variáveis ​​locais, estático é usado para armazenar a variável na memória alocada estaticamente, em vez da memória alocada automaticamente. Enquanto o idioma não determina a implementação de qualquer tipo de memória, a memória alocada estaticamente é normalmente reservada no segmento de dados do programa em tempo de compilação, enquanto a memória alocada automaticamente é normalmente implementada como uma pilha de chamadas transitórias.

E para responder sua segunda pergunta, não é como em C #.

No C ++, no entanto, statictambém é usado para definir atributos de classe (compartilhados entre todos os objetos da mesma classe) e métodos. Em C não há classes, portanto esse recurso é irrelevante.

Eli Bendersky
fonte
179
Pax, o OP não sabe sobre estática, então você sugere mergulhá-lo na diferença entre unidades e arquivos de compilação? :-)
Eli Bendersky
138
Uma unidade de compilação é um único arquivo que o compilador vê. Seu arquivo .c pode incluir outros arquivos .c, mas após o pré-processador classificar as inclusões, o compilador eventualmente vê apenas uma única "unidade de compilação".
Eli Bendersky
81
@robUK: o compilador nem sabe sobre os arquivos .h - eles são combinados nos arquivos .c no pré-processador. Portanto, sim, você pode dizer que o arquivo .c, com todos os cabeçalhos incluídos, é uma única unidade de compilação.
Eli Bendersky
6
@ TonyD talvez seja confuso, mas é assim que a compilação funciona. Normalmente, pode haver um .cmonte de arquivos de cabeçalho, mas o diabo está sempre no que não é típico.
peterph
7
@TonyD O compilador faz a compilação. O pré-processador faz o pré-processamento. Chamar o conjunto de ferramentas de 'compilador' não muda o que é ou o que faz.
Route de milhas
231

Há mais um uso não abordado aqui, e isso é parte de uma declaração de tipo de matriz como argumento para uma função:

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

Nesse contexto, isso especifica que os argumentos passados ​​para essa função devem ser uma matriz do tipo charcom pelo menos 10 elementos. Para mais informações, veja minha pergunta aqui .

dreamlax
fonte
3
Eu não acho que C tinha argumentos de matriz? Linus Torvalds reclama com raiva sobre as pessoas fazendo isso.
Suprjami 29/09/2015
13
@jamieb: C não têm argumentos da matriz, mas esse meio de sintaxe específicas que a função espera arg[0]até arg[9]a ter valores (o que também implica que a função não aceitar um ponteiro nulo). Os compiladores podem utilizar essas informações de alguma forma para otimização, e os analisadores estáticos podem utilizar essas informações para garantir que a função nunca receba um ponteiro nulo (ou, se puder dizer, uma matriz com menos elementos do que o especificado).
dreamlax
19
@Qix - Este era um novo significado sobrecarregado dado staticem C99. Tem mais de uma década e meia de idade, mas nem todos os escritores de compiladores adotaram todos os recursos do C99 - portanto, o C99 como um todo permanece amplamente desconhecido.
Happy Green Kid Naps
@suprjami Eu não tenho 100% de certeza do que você quer dizer com "argumentos da matriz" , mas se você quer dizer int arr[n];, essa é uma VLA (matriz de comprimento variável) , que foi adicionada na C99. É isso que você quis dizer?
RastaJedi
170

Resposta curta ... depende.

  1. Variáveis ​​locais definidas estáticas não perdem seu valor entre as chamadas de função. Em outras palavras, são variáveis ​​globais, mas com escopo definido para a função local em que estão definidos.

  2. Variáveis ​​globais estáticas não são visíveis fora do arquivo C em que estão definidas.

  3. Funções estáticas não são visíveis fora do arquivo C em que estão definidas.

cmcginty
fonte
8
Então, "função estática" e "função privada" significam a mesma coisa? Da mesma forma, "variáveis ​​globais estáticas" e "variáveis ​​globais privadas" são a mesma coisa?
user1599964
40
Trata-se de C. Não há privado / público em C.
chris
19
@ user1599964 embora não exista privateem C, sua analogia é boa: estática torna as coisas "privadas" para um determinado arquivo. E os arquivos em C frequentemente são mapeados para classes em C ++.
Ciro Santilli adicionou uma nova foto
67

Exemplo de escopo variável de vários arquivos

Aqui ilustro como a estática afeta o escopo das definições de função em vários arquivos.

ac

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/

/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/

/* OK: extern. Will use the one in main. */
extern int i;

/* OK: only visible to this file. */
static int si = 0;

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

main.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;
}

GitHub upstream .

Compile e execute:

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

Resultado:

m()
i = 1
si = 1

m()
i = 2
si = 2

a()
i = 3
si = 1

a()
i = 4
si = 2

Interpretação

  • existem duas variáveis ​​separadas para si, uma para cada arquivo
  • existe uma única variável compartilhada para i

Como de costume, quanto menor o escopo, melhor, sempre declare variáveis static se puder.

Na programação C, os arquivos são frequentemente usados ​​para representar "classes" e as staticvariáveis ​​representam membros estáticos privados da classe.

O que os padrões dizem sobre isso

C99 N1256 draft 6.7.1 "Especificadores da classe de armazenamento" diz que staticé um "especificador da classe de armazenamento".

6.2.2 / 3 "Ligações de identificadores" diz staticimplica internal linkage:

Se a declaração de um identificador de escopo de arquivo para um objeto ou uma função contiver o estático do especificador de classe de armazenamento, o identificador terá ligação interna.

e 6.2.2 / 2 diz que internal linkagese comporta como no nosso exemplo:

No conjunto de unidades de tradução e bibliotecas que constituem um programa inteiro, cada declaração de um identificador específico com ligação externa indica o mesmo objeto ou função. Dentro de uma unidade de conversão, cada declaração de um identificador com ligação interna indica o mesmo objeto ou função.

onde "a unidade de tradução é um arquivo de origem após o pré-processamento.

Como o GCC o implementa para o ELF (Linux)?

Com o STB_LOCAL ligação.

Se compilarmos:

int i = 0;
static int si = 0;

e desmonte a tabela de símbolos com:

readelf -s main.o

a saída contém:

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

portanto, a ligação é a única diferença significativa entre eles. Valueé apenas o deslocamento para a .bssseção, portanto esperamos que seja diferente.

STB_LOCALestá documentado na especificação ELF em http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html :

STB_LOCAL Os símbolos locais não são visíveis fora do arquivo de objeto que contém sua definição. Símbolos locais com o mesmo nome podem existir em vários arquivos sem interferir entre si

o que a torna uma escolha perfeita para representar static.

Variáveis ​​sem estática são STB_GLOBALe a especificação diz:

Quando o editor de links combina vários arquivos de objetos realocáveis, ele não permite várias definições de símbolos STB_GLOBAL com o mesmo nome.

que é coerente com os erros de link em várias definições não estáticas.

Se acionarmos a otimização -O3, o sisímbolo será removido inteiramente da tabela de símbolos: ele não pode ser usado de fora de qualquer maneira. TODO por que manter variáveis ​​estáticas na tabela de símbolos quando não há otimização? Eles podem ser usados ​​para qualquer coisa? Talvez para depuração.

Veja também

Namespace anônimos em C ++

No C ++, convém usar espaços de nome anônimos em vez de estático, o que gera um efeito semelhante, mas oculta ainda mais as definições de tipo: espaços de nome anônimos / anônimos / funções estáticas

Ciro Santilli adicionou uma nova foto
fonte
39

Depende:

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

A função retornaria 1, 2, 3 etc. - a variável não está na pilha.

ac:

static int foo()
{
}

Isso significa que esta função tem escopo apenas neste arquivo. Portanto, ac e bc podem ter foo()s diferentes , e foo não é exposto a objetos compartilhados. Portanto, se você definiu foo em ac, não poderia acessá-lo de b.cou de outros lugares.

Na maioria das bibliotecas C, todas as funções "privadas" são estáticas e a maioria "pública" não é.

Artyom
fonte
18
+1 por mencionar x que não está na pilha ou pilha. Está no espaço estático da memória.
Gob00st
1
@ Gob00st espaço de memória estática? você quis dizer "segmento de dados" ...?
Yousha Aleayoub
24

As pessoas continuam dizendo que 'estático' em C tem dois significados. Ofereço uma maneira alternativa de visualizá-lo, que lhe dá um único significado:

  • A aplicação de 'estático' a um item força esse item a ter duas propriedades: (a) não é visível fora do escopo atual; (b) É persistente.

A razão pela qual parece ter dois significados é que, em C, todo item ao qual 'estático' pode ser aplicado já possui uma dessas duas propriedades , portanto parece que esse uso específico envolve apenas o outro.

Por exemplo, considere variáveis. As variáveis ​​declaradas fora das funções já têm persistência (no segmento de dados), portanto, aplicar 'estático' só pode torná-las visíveis fora do escopo atual (unidade de compilação). Por outro lado, variáveis ​​declaradas dentro de funções já não têm visibilidade fora do escopo atual (função), portanto, aplicar 'estático' só pode torná-las persistentes.

Aplicar 'estático' a funções é como aplicá-lo a variáveis ​​globais - o código é necessariamente persistente (pelo menos no idioma), portanto, apenas a visibilidade pode ser alterada.

NOTA: Esses comentários se aplicam apenas a C. No C ++, aplicar 'estático' aos métodos de classe está realmente dando à palavra-chave um significado diferente. Da mesma forma para a extensão de argumento de matriz C99.

PMar
fonte
Seu (a) é redundante na melhor das hipóteses. Nenhuma variável é visível fora do seu escopo. Essa é simplesmente a definição de escopo. O que você quer dizer é chamado de ligação no padrão C. staticfornece ligação interna a um identificador.
Jens
16

Da Wikipedia:

Na linguagem de programação C, estática é usada com variáveis ​​e funções globais para definir seu escopo para o arquivo que contém. Nas variáveis ​​locais, estático é usado para armazenar a variável na memória alocada estaticamente, em vez da memória alocada automaticamente. Enquanto o idioma não determina a implementação de qualquer tipo de memória, a memória alocada estaticamente é normalmente reservada no segmento de dados do programa em tempo de compilação, enquanto a memória alocada automaticamente é normalmente implementada como uma pilha de chamadas transitórias.

OscarRyz
fonte
16

static significa coisas diferentes em diferentes contextos.

  1. Você pode declarar uma variável estática em uma função C. Essa variável é visível apenas na função, no entanto, ela se comporta como um global, pois é inicializada apenas uma vez e mantém seu valor. Neste exemplo, toda vez que você ligar foo(), imprimirá um número crescente. A variável estática é inicializada apenas uma vez.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
  2. Outro uso de estático é quando você implementa uma função ou variável global em um arquivo .c, mas não deseja que seu símbolo seja visível fora do .objgerado pelo arquivo. por exemplo

    static void foo() { ... }
m-sharp
fonte
8

Se você declarar uma variável em uma função estática, seu valor não será armazenado na pilha de chamadas de funções e continuará disponível quando você chamar a função novamente.

Se você declarar uma variável global estática, seu escopo será restrito ao arquivo em que você a declarou. Isso é um pouco mais seguro que um global comum, que pode ser lido e modificado durante todo o programa.

Jonathan Adelson
fonte
8

Detesto responder a uma pergunta antiga, mas acho que ninguém mencionou como a K&R a explica na seção A4.1 de "A linguagem de programação C".

Em resumo, a palavra estática é usada com dois significados:

  1. Static é uma das duas classes de armazenamento (a outra é automática). Um objeto estático mantém seu valor entre invocações. Os objetos declarados fora de todos os blocos são sempre estáticos e não podem ser automatizados.
  2. Porém, quando a static palavra - chave (grande ênfase em ser usada no código como palavra-chave) é usada com uma declaração, ela fornece a ligação interna ao objeto para que ela possa ser usada apenas dentro dessa unidade de tradução. Mas se a palavra-chave for usada em uma função, ela altera a classe de armazenamento do objeto (o objeto só seria visível dentro dessa função). O oposto de static é a externpalavra - chave, que fornece a ligação externa a um objeto.

Peter Van Der Linden dá esses dois significados em "Programação C Especialista":

  • Dentro de uma função, mantém seu valor entre as chamadas.
  • No nível da função, visível apenas neste arquivo.
jigglypuff
fonte
Há uma terceira classe de armazenamento, registre-se . Algumas pessoas também defendem uma quarta classe de armazenamento, alocada , para o armazenamento retornado por malloc e amigos.
Jens
@Jens 'register' é apenas uma dica para o compilador; o armazenamento do registro não pode ser imposto de dentro da fonte C. Portanto, eu não consideraria uma classe de armazenamento.
GermanNerd
1
@GermanNerd Acho que o padrão ISO C discorda de sua visão, pois claramente faz registerum especificador de classe de armazenamento (C99 6.7.1 Especificadores de classe de armazenamento). E é mais do que apenas uma dica, por exemplo, você não pode aplicar o endereço do operador &em um objeto com classe de armazenamento, registerindependentemente de o compilador alocar um registro ou não.
Jens
@ Jens Obrigado por me lembrar sobre &. Eu poderia ter feito muito C ++ ..... De qualquer forma, enquanto 'register' é um especificador de classe de armazenamento, na realidade o compilador provavelmente criará o mesmo código de máquina para o especificador 'auto' (inútil) e para o 'register 'especificador. Portanto, a única coisa que resta é a restrição no nível do código-fonte de não ser possível obter um endereço. Aliás, essa pequena discussão me levou a encontrar um bug no Netbeans; desde a minha última atualização, o padrão é a cadeia de ferramentas g ++ em novos projetos C!
GermanNerd
6

Em C, estática tem dois significados, dependendo do escopo de seu uso. No escopo global, quando um objeto é declarado no nível do arquivo, significa que esse objeto é visível apenas dentro desse arquivo.

Em qualquer outro escopo, ele declara um objeto que manterá seu valor entre os diferentes momentos em que o escopo específico é inserido. Por exemplo, se um int for delcared dentro de um procedimento:

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

   i++;
}

o valor de 'i' é inicializado como zero na primeira chamada para o procedimento e o valor é retido cada vez que o procedimento é chamado. se 'i' fosse impresso, produziria uma sequência de 0, 1, 2, 3, ...

schot
fonte
5

É importante observar que variáveis ​​estáticas nas funções são inicializadas na primeira entrada dessa função e persistem mesmo após o término da chamada; no caso de funções recursivas, a variável estática é inicializada apenas uma vez e persiste também em todas as chamadas recursivas e mesmo após o término da chamada da função.

Se a variável foi criada fora de uma função, significa que o programador só pode usar a variável no arquivo de origem em que a variável foi declarada.

Starhowl
fonte
5

Se você declarar isso em um mytest.carquivo:

static int my_variable;

Então essa variável pode ser vista apenas neste arquivo. A variável não pode ser exportada para nenhum outro lugar.

Se você declarar dentro de uma função, o valor da variável manterá seu valor sempre que a função for chamada.

Uma função estática não pode ser exportada de fora do arquivo. Portanto, em um *.carquivo, você está ocultando as funções e as variáveis ​​se as declarar estáticas.

ant2009
fonte
4

Variáveis ​​estáticas em C têm a vida útil do programa.

Se definidos em uma função, eles têm escopo local, ou seja, podem ser acessados ​​apenas dentro dessas funções. O valor das variáveis ​​estáticas é preservado entre as chamadas de função.

Por exemplo:

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

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

No programa acima, var é armazenado no segmento de dados. Sua vida útil é todo o programa C.

Após a chamada de função 1, vartorna-se 2. Após a chamada de função 2, vartorna-se 3.

O valor de varnão é destruído entre as chamadas de funções.

Se vartivesse entre variáveis ​​não estáticas e locais, seria armazenado no segmento de pilha no programa C. Como o quadro da pilha da função é destruído após o retorno da função, o valor de vartambém é destruído.

Variáveis ​​estáticas inicializadas são armazenadas no segmento de dados do programa C, enquanto variáveis ​​não inicializadas são armazenadas no segmento BSS.

Outra informação sobre estática: se uma variável é global e estática, ela possui o tempo de vida do programa C, mas o escopo do arquivo. É visível apenas nesse arquivo.

Para tentar isso:

file1.c

static int x;

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

file2.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

Agora tente vinculá-los usando:

gcc -o output file1.o file2.o

Isso causaria um erro de vinculador, pois x tem o escopo do arquivo file1.c e o vinculador não conseguiria resolver a referência à variável x usada no arquivo2.c.

Referências:

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack
Sahil Manchanda
fonte
Eu entendo que os dados são persistentes, o que significa que não será perdido após cada chamada de função, mas por que não static int var = 1;mudar o valor de volta para uma de cada vez
Eames
3

Uma variável estática é uma variável especial que você pode usar em uma função e salva os dados entre as chamadas e não os exclui entre as chamadas. Por exemplo:

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();
    }
}

A saída:

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

Yagel
fonte
Você pode substituir printf("%d, ", count); count++;por `printf ("% d, ", count ++) (não que isso importe: P).
RastaJedi
2

Um valor de variável estática persiste entre diferentes chamadas de função e seu escopo é limitado ao bloco local, uma var estática sempre inicializa com o valor 0

Jonathon
fonte
2

Existem 2 casos:

(1) Variáveis ​​locais declaradas static: alocadas no segmento de dados em vez da pilha. Seu valor é retido quando você chama a função novamente.

(2) Variáveis ​​ou funções globais declaradas static: Unidade de compilação externa invisível (ou seja, são símbolos locais na tabela de símbolos durante o vínculo).

Jonny Kong
fonte
1

As variáveis ​​estáticas têm a propriedade de preservar seu valor mesmo depois de estarem fora do escopo! Portanto, as variáveis ​​estáticas preservam o valor anterior no escopo anterior e não são inicializadas novamente no novo escopo.

Veja isso por exemplo - Uma variável int estática permanece na memória enquanto o programa está sendo executado. Uma variável normal ou automática é destruída quando uma chamada de função em que a variável foi declarada termina.

#include<stdio.h> 
int fun() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("%d ", fun()); 
  printf("%d ", fun()); 
  return 0; 
}

Isso produzirá: 1 2

Como 1 permanece na memória como foi declarado estático

Variáveis ​​estáticas (como variáveis ​​globais) são inicializadas como 0 se não forem inicializadas explicitamente. Por exemplo, no programa abaixo, o valor de x é impresso como 0, enquanto o valor de y é algo como lixo. Veja isso para mais detalhes.

#include <stdio.h> 
int main() 
{ 
    static int x; 
    int y; 
    printf("%d \n %d", x, y); 
}

Isso produzirá: 0 [some_garbage_value]

Estes são os principais que descobri que não foram explicados acima para um novato!

erastone
fonte
-1

Na programação C, staticé uma palavra-chave reservada que controla a vida útil e a visibilidade. Se declararmos uma variável como estática dentro de uma função, ela será visível apenas em toda a função. Nesse uso, a vida útil dessa variável estática será iniciada quando uma chamada de função e será destruída após a execução dessa função. você pode ver o seguinte exemplo:

#include<stdio.h> 
int counterFunction() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("First Counter Output = %d\n", counterFunction()); 
  printf("Second Counter Output = %d ", counterFunction()); 
  return 0; 
}

O programa acima nos dará esta saída:

First Counter Output = 1 
Second Counter Output = 1 

Porque assim que chamarmos a função, ela inicializará o count = 0. E enquanto executamos o, counterFunctionele destruirá a variável count.

Makdia Hussain
fonte
2
> O programa acima nos dará esta saída: Primeira saída do contador = 1 Segunda saída do contador = 1 <Não é verdade. Variáveis ​​estáticas são inicializadas apenas uma vez. Portanto, a saída será 1, depois 2 e assim por diante.
GermanNerd