Archivos de etiquetas: matrices. Tecnología de programación C: representación de matrices, trabajo con archivos y textos Salida de todos los elementos de una matriz rectangular C

En general, no es necesario programar el cálculo de determinantes. Se pueden contar, por ejemplo, mediante la función integrada MOPRED de Excel:

  • recopilamos elementos de la matriz en celdas adyacentes, por ejemplo, en la imagen se muestra una matriz de 4*4;
  • en la celda requerida, ingrese la fórmula (en nuestro caso =MOPRED(A1:D4) y ​​presione Enter:)

No es más difícil calcular en MathCAD: simplemente haga clic en un botón en el panel de matriz...

Pero a veces necesitas un algoritmo, no una respuesta... aquí hay algo de código en la consola C++, no pretende ser perfecto, pero los ceros en la matriz o el orden "incorrecto" de los elementos no deberían confundir la función determinante. Ejemplo de main: el número 1001 para trabajar con una matriz dinámica usando C++ :) El resto está comentado en el código fuente.

#definir bool int #definir verdadero 1 #definir falso 0 búsqueda int (doble **a, int m, int n, doble qué, coincidencia bool, unsigned int &uI, unsigned int &uJ, unsigned int starti, unsigned int startj) ( / / Busca en la matriz a[m][n] un elemento con el valor especificado what // Su número de fila y columna uI, uJ se devuelve si se encuentra el elemento // coincidencia - busca un elemento igual o diferente. del especificado // Devuelve 0 - no encontrado, no 0 - encontrado if ((!m) || (!n)) return 0 if ((starti >= n) || (startj >= m)) devolver 0; para (unsigned int i = starti; i< n; i++) for (unsigned int j = startj; j < m; j++) { if (match == true) { if (a[i][i] == what) { uI = i; uJ = j; return 1; } } else if (a[i][j] != what) { uI = i; uJ = j; return 1; } } return 0; } void swaprows (double **a, int n, int m, unsigned int x1, unsigned int x2) { //Меняет в матрице a[n][m] строки с номерами x1 и x2 местами if ((!n) || (!m)) return; if ((x1 >= norte) || (x2 >= n) || (x1 == x2)) retorno;< m; x++) { tmp = a[x]; a[x] = a[x]; a[x] = tmp; } return; }; void swapcolumns (double **a, int n, int m, unsigned int x1, unsigned int x2) { //Меняет в матрице a[n][m] столбцы с номерами x1 и x2 местами if ((!n) || (!m)) return; if ((x1 >doble temperatura;< n; x++) { tmp = a[x]; a[x] = a[x]; a[x] = tmp; } return; }; double determinant (double **a, unsigned int n) { //Вычисление определителя квадратной матрицы a[n][n] unsigned int m = n; if (m == 0) return 0; if (m == 1) return a; if (m == 2) return (a * a - a * a); bool sign = false; // смена знака определителя. по умолчанию - нет double det = 1; // определитель double tmp; unsigned int x, y; for (unsigned int i = 0; i < n; i++) { // цикл по всей главной диагонали if (a[i][i] == 0) { // если элемент на диагонали равен 0, то ищем ненулевой элемент в матрице if (!search(a,m,n,0, false, y, x, i, i)) return 0; // если все элементы нулевые, то опр. = 0 if (i != y) { // меняем i-ую строку с y-ой swaprows(a,m,n,i, y); sign = !sign; } if (i != x) { // меняем i-ый столбец с x-ым swapcolumns(a,m,n,i, x); sign = !sign; } // таким образом, в a[i][i], теперь ненулевой элемент. } // выносим элемент a[i][i] за определитель det *= a[i][i]; tmp = a[i][i]; for (x = i; x < m; x++) { a[i][x] = a[i][x] / tmp; } // таким образом a[i][i] теперь равен 1 // зануляем все элементы стоящие под (i, i)-ым, // при помощи вычитания с опр. коеффициентом for (y = i + 1; y < n; y++) { tmp = a[y][i]; for (x = i; x < m; x++) a[y][x] -= (a[i][x]*tmp); } } if (sign) return det*(-1); return det; }; #include para (int sin signo x = 0; x

= metro) || (x2 >= metro) || (x1 == x2)) retorno; Se dan formas correctas e incorrectas de implementar matrices y arreglos multidimensionales en el lenguaje C. El trabajo con matrices se ilustra con el ejemplo de cómo reducir una matriz a una forma gradual utilizando el método gaussiano. Describe métodos para trabajar con archivos usando funciones de E/S de la biblioteca estándar ANSI. Muestra cómo trabajar con caracteres y cadenas de texto utilizando funciones de biblioteca estándar. El material está ilustrado con ejemplos, incluido el programa "wc" para contar caracteres, palabras y líneas en un archivo y el programa "Libreta de direcciones", que le permite encontrar el número de teléfono de una persona por su nombre, así como guardarlo y modificarlo. el contenido del libro.

Representación de matrices y arreglos multidimensionales.

