PDF de programación - SEMINARIO DE C - Sesión 2

Imágen de pdf SEMINARIO DE C - Sesión 2

SEMINARIO DE C - Sesión 2gráfica de visualizaciones

Actualizado el 20 de Mayo del 2018 (Publicado el 27 de Abril del 2017)
559 visualizaciones desde el 27 de Abril del 2017
187,2 KB
10 paginas
Creado hace 15a (27/09/2005)
Algoritmos y Estructuras de Datos

Ingeniería en Informática, Curso 2º

SEMINARIO DE C

Sesión 2



Contenidos:

1. Punteros
2. Arrays
3. Estructuras (registros) y uniones
4. Funciones
Ejercicios



Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



2/10

1. Punteros

• Un puntero es una dirección de memoria donde se puede almacenar un valor de

cierto tipo.


• Declaración de un tipo puntero en C: *
tipo * nombre;



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

• Operadores sobre punteros:

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

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

o Indirección: *. Dado un puntero (o expresión puntero) de tipo T,

devuelve el valor de tipo T apuntado por ese puntero (o expresión).

int i=33, *p1;
p1= &i;

int i=33, *p1= &i;
*p1= 22;

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

• Puntero a tipo no definido: void *



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

inicialización por defecto).

o Se puede usar como valor de inicialización (ojo, en C no hay
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.


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

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

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;

Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



3/10



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.

• 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 Ejemplo.

float f= 1, g= 2, h= 3, i= 4;
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. 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

33

Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



4/10

2. Arrays

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

consecutivas.


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



int a[10];
float i, b[20], c[10];



• Ojo: Sólo se indica el tamaño del array. int a[10]. El primer elemento es

siempre a[0], el segundo a[1], …, el último es a[9].


a[0]

a[1]

a[2]

a[3]

a[4]

a[5]

a[6]



a[7]

a[8]



a[9]



• Inicialización de los valores en la declaración:
int a[4]= {2, 4, 12, 3};
int b[]= {1, 2, 3, 4, 5, 6}; → Se puede omitir el tamaño (será 6)
int c[100]= {1, 2, 3, 4, 5}; → Sólo se inicializan los 5 primeros valores

• Cadenas de caracteres. En C no existe el tipo “cadena”, se usan arrays de





char, donde el número 0 (ó carácter '\0') indica el fin de cadena.


char c1[20]= {'H', 'o', 'l', 'a', 0};
char c2[20]= "Hola cadena";
char c3[]= "Así es más fácil";

printf(c1);
printf(c2);
printf("\nLa cadena c1 vale: [%s] y la c3: [%s]\n", c1, c3);
c2[4]= '\n';
c2[5]= 0; /* Equivalente a c2[5]= '\0'; */
printf(c2);

• Arrays n-dimensionales.
int matriz[10][4][20];
int m2[2][3]= {{1, 2, 3}, {2, 3, 1}};
float m3[][4]= {{0., 1., 2., 3.}, {1.1, 1.2, 1.3, 5.4}};

• Ojo: no está definida la asignación entre arrays, ni la comparación. Solución:

hacer un bucle que copie, o compare, los elementos uno a uno.

• Arrays y punteros:

o Un array de tipo T es equivalente a un puntero a tipo T.

→ a equivale a &a[0]
→ Acceso al 5º elemento de a, e.d. a[4]
→ a+2 equivale a &a[2]

o Se puede asignar un array a un puntero, pero no al revés.
o Con un puntero a tipo T se pueden usar los corchetes.

→ a= p1; daría un error de compilación

int a[10], *p1;

*a= 8;
*(a+4) = 11;
p1= a + 2;



p1= a;
p1[3]= 38;
p1[0]= *(p1+1);

"equivalente" a un puntero de tipo T, con n*m elementos.
int i, j;
int mat[5][5];
int *p1= mat, *p2= mat[4];
for (i= 0; i<5*5; i++, p1++)
*p1= 0;
p1= mat;
*p1= 1;
p1[8]= 2;
*p2= 3;
*(p2+2)= 4;
mat[1][1]= 5;
(++p1)[2]= 6;
for (i= 0; i<5; i++) {
for (j= 0; j<5; j++)
printf("%d ", mat[i][j]);
printf("\n");
}



Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



5/10

o Una matriz (array bidimensional) de dimensiones nxm de tipo T es



m[0][0] m[0][1] m[0][2] m[0][3] m[0][4] m[1][0] m[1][1] m[1][2] m[1][3]



m[1][4] m[2][0] m[2][1] m[2][2] m[2][3] m[2][4] m[3][0] m[3][1] m[3][2]



m[3][3] m[3][4] m[4][0] m[4][1] m[4][2] m[4][3] m[4][4]



Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



6/10

3. Estructuras (registros) y uniones


• Un registro (en C, estructura) agrupa un conjunto de campos de diversos tipos

en un nuevo tipo compuesto.
struct persona {
unsigned long DNI;
char nombre[100];
int edad;
enum sexo s;
};
struct persona pers1, pers2;

struct fecha {
int dia, mes, ano;
} fecha1, fechas[10];






• Los campos de la estructura se denominan también miembros.

• Se accede a los miembros utilizando la notación punto: variable.miembro

• Punteros a registros. (struct persona *). El acceso a los miembros se

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

puede hacer usando la notación flecha: puntero->miembro
struct persona *pt1;
pt1= &pers1;
pt1->edad = 9; /* Equivalente a: (*p1).edad = 9; */
pt1->s = nsnc;

• 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.

union numero {
int asInt;
float asFloat;
double asDouble;
} n1;
n1.asInt= 4;
printf("%g", n1.asDouble);

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



enumerados, etc.).

