Matrices frente a vectores: similitudes y diferencias introductorias [cerrado]

111

¿Cuáles son las diferencias entre una matriz y un vector en C ++? Un ejemplo de las diferencias podría incluir bibliotecas, simbolismo, habilidades, etc.

Formación

Las matrices contienen un número específico de elementos de un tipo particular. Para que el compilador pueda reservar la cantidad de espacio requerida cuando se compila el programa, debe especificar el tipo y número de elementos que contendrá la matriz cuando se defina. El compilador debe poder determinar este valor cuando se compila el programa. Una vez que se ha definido una matriz, usa el identificador de la matriz junto con un índice para acceder a elementos específicos de la matriz. las [...] matrices tienen un índice cero; es decir, el primer elemento está en el índice 0. Este esquema de indexación es indicativo de la estrecha relación en C ++ entre punteros y matrices y las reglas que el lenguaje define para la aritmética de punteros.

- Referencia de bolsillo de C ++

Vector

Un vector es una secuencia de objetos de tamaño dinámico que proporciona operator[]acceso aleatorio al estilo de una matriz . La función miembro push_backcopia sus argumentos a través del constructor de copia, agrega esa copia como el último elemento en el vector e incrementa su tamaño en uno.pop_backhace exactamente lo contrario, eliminando el último elemento. Insertar o eliminar elementos del final de un vector requiere un tiempo constante amortizado, y insertar o eliminar desde cualquier otra ubicación toma un tiempo lineal. Estos son los conceptos básicos de los vectores. Hay mucho más para ellos. En la mayoría de los casos, un vector debería ser su primera opción sobre una matriz de estilo C. En primer lugar, tienen un tamaño dinámico, lo que significa que pueden crecer según sea necesario. No tiene que hacer todo tipo de investigación para averiguar un tamaño estático óptimo, como en el caso de las matrices C; un vector crece según sea necesario y se puede cambiar de tamaño más grande o más pequeño manualmente si es necesario. En segundo lugar, los vectores ofrecen la comprobación de límites con la atfunción miembro (pero no conoperator[]), de modo que pueda hacer algo si hace referencia a un índice inexistente en lugar de simplemente ver cómo se bloquea el programa o, peor aún, continuar la ejecución con datos corruptos.

- Libro de cocina C ++

Trancot
fuente
Diferencia más básica: hay propósitos para los que el vector es una buena opción.
Jerry Coffin
1
"exhaustivo" y "consise" son ortogonales. Es decir, no solo uno no implica al otro, sino que ni siquiera están en la misma escala.
Lightness Races in Orbit
2
Me molesta mucho la gente que me hace preguntas que son exactamente la información que estoy buscando. Esto sucede con demasiada frecuencia.
Robert Tamlyn

Respuestas:

142

matrices:

  • son una construcción de lenguaje incorporada;
  • vienen casi sin modificaciones de C89;
  • proporcionar solo una secuencia de elementos contigua e indexable ; sin campanas y silbidos;
  • son de tamaño fijo; no puede cambiar el tamaño de una matriz en C ++ (a menos que sea una matriz de POD y esté asignado con malloc);
  • su tamaño debe ser una constante en tiempo de compilación a menos que se asignen dinámicamente;
  • toman su espacio de almacenamiento dependiendo del alcance donde los declare;
  • si se asignan dinámicamente, debe desasignarlos explícitamente;
  • si se asignan dinámicamente, solo obtiene un puntero y no puede determinar su tamaño; de lo contrario, puede usar sizeof(de ahí el modismo común sizeof(arr)/sizeof(*arr), que sin embargo falla silenciosamente cuando se usa inadvertidamente en un puntero);
  • decae automáticamente a punteros en la mayoría de situaciones; en particular, esto sucede al pasarlos a una función, que generalmente requiere pasar un parámetro separado para su tamaño;
  • no se puede devolver desde una función;
  • no se puede copiar / asignar directamente;
  • las matrices dinámicas de objetos requieren un constructor predeterminado, ya que todos sus elementos deben construirse primero;

std::vector:

  • es una clase de plantilla;
  • es una construcción solo de C ++;
  • se implementa como una matriz dinámica ;
  • crece y se encoge dinámicamente;
  • gestionar automáticamente su memoria, que se libera al ser destruida;
  • se puede pasar / devolver desde funciones (por valor);
  • se puede copiar / asignar (esto realiza una copia profunda de todos los elementos almacenados);
  • no se convierte en punteros, pero puede obtener explícitamente un puntero a sus datos ( &vec[0]se garantiza que funcionará como se esperaba);
  • siempre trae junto con la matriz dinámica interna su tamaño (cuántos elementos se almacenan actualmente) y capacidad (cuántos elementos se pueden almacenar en el bloque asignado actualmente);
  • la matriz dinámica interna no se asigna dentro del objeto en sí (que solo contiene algunos campos de "contabilidad"), sino que se asigna dinámicamente por el asignador especificado en el parámetro de plantilla relevante; el predeterminado obtiene la memoria del almacén gratuito (el llamado montón), independientemente de cómo se asigne el objeto real;
  • por esta razón, pueden ser menos eficientes que los arreglos "regulares" para arreglos locales pequeños y de corta duración;
  • al reasignar, los objetos se copian (se mueven, en C ++ 11);
  • no requiere un constructor predeterminado para los objetos que se almacenan;
  • está mejor integrado con el resto de los llamados STL (proporciona los métodos begin()/ end(), los STL habituales typedef, ...)

También considere la "alternativa moderna" a las matrices - std::array; Ya describí en otra respuesta la diferencia entre std::vectory std::array, es posible que desee echarle un vistazo.

Matteo Italia
fuente
1
Gracias, @MatteoItalia. Una referencia o dos estaría bien.
Trancot
1
@Trancot: cualquier buen libro de C ++ servirá.
Matteo Italia
6
@Trancot: Realmente no puedo darte referencias mucho mejores; las diferencias destacadas en esta publicación provienen de muchas partes diferentes del Estándar y se entienden mejor con la ayuda de un buen manual de C ++.
Matteo Italia
¡Un ejemplo de una descripción tan extensa sería genial!
carloswm85
26

Agregaré que las matrices son construcciones de muy bajo nivel en C ++ y debe tratar de mantenerse alejado de ellas tanto como sea posible cuando "aprenda las cuerdas", incluso Bjarne Stroustrup recomienda esto (él es el diseñador de C ++).

Los vectores se acercan mucho al mismo rendimiento que los arreglos, pero con muchas comodidades y características de seguridad. Probablemente comenzará a usar matrices cuando interactúe con API que se ocupen de matrices en bruto, o cuando cree sus propias colecciones.

John Källén
fuente
1
Interfaz del programa de aplicación: ( en.wikipedia.org/wiki/API ). Es una colección de puntos de entrada a una entidad de software (paquete, biblioteca, sistema operativo). Algunas API tendrán puntos de entrada como strcat (char * dst, char * src), donde dst y src se tratan como matrices de caracteres (aunque la firma de la función implica punteros a caracteres).
John Källén
11

Esas referencias prácticamente respondieron a tu pregunta. En pocas palabras, las longitudes de los vectores son dinámicas, mientras que las matrices tienen un tamaño fijo. cuando usa una matriz, especifica su tamaño al momento de la declaración:

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

para los vectores, simplemente declare y agregue elementos

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

a veces no sabrá la cantidad de elementos necesarios, por lo que un vector sería ideal para tal situación.

Nicolas Brown
fuente