C ++ 30 perguntas de entrevista comuns (com respostas)

Para arrays multidimensionais, C ++ / C não converte simplesmente em ponteiros do mesmo tipo que arrays unidimensionais, mas converte em ponteiros de array equivalentes . Por exemplo, int a [m] [n] é convertido em int (* a) [n] , o que significa que a é um ponteiro para uma matriz unidimensional e a matriz unidimensional possui n elementos e a é o primeiro que aponta para a matriz original. O ponteiro de uma linha, a + 1 é o ponteiro para a segunda linha e assim por diante. As quatro expressões a seguir são equivalentes:
 

(1) a [i] [j]
(2) * (a [i] + j)
(3) (* (a + i)) [j]
(4) * (* (a + i) + j)
 

O que uma classe derivada não pode herdar de uma classe base?

Construtores, destruidores, operadores de atribuição e funções de amigo não podem ser herdados.

1.novo, excluir, malloc, relacionamento livre

delete irá chamar o destruidor do objeto , e new correspondente a free apenas liberará a memória e new irá chamar o construtor . malloc e free são funções de biblioteca padrão da linguagem C ++ / C, e new / delete são operadores C ++ . Eles podem ser usados ​​para solicitar memória dinâmica e liberar memória. Para objetos de tipos de dados não internos, malloc / free sozinho não pode atender aos requisitos de objetos dinâmicos. O objeto deve executar automaticamente o construtor quando é criado, e o objeto deve executar automaticamente o destruidor antes de morrer. Como malloc / free é uma função de biblioteca em vez de um operador, ela não está sob o controle do compilador e a tarefa de executar o construtor e o destruidor não pode ser imposta a malloc / free. Portanto, a linguagem C ++ precisa de um operador novo que possa completar a alocação e inicialização de memória dinâmica, e um operador delete que possa completar a limpeza e liberação de memória. Observe que new / delete não é uma função de biblioteca.

2. A diferença entre delete e delete []

delete irá chamar o destruidor apenas uma vez e delete [] irá chamar o destruidor de cada membro. Há uma explicação mais detalhada em C ++ Mais Eficaz: "Quando o operador delete é usado em uma matriz, ele chama o destruidor para cada elemento da matriz e, em seguida, chama o operador delete para liberar a memória." Delete corresponde a new, delete [] Combinando com novo []

MemTest * mTest1 = novo MemTest [10];

MemTest * mTest2 = novo MemTest;

Int * pInt1 = novo int [10];

Int * pInt2 = novo int;

delete [] pInt1; // - 1-

delete [] pInt2; // - 2-

delete [] mTest1; // - 3-

delete [] mTest2; // - 4-

Relate um erro em -4-.

Isso significa que para os tipos de dados simples integrados, as funções delete e delete [] são as mesmas. Para tipos de dados complexos personalizados, delete e delete [] não podem ser usados ​​mutuamente. delete [] exclui uma matriz, delete exclui um ponteiro. Simplificando, a memória alocada com novo é excluída com exclusão; a memória alocada com novo [] é excluída com excluir []. delete [] irá chamar o destruidor do elemento do array. Não há destruidor para tipos de dados internos, portanto, o problema não é grande. Se você não usar parênteses ao usar delete, delete irá assumir que aponta para um único objeto, caso contrário, irá assumir que aponta para um array.

3. Quais são as propriedades do C ++ (recursos orientados a objetos)

Encapsulamento, herança e polimorfismo.

4. O destruidor do pai deve ser chamado quando a subclasse é destruída?

A ordem da chamada do destruidor é a destruição da classe derivada primeiro e, em seguida, a destruição da classe base, o que significa que quando o destruidor da classe base é chamado, todas as informações da classe derivada foram destruídas. Ao definir um objeto, chame o construtor da classe base primeiro e, em seguida, chame o construtor da classe derivada; ao desestruturar, o oposto é verdadeiro: primeiro chame o destruidor da classe derivada e, a seguir, chame o destruidor da classe base.

5. Polimorfismo, função virtual, função virtual pura

Polimorfismo: Diferentes ações são geradas quando diferentes objetos recebem a mesma mensagem. O polimorfismo do C ++ é incorporado em dois aspectos de operação e compilação: o polimorfismo do programa é refletido por herança e funções virtuais;

O polimorfismo é refletido na sobrecarga de funções e operadores quando o programa é compilado;

