PDF de programación - SEMINARIO “C para programadores java” - Sesión 2

Imágen de pdf SEMINARIO “C para programadores java” - Sesión 2

SEMINARIO “C para programadores java” - Sesión 2gráfica de visualizaciones

Actualizado el 20 de Mayo del 2018 (Publicado el 18 de Enero del 2017)
844 visualizaciones desde el 18 de Enero del 2017
225,8 KB
10 paginas
Creado hace 15a (26/09/2008)
Algoritmos y Estructuras de Datos

2º de Ingeniería Informática, Curso 2008/2009

SEMINARIO “C para programadores java”
(este seminario forma parte de las actividades del proyecto piloto)



Sesión 2

Contenidos:

1. Estructuras (registros) y uniones
2. Estructura de la memoria (línux)
3. Punteros
4. Arrays
Ejercicios



Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2

2/10

1. Estructuras (registros) y uniones



• Una estructura o registro en C es como una clase en java, pero:

o sin métodos (sin funciones), sólo con campos de datos (miembros).
o con todos esos campos públicos
o usando la palabra clave struct en vez de class


• Ejemplo:

struct persona {
unsigned long DNI;
char nombre[100];
int edad;
enum sexo s;
};
struct persona pers1, pers2;



• En C no existen las clases; en C++ sí.

Importante diferencia en C respecto a java: aunque una estructura es un tipo
de dato compuesto (no básico), funciona como un tipo elemental en cuanto a que
es una referencia directa, es decir:
• pers1=pers2 copia los campos de pers2 sobre los de pers1 (no la referencia)
• pers1== pers2 compara las dos estructuras miembro a miembro, en vez de
comprobar si pers1 y pers2 son referencias a la misma estructura

• Al igual que en java, se accede a los miembros utilizando la notación punto:

variable.miembro
pers1.DNI = 27722;
printf("%s\n", pers1.nombre);
pers2.edad= pers1.edad + 1;



• Inicialización de registros (en la declaración). Indicar entre llaves el valor de

cada miembro, en el mismo orden.
struct persona pers1= {77000000, "Juanito", 12, hombre};


• Uniones. Una unión es como un registro, pero donde todos los campos ocupan

(comparten) la misma posición de memoria.
o Conclusión: los miembros de la unión son excluyentes.
o Su uso es mucho menos frecuente.
o Utilidad: optimizar uso de memoria.
o No existen en java.
o Ojo: escritura/lectura deben ser coherentes, por el mismo campo.
o Ejemplos:

union numero {
int comoInt;
float comoFloat;
double comoDouble;
} n1;
n1. comoInt= 4;
printf("%g", n1. comoDouble);

union identificador {
unsigned long DNI;
long Npasaporte;
char nombre[100];
};
union identificador id1, id2;

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2

3/10





• Definición de tipos. C permite dar nombre a los nuevos tipos definidos

(estructuras, registros, enumerados, etc.):



typedef expresión_tipo nombre_nuevo;

Ejemplos:
typedef unsigned char byte;
typedef byte * byte_pointer;
typedef struct persona tipo_persona;

byte b1= 1, b2[10]; /* Equivalente a: unsigned char b1, b2[10]; */
byte_pointer pb1= b2; /* Equivalente a: unsigned char *pb1= b2; */
tipo_persona pers1= {200, "Pepito", 11, hombre}, *pp;
printf("Tamaño de persona: %d\n", sizeof(tipo_persona));
pp= &pers1;
pp->nombre[5]= 'a';
printf("Nombre: %s\n", pers1.nombre);

2. Estructura de la memoria (línux)



código

memoria estática
(vars globales)

memoria dinámica (heap o montón)

⇓ heap crece hacia abajo

⇑ pila crece hacia arriba

pila (llamadas a funciones)






memoria

direcciones de
crecientes en
esta dirección





• La memoria ocupada por código y memoria estática está reservada para esos
propósitos desde que el principio al fin de la ejecución del programa. No
podemos liberar esa memoria, ni solicitar más memoria.
• La memoria dinámica es gestionada de forma explícita por el programador:
podemos solicitar memoria y liberar memoria solicitada anteriormente.
Según reservamos más memoria, la memoria dinámica crece hacia abajo. La
memoria que solicitemos permanece reservada hasta que la liberemos,
independientemente de desde qué punto del código la hemos reservado.
• La pila es gestionada automáticamente. Almacena lo necesario para
implementar las llamadas a funciones, incluyendo paso de parámetros y
variables locales de las funciones. Al acabar la función se libera la memoria.
Por tanto es un error intentar acceder a un parámetro o variable local de una
función cuando ya ha terminado la ejecución de ésta.

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2

4/10



3. Punteros



• Un puntero de tipo T es una dirección de memoria donde “se puede almacenar”

un valor tipo T. Es decir, un par (dirección de memoria, tipo “almacenable”).


• Gráficamente:



puntero: dirección xxxx ⇒
tipo = int



MEMORIA



aquí puede almacenarse un int







• Un puntero es parecido a una referencia indirecta de java, es decir, al papel de
una variable java cuyo tipo sea un tipo compuesto, por ejemplo, String a. Pero
en C el tipo almacenable es cualquiera, tipos básicos y compuestos.


• Declaración de una variable de tipo puntero en C: mediante uso de *