tipo de datos especiales matriz o matriz multidimensional en C no existe, sin embargo, puedes usar una matriz de elementos del tipo matriz. Por ejemplo, la variable a representa una matriz de 3x3 con elementos reales:

Los elementos de la matriz se ubican en la memoria secuencialmente en filas: primero hay elementos de fila con índice 0, luego filas con índice 1 y al final de la fila con índice 2 (en programación, el conteo de índices siempre comienza desde cero, no ¡de uno!). En este caso, la expresión

donde i es una variable entera, es un puntero al elemento inicial de la i-ésima línea y es de tipo doble*.

Para acceder a un elemento de matriz, debe escribir sus índices entre corchetes, por ejemplo, la expresión

representa un elemento de la matriz a en el índice de fila i y la columna en el índice j. Un elemento de matriz se puede utilizar en cualquier expresión como variable regular (por ejemplo, puede leer su valor o asignar uno nuevo).

Esta implementación de la matriz es conveniente y más eficiente en términos de tiempo de acceso a los elementos. Sólo tiene un inconveniente importante: de esta forma sólo se puede implementar una matriz cuyo tamaño se conoce de antemano. El lenguaje C no permite describir matrices de tamaño variable; el tamaño de la matriz debe conocerse antes de que el programa comience a ejecutarse, en la etapa de compilación.

Supongamos que necesitamos una matriz cuyo tamaño se determina mientras se ejecuta el programa. Luego, el espacio correspondiente debe capturarse en la memoria dinámica utilizando la función malloc del lenguaje C o el nuevo operador del lenguaje C++. En este caso, se captura una matriz lineal en la memoria dinámica y se devuelve un puntero a ella. Considere una matriz real de m filas por n columnas. La adquisición de memoria se realiza utilizando la función C malloc

doble *a; . . . a = (doble *) malloc(m * n * tamaño de (doble));

o usando el nuevo operador de C++:

doble *a; int m, n; . . . a = nuevo doble;

En este caso, se supone que los elementos de la matriz se ubicarán en la matriz de la siguiente manera: primero están los elementos de fila con índice 0, luego los elementos de fila con índice 1, etc., y por último están los elementos de fila con índice m - 1. Cada fila consta de n elementos, por lo tanto, el índice de elementos de la fila i y la columna j en una matriz lineal es

(de hecho, dado que los índices comienzan desde cero, i es igual al número de filas que deben omitirse, i * n es el número total de elementos en las filas omitidas; el número j es igual al desplazamiento dentro de la última fila) . Por tanto, el elemento de la matriz en la fila i y la columna j corresponde a la expresión

Este método de representar una matriz es conveniente y eficaz. Su principal ventaja es que los elementos de la matriz se almacenan en continuo segmento de memoria. En primer lugar, permite al compilador optimizador transformar el texto del programa, logrando el máximo rendimiento; en segundo lugar, al ejecutar el programa se aprovecha al máximo el mecanismo de la memoria caché, minimizando los accesos a la memoria y acelerando significativamente el programa.

Algunos libros de C recomiendan implementar una matriz como una matriz de punteros a sus filas, con la memoria para cada fila capturada por separado en la memoria dinámica:

doble **a; // Dirección de una matriz de punteros int m, n; // Dimensiones de la matriz: m filas, n columnas int i; . . . // Captura memoria para una matriz de punteros a = (double **) malloc(m * sizeof(double *)); para (yo = 0; yo< m; ++i) { // Захватывается память под строку с индексом i a[i] = (double *) malloc(n * sizeof(double)); }

Luego se puede acceder al elemento a ij usando la expresión

A pesar de la complejidad de esta solución, no se gana nada; al contrario, ¡el programa pierde velocidad! La razón es que la matriz no se almacena en un área contigua de la memoria, lo que interfiere tanto con la optimización del programa como con el uso eficiente de la memoria caché. Por tanto, es mejor no utilizar este método de representación matricial.

Las matrices multidimensionales se implementan de manera similar a las matrices. Por ejemplo, una matriz tridimensional real de tamaño 4 x 4 x 2 se describe como

el acceso a su elemento con índices x, y, z se realiza mediante la expresión

Las matrices multidimensionales de tamaño variable con un número de índices mayor que dos son bastante raras en los programas, pero no hay problemas con su implementación: se implementan de manera similar a las matrices. Por ejemplo, digamos que necesitamos implementar una matriz real tridimensional de tamaño m x n x k. Se captura una matriz lineal de números reales de tamaño m * n * k:

doble *a;

. . .

a = (doble *) malloc(m * n * k * tamaño de (doble));

Se accede a un elemento con índices x, y, z mediante una expresión

a[(x * n + y) * k + z]