Função virtual : uma função-membro prefixada com a palavra - chave virtual na classe base . Ele fornece uma interface de interface. É permitido redefinir a função virtual da classe base na classe derivada.

A função da função virtual pura : reservar um nome de função para sua classe derivada na classe base para que a classe derivada possa defini-la conforme necessário. Existe como uma interface. Funções puras virtuais não têm funções de funções e geralmente não podem ser chamadas diretamente.

As funções virtuais puras herdadas da classe base ainda são funções virtuais em classes derivadas. Se houver pelo menos uma função virtual pura em uma classe, essa classe é chamada de classe abstrata (classe abstrata).

As classes abstratas incluem não apenas funções virtuais puras, mas também funções virtuais . As classes abstratas devem ser usadas como classes base para derivar outras classes e não podem ser usadas para criar instâncias de objeto diretamente. No entanto, ponteiros para classes abstratas ainda podem ser usados ​​para oferecer suporte ao polimorfismo em tempo de execução.

6. Encontre o valor de retorno da seguinte função (Microsoft)

função int (x) 

int countx = 0; 

enquanto (x) 

countx ++; 

x = x & (x-1); 

return countx; 

Suponha que x = 9999. Resposta: 8

Idéia: Converta x em sistema binário e veja o número de unidades contidas.

7. O que é "cotação"? A quais questões devemos prestar atenção ao afirmar e usar "citações"?

Resposta: Uma referência é um "apelido" de uma variável de destino.O efeito da operação na referência é exatamente o mesmo que a operação direta na variável. Ao declarar uma referência, lembre-se de inicializá-la. Depois que a referência é declarada, é equivalente ao nome da variável de destino ter dois nomes, a saber, o nome original do destino e o nome de referência, e o nome de referência não pode ser usado como um alias para outros nomes de variáveis. Declarar uma referência não é uma nova definição de uma variável. Significa apenas que o nome da referência é um alias do nome da variável de destino. Não é um tipo de dados em si, então a referência em si não ocupa unidades de armazenamento e o sistema não aloca unidades de armazenamento para a referência. Não é possível criar uma referência a uma matriz.

8. Quais são as características de usar "referência" como um parâmetro de função?

(1) O efeito de passar uma referência a uma função é o mesmo que passar um ponteiro . Neste momento, o parâmetro formal da função chamada se torna a variável de parâmetro real ou um alias do objeto na função de chamada original.Portanto, a operação da variável de parâmetro formal na função chamada é o objeto de destino correspondente (na função de chamada). Na função de chamada).

(2) Usando a referência para passar os parâmetros da função, não há cópia do parâmetro real na memória, é uma operação direta no parâmetro real; ao usar a variável geral para passar o parâmetro da função, quando ocorre uma chamada de função, é necessário alocar armazenamento para o parâmetro formal Para a unidade, a variável de parâmetro formal é uma cópia da variável de parâmetro real; se o objeto for passado, o construtor de cópia também será chamado. Portanto, quando os dados passados ​​pelo parâmetro são grandes, a eficiência e o espaço ocupado pela referência são melhores do que a variável geral.

(3) Embora o uso de ponteiros como parâmetros de função também possa alcançar o efeito de usar referências, na função chamada, as unidades de armazenamento também devem ser alocadas para parâmetros formais, e a forma de "* nome da variável de ponteiro" precisa ser usada repetidamente para cálculos. Isso está sujeito a erros e má legibilidade do programa, por outro lado, no ponto de chamada da função de chamada, o endereço da variável deve ser usado como o parâmetro real. E as citações são mais fáceis de usar e mais claras.

9. Quando devo usar "citado com frequência"? 

Se você deseja usar referências para melhorar a eficiência do programa, mas também para proteger os dados passados ​​para a função de serem alterados na função, você deve usar referências constantes. Método de declaração frequentemente citado: identificador de tipo const & nome de referência = nome da variável de destino;

Exemplo 1

int a;

const int & ra = a;

ra = 1; // erro

a = 1; // correto

Exemplo 2

string foo ();

barra vazia (string & s);

Então, a seguinte expressão será ilegal:

bar (foo ());

bar ("olá, mundo");

A razão é que as strings foo () e "hello world" produzirão um objeto temporário e, em C ++, esses objetos temporários são do tipo const. Portanto, a expressão acima é uma tentativa de converter um objeto do tipo const em um tipo não const, o que é ilegal. Os parâmetros de referência devem ser definidos como const se puderem ser definidos como const.

