Apuntadores

octubre 1, 2007

Que es un puntero?

Un puntero es un tipo especial de variable, que almacena el valor de una direccion de memoria, esta direccion puede ser la de una variable individual, pero mas frecuentemente sera la de un elemento de un array, una estructura u objeto de una clase. Los punteros, al igual que una variable comun, pertenecen a un tipo (type), se dice que un puntero ‘apunta a‘ ese tipo al que pertenece. Ejemplos:

int* pint; //Declara un puntero a entero
char* pchar; //Puntero a char
fecha* pfecha; //Puntero a objeto de clase 'fecha'

Independientemente del tamaño (sizeof) del objeto apuntado, el valor almacenado por el puntero sera el de una unica direccion de memoria. En sentido estricto un puntero no puede almacenar la direccion de memoria de ‘un array’ (completo), sino la de un elemento de un array, y por este motivo no existen diferencias sintacticas entre punteros a elementos individuales y punteros a arrays. La declaracion de un puntero a char y otro a array de char es igual.

Al definir variables o arrays hemos visto que el tipo (type) modifica la cantidad de bytes que se usaran para almacenar tales elementos, asi un elemento de tipo ‘char’ utiliza 1 byte, y un entero 2 o 4. No ocurre lo mismo con los punteros, el tipo no influye en la cantidad de bytes asociados al puntero, pues todas las direcciones de memoria se pueden expresar con solo 2 bytes (o 4 si es una direccion de otro segmento)

Veamos los efectos de un codigo como el siguiente, en la zona de almancenamiento de datos:

char cad[] = "hola";
 char * p;
 p = cad;           //Puntero 'p' apunta a 'cad'

El puntero esta en la direccion 0xffee pero el valor que hay en esa localidad de memoria es otra direccion, los bytes “F0 FF” indican que el puntero apunta a FFF0, donde comienza la cadena de caracteres ‘cad’ con el contenido ‘hola’ mas el cero de fin de cadena.
En las lineas de codigo no hemos indicado a que caracter del array apunta el puntero, pero esa notacion es equivalente a:

p = &cad[0];

que indica de modo mas explicito que se trata de la direccion del primer elemento de ese array de caracteres. El juego con las direcciones puede ilustrarse tambien del siguiente modo:

ffee F0 <—– El puntero ocupa dos bytes para representar la direccion FFF0, direccion a la que ‘apunta’.
ffef FF <—–

fff0 61 <—— cad[0]. .Primer char del array de caracteres, direccion apuntada por el puntero
fff1 61 <—— cad[1]
fff2 61 <—— cad[2]
fff3 61 <—— cad[3]
fff4 0 <—— cad[4] Fin del array, caracter ascii = 0 de fin de cadena

Puesto que un puntero tiene como valor una direccion de memoria, es logico que al llamar a funciones de impresion con un puntero como argumento, la salida en pantalla sea la de una direccion de memoria. Para este tipo de pruebas es interesante usar la libreria iostream.h de C++, pues no obliga a especificar el formato (como hace printf ). Para un puntero ‘p’ la salida en pantalla sera algo similar a lo siguiente:

cout<<p; //sale: 0x8f82fff0;
printf("%p",p) //sale: FFF0

En este caso se trata de un puntero que almacena en 2 bytes una direccion de memoria, la cual es FFF0. Porque razon la impresion con ‘cout’ nos da 4 bytes? Porque agrega 2 bytes (8f y 82) para indicar el ‘segmento’ donde se encuentra esa direccion. Se trata en todo caso de una misma localidad de memoria, con distinto formato de presentacion en pantalla.

La salida en pantalla de un puntero a char es diferente, pues es tratado como apuntando a una cadena de caracteres, en tal caso no sale en pantalla una direccion de memoria, sino un conjunto de caracteres hasta encontrar el ”.

Un puntero puede almacenar la direccion de (“apuntar a”) muy diferentes entidades: una variable, un objeto, una funcion, un miembro de clase, otro puntero, o un array de cada uno de estos tipos de elementos, tambien puede contener un valor que indique que no apunta actualmente a ningun objeto (puntero nulo).

Anuncios

MANEJO DE ARCHIVOS.

octubre 1, 2007

MANEJO DE ARCHIVOS.