Ejemplo: reducir una matriz a una forma gradual utilizando el método gaussiano

  1. Como ejemplo de trabajo con matrices, considere el algoritmo gaussiano para reducir una matriz a una forma gradual. El método de Gauss es uno de los principales resultados del álgebra lineal y de la geometría analítica; a él se reducen muchos otros teoremas y métodos del álgebra lineal (teoría y cálculo de determinantes, solución de sistemas de ecuaciones lineales, cálculo del rango de una matriz y matriz inversa, teoría de bases de espacios vectoriales de dimensión finita, etc.).
  2. Recuerde que una matriz A con elementos a ij se llama por pasos si tiene las dos propiedades siguientes:< j . Тогда все элементы в j -м столбце ниже элемента a ij равны нулю, и все элементы левее и ниже a ij также равны нулю: a kl = 0 при k >si hay una fila cero en una matriz, entonces todas las filas debajo de ella también son cero;< j .

sea ​​un ij distinto de 0 el primer elemento distinto de cero en la fila con índice i, es decir elementos a il = 0 para l

yo y l =

La matriz de pasos se parece a esto:

  • aquí los primeros elementos distintos de cero de las filas de la matriz están marcados con cuadrados oscuros. Los elementos cero se representan en blanco, los elementos arbitrarios se representan en gris. El algoritmo gaussiano utiliza dos tipos de transformaciones matriciales elementales.
  • Transformación del primer tipo.: se intercambian dos filas de la matriz y se invierten los signos de todos los elementos de una de las filas.

Transformación del segundo tipo. : se suma otra fila a una fila de la matriz, multiplicada por un número arbitrario. Las transformaciones elementales preservan el determinante y el rango de la matriz, así como el conjunto solución del sistema lineal. El algoritmo de Gauss reduce una matriz arbitraria a una forma escalonada mediante transformaciones elementales. Para una matriz cuadrada escalonada, el determinante es igual al producto de los elementos diagonales y el rango es el número de filas distintas de cero (por definición, el rango es la dimensión

caparazón lineal de cuerdas

  1. matrices). El método de Gauss en su versión matemática es el siguiente: elemento en la primera columna. Si todos los elementos de la primera columna son cero, entonces pasa a la segunda columna y así sucesivamente. Si encontramos un elemento distinto de cero en la k-ésima fila, entonces usando una transformación elemental del primer tipo intercambiamos la primera y la k-ésima fila, asegurándonos de que el primer elemento de la primera fila sea diferente de cero;
  2. Utilizando transformaciones elementales del segundo tipo, restablecemos todos los elementos de la primera columna, comenzando por el segundo elemento. Para hacer esto, reste la primera línea de la línea número k, multiplicada por el coeficiente a k1 /a 11.
  3. vamos a la segunda columna (o j-ésima, si todos los elementos de la primera columna fueran cero), y en el futuro consideramos solo una parte de la matriz, comenzando desde la segunda fila hacia abajo. Repetimos los puntos 1) y 2) nuevamente hasta reducir la matriz a una forma escalonada.

La versión para programadores del método Gauss tiene tres diferencias con respecto a la matemática:

r = -a kj /a ij . ak = ak + r * ai

Este esquema normalmente funciona sólo cuando el coeficiente r en valor absoluto no excede la unidad. De lo contrario, los errores de redondeo se multiplican por un factor grande y, por tanto, crecen exponencialmente. Los matemáticos llaman a este fenómeno inestabilidad circuito computacional. Si el esquema computacional es inestable, entonces los resultados obtenidos con su ayuda no tienen relación con el problema original. En nuestro caso, el esquema es estable cuando el coeficiente r = -a kj /a ij no supera la unidad en valor absoluto. Para hacer esto, se debe satisfacer la desigualdad.

|a ij | >= |a kj | para k > yo

De ello se deduce que al buscar un elemento de resolución en la j-ésima columna, es necesario encontrar no el primer elemento encontrado distinto de cero, sino máximo en valor absoluto. Si su módulo no excede , entonces asumimos que todos los elementos de la columna son cero; de lo contrario, intercambiamos las filas, colocándolas en la parte superior de la columna y luego restablecemos la columna mediante transformaciones elementales del segundo tipo.

A continuación se muestra el texto completo del programa en C que reduce una matriz real a forma escalonada. La función que implementa el método gaussiano calcula simultáneamente el rango de la matriz. El programa ingresa las dimensiones de la matriz y sus elementos desde el teclado y llama a la función de reducción a forma escalonada. Luego, el programa imprime la vista escalonada de la matriz y su rango. En el caso de una matriz cuadrada, también se calcula e imprime. determinante de la matriz, igual al producto de los elementos diagonales de la matriz escalonada.