10. O formato, vantagens e regras de usar "referência" como o tipo de valor de retorno de uma função?

Formato: identificador de tipo e nome da função (lista formal de parâmetros e descrição do tipo) {// corpo da função}

Benefício: nenhuma cópia do valor retornado é produzida na memória; (Nota: É por este motivo que não é aconselhável retornar uma referência a uma variável local. Porque como o tempo de vida da variável local termina, a referência correspondente também é Ele irá falhar e causar erro de execução! 

Precauções:

(1) Referências a variáveis ​​locais não podem ser retornadas. Este artigo pode se referir ao item 31 do C ++ efetivo [1]. O principal motivo é que as variáveis ​​locais serão destruídas após o retorno da função, de forma que a referência retornada se torne uma referência "não referida" e o programa entrará em um estado desconhecido.

(2) Uma referência à memória alocada por new dentro da função não pode ser retornada. Este artigo pode se referir ao item 31 do C ++ efetivo [1]. Embora não haja destruição passiva das variáveis ​​locais, mas para esta situação (retornando uma referência à nova memória alocada dentro da função), ela enfrenta outras situações embaraçosas. Por exemplo, se a referência retornada pela função aparecer apenas como uma variável temporária sem ser atribuída a uma variável real, então o espaço apontado por esta referência (alocado por new) não pode ser liberado, causando um vazamento de memória.

(3) As referências aos alunos podem ser retornadas, mas const é o melhor. Este princípio pode se referir ao item 30 do Effective C ++ [1]. O principal motivo é que quando os atributos de um objeto estão associados a uma determinada regra de negócio, sua atribuição muitas vezes está relacionada a alguns outros atributos ou ao estado do objeto, portanto, é necessário encapsular a operação de atribuição em uma regra de negócio. Se outros objetos puderem obter uma referência não constante (ou ponteiro) do atributo, a simples atribuição do atributo destruirá a integridade das regras de negócios.

(4) A função de sobrecarregar o valor de retorno do operador de stream declarado como "referência":

Operadores de fluxo << e >>, esses dois operadores costumam ser usados ​​consecutivamente, por exemplo: cout << "hello" << endl; Portanto, o valor de retorno desses dois operadores deve ser um e ainda suportar essas duas operações A referência de fluxo do símbolo. Outras soluções opcionais incluem: retornar um objeto de fluxo e retornar um ponteiro de objeto de fluxo. Mas para retornar um objeto de fluxo, o programa deve reconstruir (copiar) um novo objeto de fluxo, ou seja, dois operadores << consecutivos são na verdade para objetos diferentes! Isso é inaceitável. Para retornar um ponteiro de fluxo, o operador << não pode ser usado continuamente. Portanto, retornar uma referência de objeto de fluxo é a única opção. Esta única escolha é muito importante, pois ilustra a importância e insubstituibilidade das referências, talvez por isso o conceito de referência seja introduzido na linguagem C ++. 

Operador de atribuição =. Este operador, como o operador de fluxo, pode ser usado continuamente, por exemplo: x = j = 10; ou (x = 10) = 100; o valor de retorno do operador de atribuição deve ser um lvalue para que possa ser atribuído. Portanto, a referência torna-se a única opção de valor de retorno para este operador.

#Incluir <iostream.h>

int & put (int n);

int valsa [10];

erro interno = -1;

void main ()

{

put (0) = 10; // Considere o valor da função put (0) como o lvalue, que é equivalente a vals [0] = 10; 

put (9) = 20; // Considere o valor da função put (9) como o lvalue, que é equivalente a vals [9] = 20; 

cout << vals [0]; 

cout << vals [9];

int & put (int n)

{

if (n> = 0 && n <= 9) return vals [n]; 

else {cout << "erro de subscrito"; erro de retorno; }

}

(5) Em alguns outros operadores, você nunca deve retornar uma referência: + - * / Quatro operadores aritméticos. Eles não podem retornar referências, o item 23 de Effective C ++ [1] discute esse assunto em detalhes. O principal motivo é que esses quatro operadores não têm efeito colateral. Portanto, eles devem construir um objeto como o valor de retorno. As soluções opcionais incluem: retornar um objeto, retornar uma referência a uma variável local, retornar uma referência a um objeto alocado por new e retornar Uma referência de objeto estático. De acordo com as três regras de referência acima mencionadas como valor de retorno, a segunda e a terceira opções foram rejeitadas. Referências a objetos estáticos também causam erros porque ((a + b) == (c + d)) sempre será verdadeiro. Portanto, a única opção que resta é retornar um objeto.

11. Qual é a diferença entre estrutura e união?

(1). Estruturas e uniões são compostas por vários membros de diferentes tipos de dados, mas a qualquer momento, apenas um membro selecionado é armazenado na união (todos os membros compartilham um espaço de endereço), e todos os membros da estrutura são Existe (membros diferentes têm endereços de armazenamento diferentes). 

(2). A atribuição de valores a diferentes membros do sindicato substituirá os outros membros. Os valores dos membros originais não existem mais e a atribuição de diferentes membros da estrutura não afeta uns aos outros.

12. Tente escrever o resultado do programa:

int a = 4;

int & f (int x)

{a = a + x;

      return a;

}

int main (vazio)

{int t = 5;

     cout << f (t) << endl; a = 9

    f (t) = 20; a = 20

    cout << f (t) << endl; t = 5, a = 20 a = 25

     t = f (t); a = 30 t = 30

    cout << f (t) << endl; } t = 60

}

 13. Qual é a diferença entre sobrecarga e excessivamente seca (alguns livros também são chamados de "capa")?

Perguntas comuns. Por definição:

Sobrecarga: significa que várias funções com o mesmo nome são permitidas e as listas de parâmetros dessas funções são diferentes (talvez o número de parâmetros seja diferente, ou os tipos de parâmetro sejam diferentes, ou ambos).

Reescrever: refere-se ao método de redefinir a função virtual da classe pai pela subclasse.

Do princípio de realização:

Sobrecarga: O compilador modifica o nome da função com o mesmo nome de acordo com as diferentes listas de parâmetros da função, e então essas funções com o mesmo nome tornam-se funções diferentes (pelo menos para o compilador). Por exemplo, existem duas funções com o mesmo nome: função func (p: inteiro): inteiro; e função func (p: string): inteiro ;. Então, os nomes das funções modificados pelo compilador podem ser parecidos com estes: int_func, str_func. A chamada para essas duas funções foi determinada entre os compiladores e é estática. Em outras palavras, seus endereços são vinculados em tempo de compilação (vinculação inicial), portanto, a sobrecarga não tem nada a ver com polimorfismo!

Reescrever: Realmente relacionado ao polimorfismo. Quando a subclasse redefine a função virtual da classe pai, o ponteiro da classe pai chama dinamicamente a função pertencente à subclasse de acordo com os diferentes ponteiros da subclasse atribuídos a ela. Tais chamadas de função não podem ser determinadas durante a compilação (chamar O endereço da função virtual da subclasse não pode ser fornecido). Portanto, esses endereços de função são vinculados em tempo de execução (vinculação tardia).

  

 14. Em que casos posso usar apenas a lista de inicialização, mas não a atribuição?

Resposta: Quando a classe contém const e variáveis ​​de membro de referência, o construtor da classe base precisa inicializar a tabela.

15. O tipo C ++ é seguro?

Resposta: Não. Dois ponteiros de tipos diferentes podem ser coagidos (usando elenco de reinterpretação). C # é seguro para o tipo.

16. Qual código será executado antes que a função principal seja executada?

Resposta: O construtor do objeto global será executado antes da função principal.

17. Descreva os métodos de alocação de memória e suas diferenças?

1) Alocado da área de armazenamento estático. A memória é alocada quando o programa é compilado, e essa memória existe durante todo o período de execução do programa. Por exemplo, variáveis ​​globais, variáveis ​​estáticas.

2) Crie na pilha. Quando a função é executada, as unidades de armazenamento das variáveis ​​locais na função podem ser criadas na pilha, e essas unidades de armazenamento são liberadas automaticamente quando a execução da função termina. A operação de alocação de memória da pilha é incorporada ao conjunto de instruções do processador.