El estándar de C contiene funciones varias para la edición de ficheros, estas están definidas en la cabecera stdio.h y por lo general empiezan con la letra f, haciendo referencia a file. Adicionalmente se agrega un tipo FILE, el cual se usará como apuntador a la información del fichero. La secuencia que usaremos para realizar operaciones será la siguiente:

  • Crear un apuntador del tipo FILE
  • Abrir el archivo utilizando la función fopen y asignándole el resultado de la llamada a nuestro apuntador.
  • Hacer las diversas operaciones (lectura, escritura, etc).
  • Cerrar el archivo utilizando la función fclose.

Los prototipos correspondientes de fopen y fclose son:

FILE * fopen (const char *filename, const char *opentype);

int fclose (FILE *stream);

Un ejemplo pequeño para abrir y cerrar el archivo llamado fichero.in en modo lectura:

 #include <stdio.h>
 int main ( int argc, char **argv ) {
   FILE *fp;
   fp = fopen ( "fichero.in", "r" );
   fclose ( fp );
   return 0;
 }
 

Como vemos, en el ejemplo se utilizó el opentype “r”, que es para la lectura, aquí hay una lista de ellos:

  • “r” : abrir un archivo para lectura
  • “w” : abrir un archivo para escritura
  • “a” : abrir un archivo para escritura al final del contenido
  • “r+” : abrir un archivo para lectura y escritura
  • “w+” : crear un archivo para lectura y escritura
  • “a+” : abrir/crear un archivo para lectura y escritura al final del contenido

Adicionalmente hay tipos utilizando “b” (binary) los cuales no serán mostrados por ahora y que solo se usan en los sistemas operativos que no pertenecen a la familia de unix.

Un archivo debe verse como un string (una cadena de caracteres) que esta guardado en el disco duro. Para trabajar con los archivos existen diferentes formas y diferentes funciones. Las funciones que podríamos usar para leer un archivo son:

  • int fgetc(FILE *archivo)
  • char *fgets(char *buffer, int tamano, FILE *archivo)
  • size_t fread(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);

Las primeras dos de estas funciones son muy parecidas entre si. Pero la tercera, por el numero y el tipo de parámetros, nos podemos dar cuenta de que es muy diferente, por eso la trataremos en una sección aparte junto al fwrite que es su contraparte para escritura.

La función fgetc es la más simple de las tres. Esta función lee un caracter a la vez del archivo que esta siendo señalado con el puntero *archivo. En caso de que la lectura sea exitosa devuelve el caracter leído y en caso de que no lo sea o de encontrar el final del archivo devuelve EOF. Esta función se usa generalmente para recorrer archivos de texto. A manera de ejemplo vamos a suponer que tenemos un archivo de texto llamado “prueba.txt” en el mismo directorio en que se encuentra el fuente de nuestro programa. Un pequeño programa que lea ese archivo será:

 #include <stdio.h>
 int main() {
   FILE *archivo;
   char caracter;
   archivo = fopen("prueba.txt","r");
   if (archivo == NULL)
     exit(1);
   printf ("\nEl contenido del archivo de prueba es \n\n");
   while (feof(archivo) == 0){
     caracter = fgetc(archivo);
     printf ("%c",caracter);
   }
   return 0;
 }
 

En este ejemplo lo que vemos ya ha sido explicado excepto por la función feof. Esta función sirve para determinar si el cursor dentro del archivo encontró el final (end of file). Existe otra forma de verificar el final del archivo que es comparar el caracter que trae fgetc del archivo con el macro EOF declarado dentro de stdio.h, pero este método no ofrece la misma seguridad (en especial altratar con los archivos “binarios”). La función feof siempre devolverá 0 si no se encuentra al final del archivo.

Otra cosa importante es que el lenguaje C no tiene dentro de si una estructura para el manejo de excepciones o de errores, por eso es necesario comprobar que el archivo fue abierto con éxito “if (archivo == NULL)“. Si fopen pudo abrir el archivo con éxito devuelve la referencia al archivo (*FILE), de lo contrario devuelve NULL y en este caso se debera revisar la direccion del archivo o los permisos del mismo. En estos ejemplos solo vamos a dar una salida con un retorno de 1 que sirve para señalar que el programa termino por un error.

La otra función de la que hablábamos fue fgets que sirve para el mismo propósito. Existen algunas diferencias por supuesto y podemos empezar con sus tres parámetros. El primer parámetro buffer lo hemos llamado así porque es un puntero a un espacio de memoria del tipo char (podríamos usar un arreglo de char). El segundo parámetro es tamano que es el limite en cantidad de caracteres a leer para la funcion fgets. Y por ultimo el puntero del archivo por supuesto que es la forma en que fgets sabra a que archivo debe escribir.

 #include <stdio.h>
 int main() {
   FILE *archivo;
   char caracteres[100];
   archivo = fopen("prueba.txt","r");
   if (archivo == NULL)
     exit(1); printf ("\nEl contenido del archivo de prueba es \n\n");
   while (feof(archivo) == 0){
     fgets(caracteres,100,archivo);
     printf ("%s",caracteres);
   }
   return 0;
 }

Este es el mismo ejemplo de antes con la diferencia de que este hace uso de fgets en lugar de fgetc. La función fgets se comporta de la siguiente manera, leerá del archivo apuntado por archivo los caracteres que encuentre y a ponerlos en buffer hasta que lea un caracter menos que la cantidad de caracteres especificada en tamano o hasta que encuentre el final de una linea (\n) o hasta que encuentre el final del archivo (EOF). En este ejemplo no vamos a profundizar mas que para decir que caracteres es un buffer, los pormenores seran explicados en la sección de manejo dinámico de memoria.

El beneficio de esta función es que se puede obtener una linea completa a la vez. Y resulta muy útil para algunos fines como la construcción de un parser de algún tipo de archivo de texto.

FREAD, FWRITE Y FCLOSE

Para la lectura de ficheros se utilizará la función fread, la cual sirve para leer contenidos de un fichero.

Su prototipo es el siguiente:

size_t fread (void *data, size_t size, size_t count, FILE *stream);

En estas definiciones se usa el tipo size_t, el cuál está definidio en stddef.h y sirve para definir tamaños de objetos.

Lo que recibe esta función es un puntero donde almacenaremos los datos leídos (comunmente llamado buffer), el tamaño de los datos a leer, la cantidad de esos datos a leer y el apuntador al fichero.

Aquí hay un ejemplo simple para leer los primeros 100 caracteres de un fichero y almacenarlos en un buffer:

 
 
 
 
#include <stdio.h>
 int main ( int argc, char **argv ) {
   FILE *fp;
   char buffer[100];
   fp = fopen ( "fichero.in", "r+" );
   fread ( buffer, sizeof ( char ), 100, fp );
   fclose ( fp );
   return 0;
 }
 

 

ALGORITMOS DE ORDENACIÓN Y BÚSQUEDA EN

VECTORES.

1. Algoritmos de ordenación y búsqueda en vectores:

            1.1 Ordenación de vectores:

 

Ordenar un vector se trata de reorganizar sus elementos según alguna relación de orden. El objetivo de la ordenación es que la información se pueda recuperar fácil y rápidamente (por ejemplo, en una base de datos grande). La ordenación es bastante usual en programación, existiendo varios métodos o algoritmos distintos de ordenación. Cuando se selecciona el método a usar, debe tenerse en cuenta la eficacia del mismo en dos aspectos:

 

• En la memoria que utiliza

• En el tiempo de ejecución

 

Si N es el número de elementos que se quiere ordenar, los buenos algoritmos de ordenación realizan del orden de Nlog 2 N operaciones. En esta práctica vamos a estudiar algunos algoritmos que realizan del orden de N 2   operaciones. Son métodos directos, que son más cortos y fáciles de entender, de tal forma que si N es pequeño, son lo suficientemente eficaces.

 

1.1.1 Algoritmo de intercambio directo (burbuja)

 

Básicamente consiste en realizar varias iteraciones que llevan el elemento menor del vector hasta su posición. Se considera el vector dividido en dos partes la parte ordenada y la parte desordenada. Inicialmente, se considera que todo el vector está desordenado. Se detecta el elemento menor del vector y se lleva a la posición más a la izquierda posible, quedando por tanto colocado en su posición definitiva. El elemento que estaba en ese extremo de la izquierda se desplaza, junto con los demás, hacia la derecha, hasta llegar donde estaba el elemento menor. Este método también se conoce como “método de la burbuja” ya que si imaginamos el vector en posición vertical y considerando los elementos como burbujas con “pesos” en proporción a su valor, en cada pasada sobre el vector ascenderá hasta el nivel superior la “burbuja” de menor peso, desplazando a las demás hacia abajo.

 

 