Al implementar el método de Gauss, se utiliza un esquema de construcción de ciclo que utiliza un invariante, consulte la sección 1.5.2. Se cambian dos variables en el bucle: índice de fila i, 0 =< i < m - 1 , и индекс столбца j , 0 =< j < n - 1 . Инвариантом цикла является утверждение о том, что часть матрицы (математики говорят menor) en las columnas 0,1,...j - 1 se reduce a una forma escalonada y que el primer elemento distinto de cero en la fila i - 1 está en la columna con un índice menor que j . En el cuerpo del bucle, solo se considera el menor de la matriz en las filas i,...,m - 1 y las columnas j,...,n - 1. Primero, se busca el elemento con el valor absoluto máximo en la columna j. Si no excede en valor absoluto, entonces j se incrementa en uno (la columna se considera cero). De lo contrario, al reorganizar las filas, el elemento de resolución se coloca en la parte superior de la j-ésima columna del menor, y luego la columna se restablece a cero mediante transformaciones elementales del segundo tipo. Después de esto, ambos índices i y j se incrementan en uno. El algoritmo termina cuando i = m o j = n. Al final del algoritmo, el valor de la variable i es igual al número de filas distintas de cero de la matriz de pasos, es decir rango de la matriz original.

Para calcular el valor absoluto de un número real x de tipo doble, utilizamos la función matemática estándar fabulosos(x), descrito en el archivo de encabezado estándar " math .h.

#incluir // Descripciones de funciones de E/S #include // Descripciones de funciones matemáticas #include // Descripciones de las funciones malloc y free // Un prototipo de la función para reducir una matriz // a forma escalonada. // La función devuelve el rango de la matriz int gaussMethod(int m, // Número de filas de la matriz int n, // Número de columnas de la matriz double *a, // Dirección del array de elementos de la matriz double eps // Precisión del cálculo); int main() ( int m, n, i, j, rango; double *a; double eps, det; printf("Ingrese las dimensiones de la matriz m, n: "); scanf("%d%d", &m, &n ); // Capturar memoria para elementos de la matriz a = (double *) malloc(m * n * sizeof(double));< m; ++i) { for (j = 0; j < n; ++j) { // Вводим элемент с индексами i, j scanf("%lf", &(a)); } } printf("Введите точность вычислений eps: "); scanf("%lf", &eps); // Вызываем метод Гаусса rank = gaussMethod(m, n, a, eps); // Печатаем ступенчатую матрицу printf("Ступенчатый вид матрицы:\n"); for (i = 0; i < m; ++i) { // Печатаем i-ю строку матрицы for (j = 0; j < n; ++j) { printf(// Формат %10.3lf означает 10 "%10.3lf ", // позиций на печать числа, a // 3 знака после точки); } printf("\n"); // Перевести строку } // Печатаем ранг матрицы printf("Ранг матрицы = %d\n", rank); if (m == n) { // Для квадратной матрицы вычисляем и печатаем // ее определитель det = 1.0; for (i = 0; i < m; ++i) { det *= a; } printf("Определитель матрицы = %.3lf\n", det); } free(a); // Освобождаем память return 0; // Успешное завершение программы } // Приведение вещественной матрицы // к ступенчатому виду методом Гаусса с выбором // максимального разрешающего элемента в столбце. // Функция возвращает ранг матрицы int gaussMethod(int m, // Число строк матрицы int n, // Число столбцов матрицы double *a, // Адрес массива элементов матрицы double eps // Точность вычислений) { int i, j, k, l; double r; i = 0; j = 0; while (i < m && j < n) { // Инвариант: минор матрицы в столбцах 0..j-1 // уже приведен к ступенчатому виду, и строка // с индексом i-1 содержит ненулевой эл-т // в столбце с номером, меньшим чем j // Ищем максимальный элемент в j-м столбце, // начиная с i-й строки r = 0.0; for (k = i; k < m; ++k) { if (fabs(a) >r) ( l = k; // Recuerda el número de línea r = fabs(a); // y elemento máximo ) ) if (r<= eps) { // Все элементы j-го столбца по абсолютной // величине не превосходят eps. // Обнулим столбец, начиная с i-й строки for (k = i; k < m; ++k) { a = 0.0; } ++j; // Увеличим индекс столбца continue; // Переходим к следующей итерации } if (l != i) { // Меняем местами i-ю и l-ю строки for (k = j; k < n; ++k) { r = a; a = a; a = (-r); // Меняем знак строки } } // Утверждение: fabs(a) >eps // Restablece la j-ésima columna, comenzando desde la fila i+1, // usando element. transformaciones de segundo tipo para (k = i+1; k< m; ++k) { r = (-a / a); // К k-й строке прибавляем i-ю, умноженную на r a = 0.0; for (l = j+1; l < n; ++l) { a += r * a; } } ++i; ++j; // Переходим к следующему минору } return i; // Возвращаем число ненулевых строк }

Por supuesto, puedes reconstruir matrices a partir de los datos de entrada, multiplicarlas de forma trivial y mostrar el resultado en una forma determinada. Como ejemplo de un mal estilo de programación: un algoritmo ingenuo consume casi el doble de memoria y tiene un rendimiento significativamente inferior. Existe otra solución, a la que se puede llegar adaptando secuencialmente las operaciones matriciales estándar al formato de los datos de entrada.

La mayor dificultad, tanto computacional como conceptualmente, es la multiplicación de matrices, en este caso la elevación al cuadrado. La siguiente secuencia de pasos le permitirá multiplicar matrices simétricas utilizando su representación lineal en el formato de datos de origen.