• C permite dar nombre a los nuevos tipos definidos (estructuras, registros,




• Definición de tipos: typedef expresión_tipo nombre_nuevo;
typedef unsigned char byte;
typedef byte * byte_pointer;
typedef struct persona tipo_persona;
typedef int[10][10] matriz;

byte b1= 1, b2[10]; /* Equivalente a: unsigned char b1, b2[10]; */

Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



7/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);



Algoritmos y Estructuras de Datos
Seminario de C – Sesión 2



8/10

4. Funciones


• Estructura de definición de funciones:

tipo_devuelto nombre_función ( parámetros ) { cuerpo }

int suma (int a, int b)
{
int r= a+b;
return r;
}

• Una función no se puede declarar dentro de otra (no se pueden anidar), aunque sí

se pueden definir y anidar bloques: { … { … } … { { } … } …}


• Valor devuelto.

o Sólo puede haber 1 tipo devuelto (como en Módula, Pascal o Java).
o Si no devuelve nada se pone: void
o Por defecto, si no se pone nada, se supone que devuelve un int.
o Se puede devolver un struct o union, pero no un array. En su lugar, se
o Acabar la ejecución del procedimiento: return;
o Acabar y devolver un valor: return expresion;

puede devolver un puntero al array.

• Parámetros.

o Lista de pares: (tipo1 nombre1, tipo2 nombre2, ...)
o Cada nombre debe llevar su tipo (aunque se repitan).
o El paso es siempre por valor.
o Simulación del paso por referencia: usar punteros.

void suma2 (int a, int *b)
{
int r= a + *b;
*b= r;
}
float media (int array[], int tamano) ...

o Paso de arrays: no se especifica el tamaño. Alternativa: usar punteros.



• Variables locales.

las llaves, {.

o Deben ir siempre al principio del cuerpo de la función, justo después de
o Se crean en la pila para cada llamada y se eliminan al acabar (auto).
o Variables locales static: conservan sus valores entre distintas llama-
das (equivalentes a v
  • Links de descarga
http://lwp-l.com/pdf3233

Comentarios de: SEMINARIO DE C - 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