1.2 Algoritmos de búsqueda:

 

Existen dos métodos básicos de búsqueda de un elemento en un vector: lineal y binaria. La búsqueda lineal ya se ha estudiado en Fundamentos de Informática, y en ella no hace falta que el vector esté ordenado. El algoritmo de búsqueda binaria requiere que el vector esté ordenado. Consiste en situarse en el elemento central del vector, comparando el elemento buscado con el elemento central. Si coincide, se ha terminado la búsqueda con éxito. Si el elemento a buscar es menor, rechazamos los elementos de la derecha, si es mayor, rechazaremos los elementos de la izquierda, y así  sucesivamente. El algoritmo puede expresarse en C como sigue, donde se supone que este código forma parte de una función que devuelve –1 si la variable dato no se encuentra en el vector, y el índice correspondiente en caso contrario.

 

 

ARGUMENTOS Y PARÁMETROS DE LAS FUNCIONES


Supongamos que en un determinado programa debemos calcular repetidamente el valor medio de dos variables, una solución razonable sería crear una función que realice dicho cálculo, y llamarla cada vez que se necesite. Para ello será necesario, en cada llamada, pasarle los valores de las variables para que calcule su valor medio. Esto se define en la declaración de la función especificando, no solo su valor de retorno sino también el tipo de argumentos que recibe:

 

double valor_medio(double x, double y) ;

De esta declaración vemos que la función valor_medio recibe dos argumentos ( x e y ) del tipo double y devuelve un resultado de ese mismo tipo .

Cuando definamos a la función en sí, deberemos incluir parámetros para que alberguen los valores recibidos, así escribiremos:

double valor_medio(double x, double y )

{

return ( (x + y) / 2.0 )

}

NOTA: No es necesario que los NOMBRES de los párametros coincidan con los declarados previamente, es decir que hubiera sido equivalente escribir: double valor_medio(double a, double b) etc, sin embargo es una buena costumbre mantenerlos igual. En realidad en la declaración de la función, no es necesario incluir el nombre de los parámetros, bastaría con poner solo el tipo, sin embargo es práctica generalizada, explicitarlos a fin de hacer más legible al programa .
Aquí estamos utilizando la síntaxis moderna del lenguaje C, pudiendose encontrar en versiones arcaicas, definiciones equivalentes como :

double valor_medio()      ó     double valor_medio(double, double)

double x;                      double x ;

double y;                      double y ;