• Operadores sobre punteros:

tipo * nombre;



int *p1, *p2;
float i, *p3, j;
unsigned *p4, k, l= 8;



o Dirección: &. Dada una variable de tipo T, devuelve un puntero a esa

variable de tipo “puntero a T” (e.d., TIPO “ T * ”).

int a, *b;
b= &a; // b recibe la dirección de a


Equivalencia en java: rol equivalente al de una variable java cuyo tipo es
compuesto (referencia indirecta). Para tipos simples no existe. Ejemplo:


String a, b;
a = new String(“Hola”);
b = a; // b referencia a, sólo hay un string



o Indirección: *. Dado un puntero de tipo T, devuelve la variable de tipo

T apuntada por ese puntero.
int a, *b= &a;
*b= 33; // izquierda de asignación
a = *b + 2; // derecha de asignación


Equivalencia java: no hay equivalencia directa del concepto, pero los
métodos equals y clone de java tienen algo que ver con esta idea: se
ocupan de comparar/asignar lo referenciado, en vez de la referencia. Ej.:

String a, b; boolean iguales;
a = new String(“Hola”);
b = a.clone(); // b recibe copia de a: 2 strings
iguales = a.equals(b); // compara contenido a/b

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2

5/10



• Puntero a tipo no definido (apunta a cualquier tipo): void *

int i;
float f;
void * p2= &i;
p2= &f;


• Puntero nulo: NULL (definido en stdio.h) = (void *) 0

o Se puede usar como valor de inicialización (ojo, en C no hay
inicialización por defecto de punteros, a NULL ni a nada, al igual que los
tipos numéricos no se inicializan a 0 ni a nada por defecto).

o Usado en algunas funciones como valor de error.
o Los punteros se pueden usar como booleanos. NULL es false y cualquier

otra cosa es true.



REGLA DE ORO (vers. 2): siempre inicializar “todo” antes de usarlo,

¡ESPECIALMENTE LOS PUNTEROS!



• Compatibilidad en la asignación entre punteros:
o Se pueden asignar punteros del mismo tipo.

o Se pueden asignar punteros (void *) a cualquier otro, y viceversa.

o Se pueden asignar punteros a tipos distintos con casting explícito.

int *p1, *p2;
int k;
p1= &k;
p2= p1;
int *p1;
void *p2;
p1= p2;
p2= p1;
int *p1;
float *p2;
p1= (int *) p2;
p2= (float *) p1;





o Lo anterior posibilita la mezcla de tipos. Por ejemplo, si una variable
contiene el número real 4, ¿qué obtendríamos si interpretáramos su
representación como un entero?

float f= 4.0;
float *p1= &f;
/* p1 apunta a f */
int *p2;
p2= (int *) p1; /* p2 apunta a f */
printf("%d", *p2); /* *p2 es f, pero “visto” como un entero */

o ¿Cómo escribir un puntero con printf? Probar ejemplos.





Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2


6/10

• Aritmética de punteros: A un puntero se le puede sumar o restar un entero.

o El valor de puntero avanza (o decrementa) según el tamaño del tipo

referenciado. Por ejemplo: p= p+1

 char *p → El puntero aumenta 1 byte
 int *p
 void *p → “ “ “ 1 byte


→ “ “ “ 4 bytes (sizeof(int)=4)



o Ejemplo1.


float f= 1, g= 2, h= 3, i= 4; // variables globales
main () {

float *p1= &f;
float *p2;
p1= p1 + 2;
printf("%g\n", *p1);
p1--;

printf("%g\n", *p1);
printf("%g\n", *(p1+2));
p2= &i; p1= &f;
printf("%d\n", p2-p1); /* Restar dos punteros */

/* Sumar a un puntero un entero*/
/* Decrementar un puntero en uno */

}



¡¡Cuidado con la aritmética de punteros!!

Los resultados de un error pueden ser catastróficos.

• Otras posibilidades. Comparar punteros (==), asignar a un tipo entero (casting

implícito), usar como un booleano, etc.


• Punteros a punteros a punteros a ….

int i= 33;
int *p1= &i;
int **p2= &p1;
int ***p3= &p2;
...

int ***p3

int **p2

int *p1

int i



• Punteros a registros. (struct persona *). Como en java con clases, para
acceder a los miembros se puede usar la notación flecha: puntero->miembro

struct persona *pt1;
pt1= &pers1;
pt1->edad = 9; /* Equivalente a: (*p1).edad = 9; */
pt1->s = nsnc;

33



1 NOTA: error en página 297 del texto guía (volumen I), porque se usan variables locales a main,
almacenadas al revés (pila de llamadas a funciones).

Algoritmos y Estructuras de Datos, 2007/2008
Seminario de C – Sesión 2

7/10

4. Arrays

• Un array o tabla almacena un número fijo de datos en posiciones de memoria

consecutivas.


• OJO: no son objetos, al contrario que en java. No tienen métodos. En particular,

no hay forma de saber su tamaño, salvo “recordando” con cuál se creó.

• Definición de un array en C:
tipo nombre [tamaño];



int a[10];
float i, b[20], c[10];
  • Links de descarga
http://lwp-l.com/pdf1974

Comentarios de: SEMINARIO “C para programadores java” - Sesión 2 (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad