Matrizes vs vetores: semelhanças e diferenças introdutórias [fechado]

111

Quais são as diferenças entre uma matriz e um vetor em C ++? Um exemplo das diferenças podem ser bibliotecas, simbolismo, habilidades, etc.

Array

Os arrays contêm um número específico de elementos de um tipo específico. Para que o compilador possa reservar a quantidade necessária de espaço quando o programa for compilado, você deve especificar o tipo e o número de elementos que o array conterá quando for definido. O compilador deve ser capaz de determinar esse valor quando o programa é compilado. Uma vez que um array tenha sido definido, você usa o identificador para o array junto com um índice para acessar elementos específicos do array. [...] arrays são indexados por zero; ou seja, o primeiro elemento está no índice 0. Este esquema de indexação é indicativo do relacionamento próximo em C ++ entre ponteiros e matrizes e as regras que a linguagem define para aritmética de ponteiros.

- Referência de bolso C ++

Vetor

Um vetor é uma sequência de objetos de tamanho dinâmico que fornece operator[]acesso aleatório no estilo array . A função de membro push_backcopia seus argumentos por meio do construtor de cópia, adiciona essa cópia como o último item no vetor e aumenta seu tamanho em um.pop_backfaz exatamente o oposto, removendo o último elemento. A inserção ou exclusão de itens do final de um vetor leva um tempo constante amortizado e a inserção ou exclusão de qualquer outro local leva um tempo linear. Estes são os princípios básicos dos vetores. Há muito mais para eles. Na maioria dos casos, um vetor deve ser sua primeira escolha em vez de uma matriz de estilo C. Em primeiro lugar, eles são dimensionados dinamicamente, o que significa que podem crescer conforme necessário. Você não precisa fazer todos os tipos de pesquisa para descobrir um tamanho estático ideal, como no caso dos arrays C; um vetor cresce conforme necessário e pode ser redimensionado para maior ou menor manualmente, se necessário. Em segundo lugar, os vetores oferecem limites de verificação com a atfunção membro (mas não comoperator[]), para que você possa fazer algo se fizer referência a um índice inexistente, em vez de simplesmente observar o travamento do programa ou pior, continuar a execução com dados corrompidos.

- Livro de receitas C ++

Trancot
fonte
Diferença mais básica: existem objetivos para os quais o vetor é uma boa escolha.
Jerry Coffin
1
"exaustivo" e "consise" são ortogonais. Ou seja, não apenas um não implica o outro, mas eles nem mesmo estão na mesma escala.
Lightness Races in Orbit
2
Fico muito chateado com as pessoas que fecham questões que são exatamente as informações que procuro. Isso acontece com muita frequência.
Robert Tamlyn

Respostas:

142

arrays:

  • são uma construção de linguagem embutida;
  • vem quase inalterado de C89;
  • fornecer apenas uma sequência de elementos contígua e indexável ; sem sinos e assobios;
  • são de tamanho fixo; você não pode redimensionar um array em C ++ (a menos que seja um array de POD e esteja alocado com malloc);
  • seu tamanho deve ser uma constante de tempo de compilação, a menos que sejam alocados dinamicamente;
  • eles ocupam seu espaço de armazenamento dependendo do escopo onde você os declara;
  • se alocados dinamicamente, você deve desalocá-los explicitamente;
  • se eles forem alocados dinamicamente, você apenas obterá um ponteiro e não poderá determinar seu tamanho; caso contrário, você pode usar sizeof(daí o idioma comum sizeof(arr)/sizeof(*arr), que, entretanto, falha silenciosamente quando usado inadvertidamente em um ponteiro);
  • decai automaticamente para ponteiros na maioria das situações; em particular, isso acontece ao passá-los para uma função, o que geralmente requer a passagem de um parâmetro separado para seu tamanho;
  • não pode ser retornado de uma função;
  • não pode ser copiado / atribuído diretamente;
  • arrays dinâmicos de objetos requerem um construtor padrão, uma vez que todos os seus elementos devem ser construídos primeiro;

std::vector:

  • é uma classe de modelo;
  • é uma construção apenas C ++;
  • é implementado como um array dinâmico ;
  • cresce e diminui dinamicamente;
  • gerenciar automaticamente sua memória, que é liberada na destruição;
  • pode ser passado para / retornado de funções (por valor);
  • pode ser copiado / atribuído (isto executa uma cópia profunda de todos os elementos armazenados);
  • não decai para ponteiros, mas você pode obter explicitamente um ponteiro para seus dados ( &vec[0]é garantido que funcione conforme o esperado);
  • sempre traz junto com o array dinâmico interno seu tamanho (quantos elementos estão armazenados atualmente) e capacidade (quantos elementos podem ser armazenados no bloco atualmente alocado);
  • a matriz dinâmica interna não é alocada dentro do próprio objeto (que contém apenas alguns campos de "contabilidade"), mas é alocada dinamicamente pelo alocador especificado no parâmetro de modelo relevante; o padrão obtém a memória do armazenamento livre (o chamado heap), independentemente de como o objeto real é alocado;
  • por esse motivo, eles podem ser menos eficientes do que arrays "regulares" para arrays locais pequenos e de curta duração;
  • ao realocar, os objetos são copiados (movidos, em C ++ 11);
  • não requer um construtor padrão para os objetos que estão sendo armazenados;
  • está melhor integrado com o resto da chamada STL (fornece os métodos begin()/ end(), as STLs usuais typedef, ...)

Considere também a "alternativa moderna" aos arrays - std::array; Já descrevi em outra resposta a diferença entre std::vectore std::array, você pode querer dar uma olhada nisso.

Matteo Italia
fonte
1
Obrigado, @MatteoItalia. Uma referência ou duas seriam boas.
Trancot
1
@Trancot: qualquer bom livro C ++ serve.
Matteo Italia
6
@Trancot: Eu realmente não posso dar referências muito melhores - as diferenças destacadas neste post vêm de várias partes diferentes do Padrão e são melhor compreendidas com a ajuda de um bom manual C ++.
Matteo Italia
Um exemplo de uma descrição tão extensa seria ótimo!
carloswm85
26

Acrescentarei que os arrays são construções de nível muito baixo em C ++ e você deve tentar ficar longe deles o máximo possível ao "aprender o básico" - até mesmo Bjarne Stroustrup recomenda isso (ele é o designer do C ++).

Os vetores têm quase o mesmo desempenho que as matrizes, mas com muitas conveniências e recursos de segurança. Você provavelmente começará a usar arrays ao fazer interface com APIs que lidam com arrays brutos ou ao construir suas próprias coleções.

John Källén
fonte
1
Interface do programa de aplicativo: ( en.wikipedia.org/wiki/API ). É uma coleção de pontos de entrada para uma entidade de software (pacote, biblioteca, sistema operacional). Algumas APIs terão pontos de entrada como strcat (char * dst, char * src), onde dst e src são tratados como matrizes de caracteres (mesmo que a assinatura da função implique ponteiros para caracteres).
John Källén
11

Essas referências praticamente responderam à sua pergunta. Simplificando, os comprimentos dos vetores são dinâmicos, enquanto as matrizes têm um tamanho fixo. ao usar uma matriz, você especifica seu tamanho na declaração:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

para vetores, você apenas declara e adiciona elementos

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

às vezes você não saberá o número de elementos necessários, então um vetor seria ideal para tal situação.

Nicolas Brown
fonte