{                               {

…………                    …………..

Sin embargo es preferible utilizar la nomenclatura moderna, ya que esta facilita la rápida comprensión del programa .
Veamos un ejemplo, para determinar el comportamiento de los parámetros, Supongamos desear un programa que calcule el valor medio de dos variables incrementadas en un valor fijo, es decir:

( ( x + incremento ) + ( y + incremento ) ) / 2.0

Lo podríamos resolver de la siguiente forma :

 

#include <stdio.h>

/* Declaración de la función y el tipo de sus parámetros */

double valor_medio(double p_valor, double s_valor, double inc) ;

main()

{

double x, y, z, resultado ;

printf(“Ingrese el primer valor: “) ;

scanf(“%lf”, &x ) ;

printf(“\nIngrese el segundo valor: “);

scanf(“%lf”, &y ) ;

printf(“\nIngrese el incremento    : “);

scanf(“%lf”, &z) ;

resultado = valor_medio( x, y, z );     /* llamada a la función y

                                              pasaje de argumentos   */

printf(“\n\nResultado de la operación: %lf”, resultado) ;

printf(“\n\nValor con que quedaron las variables: “) ;

printf(“\n Primer valor : %lf “, x ) ;

printf(“\n Segundo valor: %lf “, y ) ;

printf(“\n Incremento   : %lf “, z ) ;

}

/* Definición de la función y sus parámetros */

double valor_medio( double p_valor, double s_valor, double inc )

{

p_valor  += inc ;

s_valor += inc ;

return ( (p_valor + s_valor ) / 2.0 ) ;

}

VARIABLES GLOBALES Y LOCALES

VARIABLES GLOBALES

Hasta ahora hemos diferenciado a las variable segun su “tipo” (int, char double, etc), el cual se refería, en última instancia, a la cantidad de bytes que la conformaban. Veremos ahora que hay otra diferenciación de las mismas, de acuerdo a la clase de memoria en la que residen.

Si definimos una variable AFUERA de cualquier función (incluyendo esto a main() ), estaremos frente a lo denominado VARIABLE GLOBAL. Este tipo de variable será ubicada en el segmento de datos de la memoria utilizada por el programa, y existirá todo el tiempo que esté ejecutándose este.

Este tipo de variables son automáticamente inicializadas a CERO cuando el programa comienza a ejecutarse.

Son accesibles a todas las funciones que estén declaradas en el mismo, por lo que cualquiera de ellas podrá actuar sobre el valor de las mismas.

Por ejemplo:

 

#include <stdio.h>

double una_funcion(void);

double variable_global ;

main()

{

double i ;

printf(“%f”, variable_global );             /* se imprimirá 0 */

i = una_funcion() ;

printf(“%f”, i );                                     /* se imprimirá 1 */

printf(“%f”, variable_global );               /* se imprimirá 1 */

variable_global += 1 ;

printf(“%f”, variable_global );               /* se imprimirá 2 */

return 0 ;

}

double una_funcion(void)

{

return( variable_global  += 1) ;

}

 

 

int y; /* Global. Conocida tanto por main() como por MiFuncion() */

 

main ()

{

     int x;                                               /* Esta x es local a main () */

     y = 100;

     x = 1;

     printf (“x=%d, y=%d”, x, y)        /* Visualiza x=1, y=100 */

     {                                                      /* Comienza bloque */

          int x;                                           /* Esta x es local al bloque */

          x = 2;

          printf (“x=%d, y=%d”, x, y)               /* Visualiza x=2, y=100 */

          MiFuncion ()                              /* Visualiza x=3, y=100 */

          printf (“x=%d, y=%d”, x, y)               /* Visualiza x=2, y=100 */

     }                                                      /* Fin del bloque */

     printf (“x=%d, y=%d”, x, y)        /* Visualiza x=1, y=100 */

}

 

MiFuncion ()

{

     int x;                                               /* Local a MiFuncion() */

     x = 3;

     printf (“x=%d, y=%d”, x, y)        /* Visualiza x=3, y=100 */

}

 

Observemos que la variable_global está definida afuera de las funciones del programa, incluyendo al main(), por lo que le pertenece a TODAS ellas. En el primer printf() del programa principal se la imprime, demostrandose que está automaticamente inicializada a cero .

Luego es incrementada por una_funcion() que devuelve ademas una copia de su valor, el cual es asignado a i ,la que, si es impresa mostrará un valor de uno, pero tambien la variable_global ha quedado modificada, como lo demuestra la ejecución de la sentencia siguiente. Luego main() tambien modifica su valor , lo cual es demostrado por el printf() siguiente.

Esto nos permite deducir que dicha variable es de uso público, sin que haga falta que ninguna función la declare, para actuar sobre ella.

VARIABLES LOCALES


A diferencia de las anteriores, las variables definidas DENTRO de una función, son denominadas VARIABLES LOCALES a la misma, a veces se las denomina también como AUTOMÁTICAS, ya que son creadas y destruidas automáticamente por la llamada y el retorno de una función, .

respectivamente.

Estas variables se ubican en la pila dinámica (stack) de memoria , destinándosele un espacio en la misma cuando se las define dentro de una función, y borrándose cuando la misma devuelve el control del programa, a quien la haya invocado.

Este método permite que, aunque se haya definido un gran número de variables en un programa, estas no ocupen memoria simultáneamente en el tiempo, y solo vayan incrementando el stack cuando se las necesita, para luego, una vez usadas desaparecer, dejando al stack en su estado original.
El identificador ó nombre que se la haya dado a una variable es sólo relevante entonces, para la función que la haya definido, pudiendo existir entonces variables que tengan el mismo nombre, pero definidas en funciones distintas, sin que haya peligro alguno de confusión .
La ubicación de estas variables locales, se crea en el momento de correr el programa, por lo que no poseen una dirección prefijada, esto impide que el compilador las pueda inicializar previamente. Recuérdese entonces que, si no se las inicializa expresamente en el momento de su definición, su valor será indeterminado (basura).

Las funciones de usuario son, como su nombre indica, las que el propio usuario declara, de igual manera que declara procedimientos. Las funciones nacen con el propósito de ser subprogramas que siempre tienen que devolver algún valor.

Las dos principales diferencias entre procedimientos y funciones son:

  • Las funciones siempre devuelven un valor al programa que las invocó.
  • Para llamar a un procedimiento se escribe su nombre en el cuerpo del programa, y si los necesita, se incluyen los parámetros entre paréntesis. Para invocar una función es necesario hacerlo en una expresión.

Las funciones de usuario vienen definidas por un nombre, seguidas de dos paréntesis () entre los que puede haber o no argumentos. Los argumentos son valores que se le pasan a la función cuando se llama.

Un ejemplo de una función sin argumentos:

#include <stdio.h>

main ()

{

printf (“\nEste mensaje lo muestra la función main()”);

MiFuncion ();

}

/* Definición de la función MiFuncion() */

MiFuncion ()

{

printf (“\nEste otro lo muestra MiFuncion()”);

}

En este ejemplo se utiliza la función MiFuncion() para mostrar en pantalla una frase. Como se ve, MiFuncion() se invoca igual que printf() o scanf(), es decir, simplemente se escribe el nombre de la función y los paréntesis. La definición de MiFuncion() tiene el mismo aspecto que main(): el nombre de la función con los paréntesis y, seguidamente, el cuerpo de la función encerrado entre llaves.

Un ejemplo de una función con argumentos. El programa visualiza el cuadrado de un número entero por medio de una función que recibe dicho número como argumento.

#include <stdio.h>

main ()

{

int num;

printf (“\nTeclee un número entero: “);

scanf (“%d”, &num);

cuadrado (num);

}

/* Definición de la función cuadrado() */

cuadrado (int x)

{

printf (“\nEl cuadrado de %d es %d\n”, x, x * x);

}

Es la declaración de la función cuadrado(). Dentro de los paréntesis se pone la variable que recibirá el valor pasado a cuadrado() y de qué tipo es. Así, si se teclea el valor 6, se almacena en num y al hacer la llamada cuadrado (num), la variable num se copia en la variable x, que es con la que trabaja internamente la función cuadrado().

Es importante mantener claros dos términos:

1. El término Argumento se refiere a la variable usada al llamar la función.

2. El término Parámetro Formal se refiere a la variable de una función que recibe el valor de los argumentos.

También es importante tener claro que la copia de variables se hace sólo en una dirección: del argumento al parámetro formal. Cualquier modificación del parámetro formal realizado dentro de la función no tiene ninguna influencia en el argumento.

Hay que tener en cuenta es que el tipo de argumento que se utiliza para llamar a una función debe ser el mismo que el del parámetro formal que recibe el valor. Así, no debe llamarse a la función cuadrado con un argumento de tipo float.

 

Un ejemplo que utiliza una función que devuelve un valor. El siguiente programa lee dos números enteros del teclado y muestra su producto en pantalla. Para el cálculo se usa una función que recibe los dos números y devuelve el producto de ambos.

#include <stdio.h>

main ()

{

int a, b, producto;

printf (“\nTeclee dos números enteros: “);

scanf (“%d %d”, &a, &b);

producto = multiplica (a, b);

printf (“\nEl resultado es %d”, producto);

}

/* Definición de la función multiplica() */

multiplica (int x, int y)

{

return (x * y);

}

Es un arreglo de dos dimensiones.

Son estructuras de datos que agrupan muchos datos del mismo tipo, en donde cada elemento se puede trabajar individualmente y se puede referenciar con un mismo nombre. Se usan para representar datos que pueden verse como una tabla con filas y columnas.

ü Declaración:

Tipo_dato nombre_matriz [índice fila] [índice columna]

ü Uso:

Nombre_matriz [subíndice1] [subíndice2]

int matriz [2][2]

char mapa [100][100]

int certamen [60][4]

Declara una matriz de 3 filas por 4 columnas:

int matriz [3][4];

ü Declaración e iniciación:

int matriz [2][2]={1,2,3,4}

1

2

Para referenciar un elemento de la matriz, debe darse un nombre de la matriz y el índice de la fila y de la columna que el elemento ocupa en dicha matriz. Es importante que los índices de las matrices tanto de las filas como de las columnas empiezan en 0 y terminan en tamaño fila-1 y tamaño columna-1 respectivamente.

A las matrices se le asignan automáticamente valores iniciales predeterminados a cada uno de sus elementos, de acuerdo a los siguientes criterios:

  • Si el tipo del arreglo es numérico, a sus elementos se les asigna el valor cero.
  • Si el tipo del arreglo es char, a sus elementos se les asigna el valor ‘\u0000’.
  • Si el tipo del arreglo es bool, a sus elementos se les asigna el valor false.
  • Si el tipo del arreglo es una clase, a sus elementos se les asigna el valor null.

Ejemplo:

#include <stdio.h>

int main()

{

int fila, columna;

int matriz[2][2];

for(fila=0; fila<2; fila++)

for(columna=0; columna<2; columna++)

printf(“%d”, matriz[fila][columna]);

return 0;

}

 

Ejercicios

EJEMPLO 1

EJMEPLO 2 

Arreglos unidimensionales

septiembre 30, 2007

Bienvenido a continuación aprenderemos juntos un poco mas del lenguaje c++, recuerda que nos basamos en el compilador DEV-C++, en esta ocasión aprenderemos de los arreglos.. comenzaremos por los arreglos Unidimensionales

En programación, un vector, array, arreglo o alineación es un conjunto o agrupación de variables del mismo tipo cuyo acceso se realiza por índices.

Un arreglo unidimensional de 10 elementos

Los arreglos permiten agrupar datos usando un mismo identificador. Todos los elementos de un arreglo son del mismo tipo, y para acceder a cada elemento se usan subíndices. En el siguiente capítulo se presentan los arreglos y las cadenas. Las cadenas se consideran como un arreglo de tipo char.

ejemplo de esto seria

Vector [ tamaño ]

A los arreglos unidimensionales se les llama vectores, se puede decir que son un grupo de variables que se relacionan por un nombre en común, un arreglo consta de una posición de memoria contigua,es decir un orden de menor a mayor, así podemos afirmar que la mas baja corresponde al primero y la mayor al ultimo, para acceder a una sección de un arreglo en especifico se utiliza el indice, a continuación mostramos un ejemplo:

aplicado en c++

int can[9] //un vector llamado can con diez de tamaño

el vector o arreglo unidimensional llamado can(cantidad) tiene cantidad diez porque se inicia en 0 y es tomado en cuenta-

es decir un arreglo con diez elementos enteros de así desde can[0]-can[9]

La forma por la cual pueden ser accesados es la siguiente:*en este caso aportaremos una cantidad a un elemento de la lista “can”

ca[5]= 15

¡para ser claros! un ejemplo sencillo aplicado a la vida cotidiana, supongamos que tenemos diez niños( 0-9) y a cada uno le daremos cierta cantidad de dinero..(daremos un valor) y si decimos. el niño numero 5 (can[5]) tendrá $15* en nuestro ejemplo seria niño[5]=15*

también podemos guardar en una variable el contenido de un elemento

así cantidad=can[5] tomando en cuenta lo anterior podemos decir que cantidad=15

Los arreglos o arrays corresponden a la “Estructura de Datos estáticas”: son aquellas en las que el espacio ocupado en memoria se define en tiempo de compilación y no puede ser modificado durante la ejecución del programa.

 

En lenguaje C/C++ es posible inicializar un arreglo con una lista de valores, de la siguiente forma:

int Vector[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

A los vectores se le asignan automáticamente valores iniciales predeterminados a cada uno de sus elementos, de acuerdo a los siguientes criterios:

Si el tipo del arreglo es numérico, a sus elementos se les asigna el valor cero.
Si el tipo del arreglo es char, a sus elementos se les asigna el valor ‘\u0000’.
Si el tipo del arreglo es bool, a sus elementos se les asigna el valor false.
Si el tipo del arreglo es una clase, a sus elementos se les asigna el valor null.

 

Download

Baja ejercicios-  ejercicio 1

                             ejercicio 2