Categorías destacadas
programacion php    
Artículo
7
¡votar!

 Lenguaje C


Estructuras de las Tablas

Cada variable de un programa tiene una dirección en la memoria del ordenador. Esta dirección indica la posición del primer byte que la variable ocupa. En el caso de una estructura es la dirección del primer campo. En los ordenadores actuales la dirección de inicio se considera la dirección baja de memoria. Como en cualquier caso las variables son almacenadas ordenadamente y de una forma predecible, es posible acceder a estas y manipularlas mediante otra variables que contenga su dirección. A este tipo de variables se les denomina punteros.

Los punteros C son el tipo más potente y seguramente la otra clave del éxito del lenguaje. La primera ventaja que obtenemos de los punteros es la posibilidad que nos dan de poder tratar con datos de un tamaño arbitrario sin tener que moverlos por la memoria. Esto puede ahorrar un tiempo de computación muy importante en algunos tipos de aplicaciones. También permiten que una función reciba y cambie el valor de una variable. Recordemos que todas las funciones C únicamente aceptan parámetros por valor. Mediante un puntero a una variable podemos modificarla indirectamente desde una función cualquiera.

Un puntero se declara de la forma: tipo *nombre;

float *pf;
PLANETA *pp;
char *pc;

Para manipular un puntero, como variable que es, se utiliza su nombre; pero para acceder a la variable a la que apunta se le debe preceder de *. A este proceso se le llama indirección. Accedemos indirectamente a una variable. Para trabajar con punteros existe un operador, &, que indica 'dirección de'. Con él se puede asignar a un puntero la dirección de una variable, o pasar como parámetro a una función.

void prueba_puntero ( void ) {
  long edad;
  long *p;
  p = &edad;
  edad = 50;
  printf("La edad es %ld\n", edad );
  *p = *p / 2;
  printf("La edad es %ld\n", edad );
}

void imprimir_string ( char string[] ) {
  char *p;
  for ( p = string; *p != '\0'; p++ )
    imprimir_char(*p);
}

Definimos un vector de N_PLA componentes de tipo PLANETA. Este tipo está formado por un registro. Vemos que en la función de inicialización del vector el puntero a la primera componente se inicializa con el nombre del vector. Esto es una característica importante de C. La dirección de la primera componente de un vector se puede direccionar con el nombre del vector. Esto es debido a que en la memoria del ordenador, los distintos elementos están ordenados de forma ascendente. Así, SSolar se puede utilizar como &SSolar[0]. A cada iteración llamamos a una función que nos inicializará los datos de cada planeta. A esta función le pasamos como argumento el puntero a la componente en curso para que, utilizando la notación ->, pueda asignar los valores adecuados a cada campo del registro. Debemos fijarnos en el incremento del puntero de control de la iteración, p++. Con los punteros se pueden realizar determinadas operaciones aritméticas aunque, a parte del incremento y decremento, no son muy frecuentes. Cuando incrementamos un puntero el compilador le suma la cantidad necesaria para que apunte al siguiente elemento de la memoria. Debemos fijarnos que esto es aplicable sólo siempre que haya distintas variables o elementos situados consecutivamente en la memoria, como ocurre con los vectores.

De forma similar se pueden utilizar funciones que tengan como parámetros punteros, para cambiar el valor de una variable. Veamos:

void intercambio ( void ) {
  int a, b;
  a = 1;
  b = 2;
  swap( &a, &b );
  printf(" a = %d b = %d\n", a, b );
}

void swap ( int *x, int *y ) {
  int tmp;
  tmp = *x;
  *x = *y;
  *y = tmp;
}

La sintaxis de C puede, a veces, provocar confusión. Se debe distinguir lo que es un prototipo de una función de lo que es una declaración de una variable. Así mismo, un puntero a un vector de punteros, etc...

  • int f1(); función que devuelve un entero
  • int *p1; puntero a entero
  • int *f2(); función que devuelve un puntero a entero
  • int (*pf)(int); puntero a función que toma y devuelve un entero
  • int (*pf2)(int *pi); puntero a función que toma un puntero a entero y devuelve un entero
  • int a[3]; vector de tres enteros
  • int *ap[3]; vector de tres punteros a entero
  • int *(ap[3]); vector de tres punteros a entero
  • int (*pa)[3]; puntero a vector de tres enteros
  • int (*apf[5])(int *pi); vector de 5 punteros a función que toman un puntero a entero y devuelven un entero.

En los programas que se escriban se debe intentar evitar declaraciones complejas que dificulten la legibilidad del programa. Una forma de conseguirlo es utilizando typedef para redefinir/renombrar tipos.

typedef int *intptr;
typedef intptr (*fptr) ( intptr );
fptr f1, f2;
Publicado por:
Luis Raymundo
Recomendar
a un amigo
Compartir
en redes
 
Comentarios
 
BBDD
Entornos de desarrollo
Entretenimiento
Herramientas
Internet
Lenguajes de script
Lenguajes imperativos
Lenguajes orientados a objeto
Otros lenguajes
Plataformas
Teoría
Varios
Copyright © 1998-2011 Programación en Castellano. Todos los derechos reservados
Datos legales | Politica de privacidad | Contacte con nosotros | Publicidad

Diseño web y desarrollo web. Un proyecto de los hermanos Carrero.

Red internet:
Juegos gratis | Servidores dedicados
Más internet: Password | Directorio de weblogs | Favicon