Nota 1

El subespacio de matrices simétricas no está cerrado bajo la multiplicación: el producto de dos matrices simétricas puede ser una matriz asimétrica.

Ejemplo

\left(\begin(array)(ccc) 1 y 1 y 3 \\ 1 y 4 y 5 \\ 3 y 5 y 0\end(array) \right) \cdot \left(\begin(array)(ccc) ) 4 y 0 y 0 \\ 0 y 4 y 3 \\ 0 y 3 y 2 \end(array) \right) = \left(\begin(array)(ccc) 4 y 13 y 9 \\ 4 y 31 & 22 \\ 12 & 20 & 15 \end(array) \right)

Nota 2

El grado de una matriz simétrica también es una matriz simétrica. La demostración se basa en la representación de una matriz como representación de un operador lineal y en las propiedades de los operadores hermitianos.

En todos los cálculos posteriores se supone que la matriz está representada por una matriz lineal de \frac(n(n+1))(2) elementos.

Para empezar, observamos que el elemento c_(i,j) de la matriz C=A^(2) es igual al producto escalar (como vectores en la base estándar) de la i-ésima fila de la matriz A por su j-ésima fila (debido al hecho de que en una matriz simétrica, la j-ésima fila coincide con la j-ésima columna). Por tanto, para elevar una matriz simétrica a una potencia, es necesario y suficiente implementar la operación de multiplicación escalar de sus dos filas.

Entonces necesitas entender cómo obtener su i-ésima fila a partir de una representación matricial determinada. Por conveniencia, escribimos los elementos disponibles en forma de una matriz completa. Tenga en cuenta que el primer elemento de la i-ésima fila será el i-ésimo elemento de la primera fila y generalice esta observación. Denotemos la posición del elemento actual que nos interesa en la i-ésima fila como j. si j< i, то следует выбрать i-ый элемент j-ой строки, иначе следует выбрать все элементы j-ой строки, лежащие правее данного. Графически можно интерпретировать алгоритм таким образом: начиная с i-го элемента первой строки, спускаться вертикально вниз по матрице до тех пор, пока не будет достигнута i-ая строка, далее — двигаться вправо до конца строки. Наглядность алгоритма позволяет легко воплотить его программно.
Solo necesita observar cómo las distancias entre los elementos que se encuentran uno debajo del otro cambian al moverse hacia abajo en las filas de la matriz, lo que facilitará la transferencia del algoritmo a la representación lineal de la matriz triangular superior. Invitamos al lector a realizar este sencillo pero visual ejercicio para una mejor comprensión del algoritmo.

Ahora puedes ir directamente a la implementación.

I. ¿A quién está destinado el módulo?

Este módulo está diseñado para estudiantes de secundaria o pregrado. Debe dominar temas como trabajar con bucles, con punteros, necesita saber qué es una matriz unidimensional.

II. Motivación

Ya sabemos por qué podríamos necesitar matrices unidimensionales. Por ejemplo, podemos almacenar los coeficientes de una ecuación cuadrática en una matriz unidimensional y calcular las raíces usando el discriminante. ¿Qué pasa si necesitamos calcular muchas de esas ecuaciones? ¿Es realmente posible reescribir nuevos coeficientes en lugar de los antiguos cada vez? ¿Y si es necesario volver a los ya calculados? O necesitamos resolver un sistema de varias ecuaciones, es decir ¿Necesitas trabajar con todos al mismo tiempo? Si sólo necesitamos almacenar una tabla de algunos valores, por ejemplo, mediciones durante un experimento, ¿cómo podemos hacerlo utilizando el conocimiento que ya hemos adquirido?

Para cada uno de los casos anteriores, simplemente puede declarar varias matrices unidimensionales, pero ¿será agradable trabajar con tantas? Después de todo, cada uno deberá nombrarse y procesarse por separado. La situación es similar a la que acabamos de presentar el concepto de matriz unidimensional. Aquí es donde las matrices bidimensionales vienen al rescate.

III. Presentación del material del módulo.

La representación habitual de tales matrices es mesas valores que contienen información en pauta Y columnas. Para definir un único elemento de tabla, debe especificar dos índices: el primero (por convención) especifica el número de fila y el segundo (nuevamente por convención) especifica el número de columna.

La figura ilustra una matriz bidimensional. a. La matriz contiene tres filas y cuatro columnas, por lo que también se dice que es una matriz de tres por cuatro. En general, las matrices con metro líneas y norte las columnas se llaman matrices metro en norte.

Cada elemento de la matriz A determinado por el nombre del elemento en la forma a[ i ][ j ]; a este es el nombre de la matriz, y i Y j– índices que identifican de forma única cada elemento en A. Tenga en cuenta que los nombres de los elementos de la primera fila tienen un primer índice 0 , los nombres de los elementos en la cuarta columna tienen un segundo índice 3 .