3) Alocação do heap, também conhecida como alocação de memória dinâmica. Quando o programa estiver rodando, use malloc ou new para solicitar qualquer quantidade de memória, e o programador é responsável por quando usar free ou delete para liberar a memória. O tempo de vida da memória dinâmica é determinado pelo programador e é muito flexível de usar, mas apresenta muitos problemas.

 18. Escreva a declaração de comparação de BOOL, int, float, variável de tipo de ponteiro a e "zero", respectivamente. Do "Guia para programação de alta qualidade"

responda:

BOOL: if (! A) ou if (a)

int: if (a == 0)

flutuante: const EXPRESSION EXP = 0,000001

if (a <EXP && a> -EXP)

ponteiro: if (a! = NULL) ou if (a == NULL)

19. Diga-me quais são as vantagens de const em comparação com #define? Do "Guia para programação de alta qualidade"

responda:

função const: define constantes, modifica os parâmetros da função e modifica os valores de retorno da função. As coisas modificadas por Const estão sujeitas a proteção obrigatória, o que pode evitar mudanças inesperadas e melhorar a robustez do programa.

1) constantes de constantes têm tipos de dados, enquanto constantes de macro não têm tipos de dados. O compilador pode realizar verificações de segurança de tipo no primeiro. Para o último, apenas a substituição de caracteres é executada, não há verificação de segurança de tipo e erros inesperados podem ocorrer na substituição de caracteres.

