Conceptos básicos de matrices C

Conceptos básicos de matrices C

El lenguaje C proporciona una capacidad llamada "matriz" que permite al usuario diseñar un conjunto de tipos de datos similares. Muy a menudo, uno necesita procesar colecciones de elementos de datos relacionados, como la suma de cincuenta números, puntajes de exámenes de estudiantes en una universidad, un conjunto de medidas resultantes de un experimento, tablas de impuestos sobre la renta, etc. Una forma de manejar tal situación sería declarar un nuevo nombre de variable para cada uno de estos elementos de datos. Obviamente, este enfoque es bastante engorroso, si no del todo imposible.

Una mejor manera de resolver el problema es usar una matriz de un tipo de datos correspondiente. Esto permite al usuario acceder a cualquier número de tipos de datos relativos usando un solo nombre y subíndice.

Definición

Una colección finita ordenada de elementos de datos, cada uno del mismo tipo, se denomina matriz, y los elementos de datos individuales son sus elementos. Solo se asigna un nombre a una matriz y la especificación de un subíndice hace referencia a elementos individuales.

Un subíndice también se llama índice. En C, los subíndices comienzan en 0, en lugar de 1, y no pueden ser negativos. El nombre del grupo único y el subíndice se asocian encerrando el subíndice entre corchetes a la derecha del nombre.

Considere un ejemplo en el que las calificaciones de algunos estudiantes se almacenan en una matriz llamada marca, luego marca[0] se refiere a las calificaciones del primer estudiante, marca[1] a las calificaciones del segundo estudiante, marca[10] a las calificaciones del undécimo estudiante y marca[n-1] a las marcas del n-ésimo estudiante.

Una matriz tiene las siguientes propiedades:

  • El tipo de una matriz es el tipo de datos de sus elementos.
  • La ubicación de una matriz es la ubicación de su primer elemento.
  • La longitud de una matriz es el número de elementos de datos en la matriz.
  • El almacenamiento requerido para una matriz es la longitud de la matriz multiplicada por el tamaño de un elemento.

Los arreglos, cuyos elementos están especificados por un subíndice, se llaman arreglos unidimensionales. Los arreglos, cuyos elementos están especificados por más de un subíndice, se denominan arreglos multidimensionales.

Declaración de matriz de una sola dimensión

Las matrices, al igual que las variables simples, deben declararse antes de su uso. Una declaración de matriz tiene la forma:

data-type arrayname[size] ;

donde,
tipo de datos :el tipo de datos almacenados en la matriz.
nombre de la matriz :Nombre de la matriz.
Tamaño :Número máximo de elementos que puede contener la matriz.

Por lo tanto, un número de matriz de 50 elementos enteros se puede declarar como:

Inicialización de matriz unidimensional

A los elementos de una matriz se les pueden asignar valores iniciales siguiendo la definición de la matriz con una lista de inicializadores encerrados entre llaves y separados por comas.

Por ejemplo, la declaración:

int mark[5] = {40,97,91,88,100}; 

declara una marca de matriz para contener cinco elementos enteros e inicializa los elementos de la matriz como se indica a continuación:

mark[0]   40 
mark[1]   97 
mark[2]   91 
mark[3]   88 
mark[4]   100

La declaración:

char name[3] = {‘R’,’A’,’J’};

declara un nombre de matriz para contener tres elementos de caracteres e inicializa los elementos de la matriz como se indica a continuación:

name[0]     'R'
name[1]     'A' 
name[2]     'J'

La declaración:

float price[7] = {0.25, 15.5, 10.7, 26.8, 8.8, 2.8, 9.7};

declara un precio de matriz que contiene siete elementos flotantes e inicializa los elementos de la matriz como se indica a continuación:

price[0]      0.25 
price[1]      15.5 
price[2]      10.7 
price[3]      26.8 
price[4]      8.8 
price[5]      2.8 
price[6]      9.7

Dado que se puede usar cualquier expresión integral constante para especificar el número de elementos en una matriz, las constantes simbólicas o las expresiones que involucran constantes simbólicas también pueden aparecer en las declaraciones de matriz.

Por ejemplo, la declaración:

#define UNIT_PRICE 80 
#defineTOT_PRICE 100 
int sl_price[UNIT_PRICE] ; 
int nt_price[TOT_PRICE] ;

declare sl_price y nt_price como una matriz de enteros unidimensional de 80 y 100 elementos respectivamente. El tamaño de la matriz se puede omitir durante la declaración.

Así, la declaración,

int mark[] = {40,97,91,88,100}; 