Error de programación típico

Referencia no válida a un elemento de una matriz bidimensional a[ incógnita] [ y] Cómo a[ incógnita, y]. De hecho, a[ incógnita, y] percibido como a[ y] , porque C evalúa una expresión (que contiene una operación seguida de coma) incógnita, y al igual que y(la última de las expresiones separadas por comas).

Las matrices multidimensionales se pueden inicializar en sus declaraciones al igual que las matrices indexadas de forma natural. Por ejemplo, una matriz bidimensional b puedes declarar y darle valores iniciales como este:

int b = ((1,2), (3,4));

Los valores se agrupan en cadenas encerradas entre llaves. Entonces los elementos b Y b recibir los valores iniciales 1 y 2, y los elementos b Y b obtenga los valores iniciales 3 y 4. Si los valores iniciales en una línea determinada no son suficientes para asignarlos a todos los elementos de la línea, a los elementos restantes se les asignan valores iniciales cero. Entonces el anuncio

intb = ((1,),(3,4));

significará que b obtiene el valor inicial 1, b obtiene el valor inicial 0.

La cantidad de memoria en bytes que ocupa una matriz bidimensional se calcula mediante la siguiente fórmula:

Número de bytes = 1.ª dimensión_tamaño*2.ª dimensión_tamaño*tamaño de (tipo base)

Por ejemplo, una matriz bidimensional de enteros de 4 bytes con dimensiones 10*5 ocupa un área de memoria de

es decir, 200 bytes.

Pasar una matriz a una función.

Considere un pequeño programa para mostrar los elementos de una matriz bidimensional:

#incluir

matriz de impresión vacía (int a)

para (int i = 0; i<=1;i++)

para (int j=0; j<=2; j++)

printf(“%i, ”,&a[i][j]);

printf(“\n”);

matriz int = ((1,2,3),(4,5,6));

printf(“Valores en matriz en filas:”);

printgArray(matriz);

Valores en matriz en filas:

El programa llama a la función. imprimirmatriz para mostrar elementos de la matriz. Tenga en cuenta que la descripción de la función especifica el parámetro de matriz como enteroa. Cuando especificamos una matriz unidimensional como argumento de función, los paréntesis en la lista de parámetros de función están vacíos. Tampoco se requiere la dimensión del primer índice de una matriz multidimensional, pero sí todas las dimensiones de índice posteriores. El compilador utiliza las dimensiones de estos índices para determinar las ubicaciones de memoria apropiadas para acceder a elementos de matrices multidimensionales. En la memoria, todos los elementos de la matriz se almacenan secuencialmente, independientemente del número de índices (tamaño de la matriz). En una matriz bidimensional, la primera fila se almacena en la memoria antes que la segunda fila.

Tener dimensiones de índice en una declaración de parámetro permite al compilador decirle a la función cómo están organizados los elementos en la matriz. En una matriz bidimensional, cada fila es una matriz unidimensional. Para localizar un elemento en alguna fila, la función debe saber exactamente cuántos elementos hay en cada fila. Luego, la función puede omitir el número correspondiente de celdas de memoria al acceder a la matriz. Así, al acceder a La función sabe que para acceder a la segunda fila (línea 1), necesita omitir tres elementos de la primera línea en la memoria y luego acceder al tercer elemento de esa línea (elemento 2).

Muchas operaciones de matriz comunes utilizan la construcción para. Entonces, el siguiente bucle determina la suma de todos los elementos de la matriz. a:

para (fila = 0; fila< 3; row++)

para (columna = 0; columna< 3; column ++)

total += un ;

Estructura interna para suma los elementos de una fila de una matriz. Estructura externa para comienza con la instalación fila(es decir, índice de fila) a cero, de modo que en la estructura interna para Los elementos de la segunda fila se pueden sumar. La siguiente es la estructura externa. para aumenta fila al valor 2 para que se puedan sumar los elementos de la tercera fila. Una vez completada la estructura anidada para se imprime el resultado.

Tarea

Una vez, los estudiantes de una de las universidades discutieron sobre quién tenía el puntaje promedio más alto en la sesión que acababan de aprobar. Al mismo tiempo, querían saber quiénes recibían las mejores y peores notas. Para divertirnos, imaginemos que vivimos en Estados Unidos y las calificaciones se dan en una escala de 100 puntos.

Nota:

El programa debe “conocer” los nombres de los estudiantes y mostrarlos en la pantalla. Lo mismo con la boleta de calificaciones. Se supone que los números de columna son equivalentes a los números de examen.

Reflexiones sobre la solución de un problema.

Primero, determinemos qué necesitamos para resolver este problema. Lo primero que notamos es que la condición dice explícitamente la palabra "tabla". Esto significa que lo más probable es que utilicemos una matriz bidimensional para trabajar con él. Cada línea que contiene es la actuación de un estudiante individual. Como se indica en la condición, el número de columna determinará el número del examen aprobado, el número de fila determinará el estudiante. Es con esta matriz con la que trabajaremos, calculando la puntuación media, mínima y máxima. Se puede observar que será necesario crear tres funciones para obtener los datos que necesitamos y una función para mostrar la tabla de calificaciones en pantalla. Ya sabemos todo lo que necesitamos para escribir esta parte del programa.