2) Algumas ferramentas de depuração integradas podem depurar constantes constantes, mas não podem depurar constantes de macro.

20. Descreva resumidamente a diferença entre array e ponteiro?

Os arrays são criados no armazenamento estático (como arrays globais) ou na pilha. O ponteiro pode apontar para qualquer tipo de bloco de memória a qualquer momento.

(1) Diferenças no conteúdo modificado

char a [] = “olá”;

a [0] = 'X';

char * p = "mundo"; // Observe que p aponta para uma string constante

p [0] = 'X'; // O compilador não pode encontrar o erro, é um erro de tempo de execução

(2) Use o operador sizeof para calcular a capacidade (número de bytes) da matriz. sizeof (p), p é o número de bytes de uma variável de ponteiro, não a capacidade de memória apontada por p. A linguagem C ++ / C não tem como saber a capacidade de memória apontada pelo ponteiro, a menos que seja lembrada ao solicitar memória. Observe que quando um array é passado como um parâmetro de função, o array degenera automaticamente em um ponteiro do mesmo tipo.

char a [] = "olá mundo";

char * p = a;

cout << sizeof (a) << endl; // 12 字节

cout << sizeof (p) << endl; // 4 字节

Calcule a capacidade de memória de arrays e ponteiros

void Func (char a [100])

{

cout << sizeof (a) << endl; // 4 bytes em vez de 100 bytes

}

Pergunta 21: O que int (* s [10]) (int) significa? *

int (* s [10]) (int) Matriz de ponteiros de função, cada ponteiro aponta para uma função int func (int param).

Pergunta 22: Pilha de memória e área constante de texto

           char str1 [] = "abc";
  char str2 [] = "abc";

  const char str3 [] = "abc";
  const char str4 [] = "abc";

  const char * str5 = "abc";
  const char * str6 = "abc";

  char * str7 = "abc";
  char * str8 = "abc";

  cout << (str1 == str2) << endl; // 0 respectivamente aponta para sua respectiva pilha de memória
  cout << (str3 == str4) << endl; // 0 respectivamente aponta para sua respectiva pilha de memória
  cout << (str5 = = str6) << endl; // 1 aponta para o mesmo endereço na área constante de texto

  cout << (str7 == str8) << endl; // 1 aponta para o mesmo endereço na área constante de texto

  O resultado é: 0 0 1 1

  Resposta: str1, str2, str3 e str4 são variáveis ​​de matriz, elas têm seu próprio espaço de memória; enquanto str5, str6, str7 e str8 são ponteiros, eles apontam para a mesma área constante.

Pergunta 23: Salte o programa para o endereço de memória especificado

Para atribuir um valor ao endereço absoluto 0x100000, podemos usar (unsigned int *) 0x100000 = 1234; então, o que devemos fazer se quisermos que o programa vá para o endereço absoluto 0x100000 para execução?


  * ((void (*) ()) 0x100000) ();
  Primeiro, 0x100000 deve ser forçado a um ponteiro de função, ou seja:
  (void (*) ()) 0x100000
  e depois chamá-lo de:
  * ((void (*) () ) 0x100000) ();
  pode ser visto de forma mais intuitiva com typedef:
  typedef void (*) () voidFuncPtr;
  * ((voidFuncPtr) 0x100000) ();

Pergunta 24: int id [sizeof (unsigned long)]; isso está correto? porque?


 Resposta: Correto. Este sizeof é um operador em tempo de compilação, que é determinado em tempo de compilação e pode ser considerado uma constante relacionada à máquina.