es equivalente a:

int mark[5] = {40,97,91,88,100};

En tales casos, se supone que el subíndice es igual al número de elementos de la matriz (5 en este caso). Los elementos, que no se inicializan explícitamente, se establecen automáticamente en cero.

int x[4]={1,2}; implies 
      x[0]=1 
      x[1]=2 
      x[2]=0 
      x[3]=0

Elementos de matriz en memoria

Considere la siguiente declaración de matriz:

int num[100];

En la declaración anterior, 400 bytes se reservan inmediatamente en la memoria, ya que cada uno de los 100 enteros tendría una longitud de 4 bytes. Una matriz es un conjunto de ubicaciones de memoria contiguas, cuyo primer elemento comienza en el índice cero. La asignación será así.

Como se vio anteriormente, los elementos de la matriz siempre están numerados (índice) de 0 a (n-1), donde n es el tamaño de la matriz.

Procesamiento de matrices

La capacidad de representar una colección de elementos de datos relacionados mediante una sola matriz permite el desarrollo de programas concisos y eficientes. Un elemento de matriz individual se puede usar de manera similar a como se usa una variable simple. Es decir, el usuario puede asignar un valor, mostrar su valor o realizar operaciones aritméticas sobre él.

Para acceder a un elemento particular en una matriz, especifique el nombre de la matriz, seguido de llaves cuadradas que encierran un número entero, que se denomina índice de matriz.

Por ejemplo, la declaración de asignación,

num[5] = 2 ;

asigna del 2 al 6º elemento de num.

p = (net[1] + amount[9]) /2 ; 

asigna el valor medio del segundo elemento del neto y el décimo elemento del importe parte superior.

La declaración

--num[8] ;

disminuye el contenido del noveno elemento de num en 1.

Las declaraciones de asignación,

i = 5; 
p = num[++i] ;

asigna el valor de num[6] a p.

mientras que las declaraciones,

i = 5 ; 
p = num[i++] ; 

asigne el valor de num[5] a p.

Sin embargo, todas las operaciones que involucren arreglos completos deben realizarse elemento por elemento. Esto se hace usando bucles. Por lo tanto, el número de iteraciones del ciclo será igual al número de elementos de la matriz que se procesarán.

Como ilustración del uso de arreglos, considere el siguiente programa.

/* Program to find average marks obtained by 25 students in a test by accepting marks of each student */ 
# include <stdio.h>
void main(void) 
{  
   int i; 
   float sum=0; 
   float mark[25]; 
   for(i=0;i<25;i++) 
   { 
       printf(“Enter marks : “); 
       scanf(“%f”,&mark[i]); 
       sum += mark[i]; 
   } 
   printf(“\n Average marks : %.2f \n”,sum/25); 
}

¿Qué son las cadenas?

Una constante de cadena es una matriz unidimensional de caracteres que termina en un carácter nulo ('\0'). Las cadenas se utilizan para almacenar información de texto y realizar manipulaciones en ellas. Las cadenas se declaran de la misma manera que otras matrices.

Por ejemplo:

char fruit[10];

Inicializar matrices de caracteres

Las matrices de caracteres se pueden inicializar de dos maneras como caracteres individuales o como una sola cadena.

char name[ ] = {‘P’, ’a’, ’t’, ’n’, ‘i’, ’\0’}; 

Cada carácter de la matriz ocupa un byte de memoria y el último carácter siempre es '\0', que es un solo carácter. El carácter nulo actúa como un terminador de cadena. Por lo tanto, una cadena de n elementos puede contener (n-1) caracteres.

char fruit[ ] = “Apple”; 

Tenga en cuenta que, en esta declaración, '\0' no es necesario, C inserta el carácter nulo automáticamente, cuando la matriz se inicializa con una constante de cadena entre comillas dobles.

Al inicializar una matriz de caracteres, se puede omitir la longitud. El compilador asigna automáticamente el almacenamiento según la longitud del valor dado.

char name[ ] = "Geek"; 

La declaración anterior asigna automáticamente un almacenamiento equivalente a 6 caracteres, incluido '\0' al nombre de la matriz de caracteres.

La representación de memoria de la matriz anterior se muestra a continuación:

G e e k \0
/* Program to accept and print a string */ 
void main(void) 
{ 
    char name[20]; 
    scanf(“%s”, name); 
    printf(“%s”, name); 
}