Ahora veamos los nombres. Sería una buena idea ordenarlos en una tabla para que el número del estudiante pueda usarse para determinar su nombre y viceversa. Ya lo sabemos. Que una cadena es una matriz unidimensional de caracteres. Esto significa que puede crear una matriz bidimensional en la que el número de fila determinará el número del estudiante y el número de columna determinará la letra correspondiente del nombre.

Pero luego tendrás que crear una matriz con la mayor cantidad de celdas horizontales posible. Es decir, si tenemos cuatro alumnos:


Luego necesitarás crear una tabla similar a la que se muestra en la figura:

Al resolver problemas con una gran cantidad de datos del mismo tipo, el uso de variables con diferentes nombres que no están ordenados por direcciones de memoria dificulta la programación. En tales casos, el lenguaje C utiliza objetos llamados matrices.

es una pieza de memoria contigua que contiene una secuencia de objetos del mismo tipo, indicados por un nombre.

La matriz se caracteriza por los siguientes conceptos básicos:

Elemento de matriz (valor del elemento de matriz)– un valor almacenado en una celda de memoria específica ubicada dentro de la matriz, así como la dirección de esta celda de memoria.
Cada elemento de la matriz se caracteriza por tres valores:

  • dirección del elemento: la dirección de la celda de memoria inicial en la que se encuentra este elemento;
  • índice del elemento (número ordinal del elemento en la matriz);
  • valor del elemento.

Dirección de matriz: la dirección del elemento inicial de la matriz.

El nombre de la matriz es un identificador que se utiliza para hacer referencia a los elementos de la matriz.

Tamaño de la matriz: número de elementos de la matriz

El tamaño del elemento es el número de bytes ocupados por un elemento de la matriz.

Gráficamente, la ubicación de la matriz en la memoria de la computadora se puede representar como una franja continua de direcciones.

La matriz que se muestra en la figura contiene q elementos con índices de 0 a q-1. Cada elemento ocupa k bytes en la memoria de la computadora y la disposición de los elementos en la memoria es secuencial.

Las direcciones del i-ésimo elemento de la matriz son

La dirección de la matriz es la dirección del elemento inicial (cero) de la matriz. Para acceder a los elementos de la matriz, se utiliza el número de serie (índice) del elemento, cuyo valor inicial es 0. Entonces, si una matriz contiene q elementos, entonces los índices de los elementos de la matriz varían de 0 a q-1.

La longitud de la matriz es la cantidad de bytes asignados en la memoria para almacenar todos los elementos de la matriz.

Longitud de la matriz = Tamaño del elemento * Número de elementos

La función se puede utilizar para determinar el tamaño de un elemento de matriz.

int tamaño de (tipo);

Por ejemplo,

tamaño de (carácter) = 1;
tamaño de (int) = 4;
tamaño de (flotante) = 4;
tamaño de (doble) = 8;

Declarar e inicializar matrices

Para declarar una matriz en C, se utiliza la siguiente sintaxis:

escriba nombre[dimensión]=(init);

La inicialización es un conjunto de valores iniciales de los elementos de la matriz, especificados entre llaves, separados por comas.

int a = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // matriz a de 10 enteros

Si el número de valores de inicialización especificados entre llaves es menor que el número de elementos de la matriz especificados entre corchetes, entonces todos los elementos restantes de la matriz (para los cuales no había suficientes valores de inicialización) serán cero. Esta propiedad es conveniente para establecer todos los elementos de una matriz en valores cero.

int b = (0); // matriz b de 10 elementos inicializada a 0


Si la matriz se inicializa cuando se declara, entonces los valores iniciales constantes de sus elementos se indican separados por comas entre llaves. En este caso, se puede omitir el número de elementos entre corchetes.

int a = (1, 2, 3, 4, 5, 6, 7, 8, 9);

Al acceder a los elementos de la matriz, el índice del elemento requerido se indica entre corchetes.

Ejemplo en C

1
2
3
4
5
6
7
8

#incluir
int principal()
{
int a = (5, 4, 3, 2, 1); // la matriz a contiene 5 elementos
printf("%d %d %d %d %d\n" , a, a, a, a, a);
getchar();
devolver 0;
}

Resultado de la ejecución del programa:

Sin embargo, a menudo es necesario establecer los valores de los elementos de la matriz durante la ejecución del programa. Esto utiliza una declaración de matriz sin inicialización. En este caso es obligatorio indicar el número de elementos entre corchetes.

ent a;

A menudo se utiliza un bucle paramétrico para establecer los valores iniciales de los elementos de la matriz:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