Questão 25: Qual é a diferença entre uma referência e um ponteiro?


[Consulte a resposta]                         
1) A referência deve ser inicializada, o ponteiro não é necessário.

2) A referência não pode ser alterada após a inicialização, e o ponteiro pode alterar o objeto apontado.

3) Não há referência ao valor nulo, mas há um ponteiro para o valor nulo.

Pergunta 26: Comparando const e #define, quais são as vantagens de const? Do "Guia para programação de alta qualidade"
 [resposta de referência]

(1) constantes constantes têm tipos de dados , enquanto constantes macro não têm tipos de dados . O compilador pode realizar verificações de segurança de tipo no primeiro. 'No último, apenas a substituição de caracteres é realizada, não há verificação de segurança de tipo e erros inesperados (efeitos colaterais) podem ocorrer na substituição de caracteres.

(2) Algumas ferramentas de depuração integradas podem depurar constantes constantes, mas não podem depurar constantes de macro.

Item 27: Declaração complexa

void * (* (* fp1) (int)) [10];

float (* (* fp2) (int, int, int)) (int);

int (* (* fp3) ()) [10] ();

O que eles querem dizer?
【Resposta padrão】                                                           

1.void * (* (* fp1) (int)) [10]; fp1 é um ponteiro, apontando para uma função, o parâmetro desta função é do tipo int, o valor de retorno da função é um ponteiro, este ponteiro aponta para um array, este O array possui 10 elementos, e cada elemento é um ponteiro void *.

2. float (* (* fp2) (int, int, int)) (int); fp2 é um ponteiro, apontando para uma função, o parâmetro desta função é do tipo 3 int, o valor de retorno da função é um ponteiro, este ponteiro Aponte para uma função, o parâmetro desta função é do tipo int, o valor de retorno da função é do tipo float.

3.int (* (* fp3) ()) [10] (); fp3 é um ponteiro, apontando para uma função, o parâmetro desta função está vazio, o valor de retorno da função é um ponteiro, este ponteiro aponta para um array, este array Existem 10 elementos, cada elemento é um ponteiro para uma função, o parâmetro desta função está vazio, o valor de retorno da função é do tipo int.

Pergunta 28: Quantas maneiras existem para alocar memória?   Do "Guia de programação de alta qualidade"

[Resposta de referência]

1. Alocar da área de armazenamento estático . A memória é alocada quando o programa é compilado, e essa memória existe durante todo o período de execução do programa. Por exemplo, variáveis ​​globais.

2. Crie na pilha . Quando a função é executada, as unidades de armazenamento das variáveis ​​locais na função podem ser criadas na pilha, e essas unidades de armazenamento são liberadas automaticamente quando a execução da função termina. A operação de alocação de memória da pilha é incorporada ao conjunto de instruções do processador e é muito eficiente, mas a capacidade de memória alocada é limitada.

3. Alocação do heap , também conhecida como alocação de memória dinâmica. Quando o programa estiver rodando, use malloc ou new para solicitar qualquer quantidade de memória, sendo que o programador é responsável por quando liberar a memória ou excluí-la. O tempo de vida da memória dinâmica é determinado por nós e seu uso é muito flexível, mas apresenta muitos problemas.

Questão 29: O destruidor da classe base não é uma função virtual, que problemas isso trará?

[Consulte a resposta] O destruidor da classe derivada não é usado, o que causará vazamento de recursos.

Questão 30: Qual é a diferença entre variáveis ​​globais e variáveis ​​locais? Como isso é alcançado? Como o sistema operacional e o compilador sabem?

[Resposta de referência]

O ciclo de vida é diferente:

As variáveis ​​globais são criadas e criadas com o programa principal e destruídas quando o programa principal é destruído; as variáveis ​​locais existem dentro da função local ou mesmo no corpo do loop local, portanto, a saída não existe;

O uso é diferente: todas as partes do programa de variável global podem ser usadas após a declaração; as variáveis ​​locais só podem ser usadas localmente; elas são alocadas na área de pilha. 

O sistema operacional e o compilador sabem a localização da alocação de memória.As variáveis ​​globais são alocadas no segmento de dados globais e carregadas quando o programa começa a ser executado. Variáveis ​​locais são alocadas na pilha.

Acho que você gosta

Origin blog.csdn.net/qingzhuyuxian/article/details/107938453
Recomendado
Clasificación