El %s usado en printf() es una especificación de formato para imprimir una cadena. La misma especificación también se puede usar con scanf(). En ambos casos estamos proporcionando la dirección base a las funciones. La función scanf(), después de presionar enter, inserta automáticamente un '\0' al final de la cadena. La función scanf() no es capaz de recibir cadenas de varias palabras separadas por espacios. En ese caso, utilice las funciones gets() y puts().

/* Program that accepts and prints a string using gets and puts functions */
#include  
#include <stdio.h>
#include <string.h>main() 
{ 
   char name[20]; 
   gets(name); 
   puts(name); 
}
/* Program to compute the length of a given string */
#include <stdio.h>
void main(void) 
{ 
   char str[10]; 
   int len; 
   printf("\n Enter string :"); 
   scanf("%[^\n]", arr1); 
   for(len = 0; str[len] != '\0'; len++); 
   printf("\nThe length of the string is %d\n", len); 
}

Pasar matrices a funciones

A veces es un inconveniente llamar a una función que requiere una larga lista de argumentos. Una forma de evitar esto es almacenar sus variables en una matriz, luego pasar un PUNTERO a la matriz a la función. Este método se discutirá con mayor detalle en la sección de punteros, pero por ahora necesita saber que la matriz en realidad no se pasa a la función, solo la ubicación de la matriz en la memoria. Esto se conoce como PASO POR REFERENCIA. El nombre de una matriz hace referencia a la ubicación de la matriz en la memoria, su DIRECCIÓN.

/* Passing Arrays to functions */
#include <stdio.h> 
int addNumbers(int fiveNumbers[]); /* declare function */ 
int main() 
{ 
    int array[5]; 
    int i; 
    printf("Enter 5 integers separated by spaces:"); 
    for(i=0 ; i<5 ; i++) 
    { 
       scanf("%d", &array[i]); 
    } 
    printf("\nTheir sum is: %d\n", addNumbers(array)); 
    return 0; 
} 

int addNumbers(int fiveNumbers[]) /* define function */ 
{ 
int sum = 0; 
int i; 
    for(i=0 ; i<5 ; i++) 
    { 
        sum+=fiveNumbers[i]; /* work out the total */ 
    } 
    return sum; /* return the total */ 
}

Tenga en cuenta que el tamaño de la matriz está en blanco tanto en la declaración como en la definición de la función; el compilador lo resuelve por usted. Además, cuando se llama a la función, se pasa el nombre de la matriz. Esto es equivalente a pasar &array[0], la dirección del primer elemento.

Matrices multidimensionales

Esto es similar a pasar una matriz 1D pero, en las declaraciones de función, debe especificar todos los tamaños de dimensión (solo el más a la izquierda es opcional).

/* Passing Multi dimensional Arrays to functions */
#include <stdio.h>   
void printArray(int array[][4]); /* declare function */ 

int main() 
{ 
   int array[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11}; 
   printArray(array); 
   return 0; 
}

void printArray(int array[][4]) 
{ 
   /* define function */ 
   int i, j; 
   for(i=0 ; i<3 ; i++) 
   { 
      for(j=0 ; j<4 ; j++) { 
         printf("%2d ", array[i][j]); 
      printf(“\n”); 
    } 
    printf("\n"); 
    } 
}

Pasar cadenas a funciones

Para pasar direcciones a una función (lo que se conoce como pasar por referencia), puede usar el nombre de la matriz. Si su función necesita saber cuántos elementos hay en la matriz, puede pasar ese valor como segundo argumento:

Function Prototype 
     void MyFunct(char []); 
     void MyFunct(char [],int); 

Function call 
     MyFunct(ArrayName); 
     MyFunct(ArrayName,HowMany); 

Function Header 
     void MyFunct(AryNm[]); 
     void MyFunct(AryNm[],Num);

Funciones de cadenas integradas

El archivo de encabezado string.h proporciona un conjunto útil de funciones de cadena. Estas funciones ayudan en la manipulación de cadenas. Para usar estas funciones, el archivo de encabezado string.h debe incluirse en el programa con la instrucción:

strcat (objetivo, origen)

La función strcat() acepta dos cadenas como parámetros y las concatena, es decir, agrega la cadena de origen al final de la de destino.

/* Sample program using strcat() */ 
#include <stdio.h>
#include <string.h>
void main(void) 
{ 
    char name1[]= "Ash"; 
    char name2[]= "wini"; 
    strcat(name1, name2); 
    printf("\n"); 
    puts(name1); 
}

Salida:

Ashwini

strcmp (cadena1, cadena2)