#incluir
int principal()
{
ent a;
ent i;
// Ingresando elementos de la matriz
para (yo = 0; yo<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
// elementos de la matriz de salida
para (yo = 0; yo<5; i++)
printf("%d ", a[i]); // se requiere espacio en el formato de impresión
getchar(); getchar();
devolver 0;
}

Resultado de la ejecución del programa.

matrices multidimensionales

Las matrices multidimensionales también se pueden declarar en C. La diferencia entre una matriz multidimensional y unidimensional es que en una matriz unidimensional la posición de un elemento está determinada por un índice, y en una matriz multidimensional, por varios. Un ejemplo de matriz multidimensional es una matriz.

Forma general de declarar una matriz multidimensional.

escriba nombre[dimensión1][dimensión2]...[dimensiónm];

Los elementos de una matriz multidimensional están ubicados en sucesivas celdas RAM en orden de dirección ascendente. En la memoria de la computadora, los elementos de una matriz multidimensional están dispuestos en una fila, por ejemplo una matriz con 2 filas y 3 columnas,

ent a;


se ubicará en la memoria de la siguiente manera

El número total de elementos en la matriz bidimensional dada se determina como

Número de filas * Número de columnas = 2 * 3 = 6.

El número de bytes de memoria necesarios para acomodar la matriz está dado por

Número de elementos * Tamaño del elemento = 6 * 4 = 24 bytes.

Inicializando matrices multidimensionales

Los valores de los elementos de una matriz multidimensional, como en el caso unidimensional, se pueden especificar mediante valores constantes cuando se declaran, entre llaves (). Sin embargo, en este caso, el número de elementos en filas y columnas debe indicarse entre corchetes.

Ejemplo en C

1
2
3
4
5
6
7
8
9

#incluir
int principal()
{
int a = (1, 2, 3, 4, 5, 6);
printf("%d %d %d\n" , a, a, a);
getchar();
devolver 0;
}



Sin embargo, con mayor frecuencia es necesario ingresar los valores de los elementos de una matriz multidimensional durante la ejecución del programa. Para ello, es conveniente utilizar un bucle paramétrico anidado.

Ejemplo en C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#definir _CRT_SECURE_NO_WARNINGS
#incluir
int principal()
{
ent a; // matriz de 2 filas y 3 columnas
int i, j;
// Ingresando elementos de la matriz
para (yo = 0; yo<2; i++) // recorrer las líneas
{
para (j = 0; j<3; j++) // recorrer las columnas
{
printf("a[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
// elementos de la matriz de salida
para (yo = 0; yo<2; i++) // recorrer las líneas
{
para (j = 0; j<3; j++) // recorrer las columnas
{
printf("%d ", a[i][j]);
}
printf("\n"); // nueva línea
}
getchar(); getchar();
devolver 0;
}



Pasar una matriz a una función

El procesamiento de matrices se puede organizar cómodamente mediante funciones especiales. Para procesar un array, debes pasar como argumentos a la función

  • dirección de matriz,
  • tamaño de la matriz.

La excepción son las funciones de procesamiento de cadenas, donde basta con pasar sólo la dirección.

Cuando se pasan variables como argumentos a una función, los datos se pasan como copias. Esto significa que si el valor de un parámetro cambia dentro de una función, esto no afectará su valor dentro de la función que llama.

Si se pasa una dirección de variable (o dirección de matriz) a una función, entonces todas las operaciones realizadas en la función en datos dentro del alcance de la dirección especificada se realizan en los datos originales, por lo que la matriz original (o valor de variable) se puede cambiar por la función llamada.

Ejemplo en C Dan matriz de 10 elementos. Intercambie los elementos más grandes y iniciales de la matriz. Para operaciones máximas de búsqueda e intercambio de elementos, utilice la función.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#definir _CRT_SECURE_NO_WARNINGS
#incluir
// función de intercambio
cambio vacío (int *x, int n)
{
// x - puntero a la matriz (dirección de la matriz)
// n - tamaño de la matriz
ent i;
int máx, índice;
máx = x;
índice = 0;
//Encontrar el elemento máximo
para (yo = 1; yo {
si (x[i]>máx)
{
máximo = x[i];
índice = i;
}
}
// Intercambio
x = x;
x = máximo;
}
// función principal
int principal()
{
ent a;
ent i;
para (yo = 0; yo<10; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
cambio(a, 10); // llama a la función de intercambio
// elementos de la matriz de salida
para (yo = 0; yo<10; i++)
printf("%d ", a[i]);
getchar();
getchar();
devolver
p = p * x[i];
}
devolver p;
}
// función principal
int principal()
{
ent a; // matriz declarada de 5 elementos
ent i;
int pr;
// Ingresando elementos de la matriz
para (yo = 0; yo<5; i++)
{
printf("a[%d] = ", i);
scanf("%d", &a[i]); // &a[i] - dirección del i-ésimo elemento de la matriz
}
pr = func(a, 5); //calcular el producto
printf("\n pr = %d", pr); // genera el producto de elementos pares
getchar(); getchar();
devolver 0;
}






Arriba