La función strcmp() se usa para comparar dos cadenas. Esta función es útil al escribir un programa para ordenar o buscar cadenas.
La función acepta dos cadenas como parámetros y devuelve un valor entero, según el orden relativo de las dos cadenas.

Valor devuelto Descripción
Menos de 0 Si cadena1 es menor que cadena2
Igual a 0 Si cadena1 y cadena2 son idénticas
Mayor que 0 Si cadena1 es mayor que cadena2
/* Sample program to test equality of two strings using strcmp() */
# include <stdio.h>
# include <string.h>
void main(void) 
{ 
   char str1[10]; 
   char str2[10]; 
   int result; 
   printf("\n*** Comparing two strings ***\n"); 
   fflush(stdin); /* flush the input buffer */ 
   printf("Enter first string\n"); 
   scanf("%s", str1); 
   fflush(stdin); 
   printf("\nEnter second string\n"); 
   scanf("%s", str2); 
   result = strcmp(str1, str2); 
   if(result < 0) 
       printf("\nString2 is greater than String1 ..."); 
   else if(result == 0) 
       printf("\nBoth the Strings are equal.."); 
   else 
       printf("\nString1 is greater than String2 ..."); 
}

La función strcmp() compara las dos cadenas, carácter por carácter, para decidir cuál es mayor. Cada vez que dos caracteres de la cadena difieren, la cadena que tiene el carácter con un valor ASCII más alto es mayor.

P.ej. considere las cadenas hola y ¡Hola!

El primer carácter en sí difiere. El código ASCII de h es 104, mientras que el de H es 72. Dado que el código ASCII de h es mayor, la cadena hola es mayor que ¡Hola!. Una vez que se encuentra una diferencia, no hay necesidad de comparar los otros caracteres de las cadenas; por lo tanto, la función devuelve el resultado.

strcpy(objetivo, fuente)

La función strcpy() copia una cadena en otra. Esta función acepta dos cadenas como parámetros y copia la cadena de origen carácter por carácter en la cadena de destino, hasta e incluyendo el carácter nulo de la cadena de origen.

/* Sample program using strcpy() function */ 
# include <stdio.h>
# include <string.h>
void main(void) 
{ 
    char name1[]= "Ash"; 
    char name2[]= "win"; 
    printf("\n** Before Copying two strings are **\v"); 
    printf("%s\t%s", name1, name2); 
    strcpy(name1, name2); 
    printf("\n** After Copying two strings are **\v"); 
    printf("%s\t%s\n", name1, name2); 
}

Salida:

** Before Copying two strings are ** 
            Ash              win 
** After Copying two strings are ** 
            win              win

strlen(cadena)

La función strlen() devuelve un valor entero, que corresponde a la longitud de la cadena pasada. La longitud de una cadena es el número de caracteres presentes en ella, excluyendo el carácter nulo de terminación.

/* Sample Program using strlen() function() */ 
# include <stdio.h>
# include <string.h>
void main(void) 
{ 
    char arr1[10]; 
    int i, len; 
    printf("\nEnter string :\n"); 
    scanf("%[^\n]", arr1); 
    printf("\nThe length of the string is %d", strlen(arr1)); 
}

Hay muchas más funciones de manipulación de cadenas en . Los más útiles se pueden enumerar aquí.

TFunciónT TPrototipoT SignificadoT
strcat char *strcat(char *str1, const char *str2) Agrega la cadena a la que apunta str2 al final de la cadena a la que apunta str1. El carácter nulo final de str1 se sobrescribe. La copia se detiene una vez que se copia el carácter nulo final de str2. Si se produce una superposición, el resultado no está definido.
strncat char *strncat(char *str1, const char *str2, size_t n); Agrega la cadena apuntada por str2 al final de la cadena apuntada por str1 hasta n caracteres de longitud
strchr char *strchr(const char *str, int c) Busca la primera aparición del carácter c (un carácter sin signo) en la cadena a la que apunta el argumento str. El carácter nulo final se considera parte de la cadena.
strncmp int strncmp(const char *str1, const char *str2, size_t n) Compara como máximo los primeros n bytes de str1 y str2. Deja de comparar después del carácter nulo
strcpy char *strcpy(char *str1, const char *str2) Copia la cadena apuntada por str2 a str1. Copia hasta e incluyendo el carácter nulo de str2
error Tchar *strerror(int TerrnumT)T Busca en una matriz interna el número de error errnum y devuelve un puntero a una cadena de mensaje de error.
estrenar size_t strlen(const char *str) Calcula la longitud de la cadena str hasta el carácter nulo final, pero sin incluirlo. Devuelve el número de caracteres de la cadena