TÉCNICAS DE PROGRAMACIÓN Lenguaje C Apuntadores y arreglos.

Slides:



Advertisements
Presentaciones similares
Curso de java básico (scjp)
Advertisements

DATSI, FI, UPM José M. Peña Programación en C DATSI, FI, UPM José M. Peña Programación en C.
Tablas. Descripción general Introducción a las tablas Creación de tablas Uso de tablas.
Repaso para la construcción del intérprete 2012
Programación I Teoría III
Direcciones, Arreglos y Argumentos de Funciones
Funciones. Programación, Algoritmos y Estructuras de Datos.
Tipos de Datos Básicos y Estructurados
Desarrollo de Aplicaciones para Internet
Punteros Universidad Nacional Mayor de San Marcos
Introducción al Lenguaje C (ANSI)
UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO
Informática II 1 Diego Fernando Serna RestrepoSemestre 2011/2.
Programación Estructurada
Estructuras de control
ESTRUCTURAS DE SECUENCIA
Unidad 3 Punteros.
Ingeniero Anyelo Quintero
¿Qué es un PUNTERO?: Un puntero es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. No.
Tema 7: Polimorfismo Antonio J. Sierra. Índice Introducción. Sobrecarga de métodos. Objetos como parámetros. Paso de argumentos. Devolución de objetos.
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.

Material de apoyo Unidad 2 Estructura de datos
Semana 5 Subprogramas..
FUNCIONES EN C. SOBRE FUNCIONES... Caja negra in_1 in_N out_1 In_2 Función: Nombre. (Con el cual es invocada). Entradas. (Parámetros de la función). Salida.
Cadenas y apuntadores Programación.
SCJP SUN CERTIFIED PROGRAMMER FOR JAVA 6. SEMANA TRES ASIGNACION.
Capítulo 5. Punteros y Cadenas de Caracteres
Archivos.
Programación I Teoría VIII: Entrada/Salida
Java. Java nació el año 1991, por un par de ingenieros de la Sun Microsystems.
Prof. Mayra M. Méndez Anota.  Herramientas  Características  Convenciones  Estructura de una clase  Sintaxis de: métodos, atributos, constructores.
CAPITULO 1 - INTRODUCCIÓN Comenzaremos con una rápida introducción al lenguaje C. Mostraremos algunos elementos esenciales del lenguaje en programas reales,
El lenguaje de programación C - Identificadores y variables – Isidro González Caballero ( Introducción.
El lenguaje de programación C - Vectores y matrices -
1 Asignación Dinámica de Memoria Agustín J. González Versión original de Kip Irvine ELO 329.
Introducción a los punteros Prof. Domingo Hernández.
FUNCIONES Conceptos básicos. Retorno de una función Clases de funciones. Paso de parámetros. Funciones y arrays.
Informática Ingeniería en Electrónica y Automática Industrial
Programación Técnica1UVM Tipos de Datos. Programación Técnica2UVM.
Programación en C para electrónicos
Punteros.
PUNTEROS Y REFERENCIAS
TÉCNICAS DE PROGRAMACIÓN Lenguaje C
1 Algunas ideas básicas de C++ Agustín J. González ELO-320.
TÉCNICAS DE PROGRAMACIÓN Lenguaje C - 2
APUNTADORES.
1 Algunas ideas básicas en C++ Agustín J. González ELO-329.
PROGRAMACIÓN MULTIMEDIA
1 Algunas ideas básicas de C++ Agustín J. González ELO-329.
CARACTERÍSTICAS Es un lenguaje de programación estructurado de propósito general. Está estrechamente asociado al sistema operativo UNIX, ya que el propio.
Computación II Capitulo VII Punteros. Presentación de la unidad Objetivos: –Ser capaces de utilizar punteros. –Comprender las relaciones entre punteros,
1 Algunas ideas básicas de C++ Agustín J. González ELO-329.
1 Asignación Dinámica de Memoria Agustín J. González ELO 329.
1 Algunas ideas básicas de C++ Agustín J. González ELO-329.
Tipo de dato char El tipo de dato char ocupa un byte de memoria. Con un byte solo se puden guardar 256 números enteros sin signo, del 0 – 255. Si a cada.
Capitulo 4 Arreglos o Arrays Unidimensionales Bidimensionales Strings
Empleando apuntadores una función puede entregar múltiples resultados / /Esta función no funciona #include void intercambiaValores(float a, float b) {

LENGUAJE “C” Programación.
1 TÉCNICAS DE PROGRAMACIÓN Lenguaje C Tercera Clase (Segunda de C)
Fundamentos de Programación
Ing. Esp. Ricardo Cujar.  Lenguaje de programación orientado a objetos.  Desarrollado por Sun MicroSystems.  Independiente del Sistema Operativo gracias.
PUNTEROS EN EL LENGUAJE C
TÉCNICAS DE PROGRAMACIÓN Lenguaje C
Conceptos y Lenguaje Imperativo
MEMORIA DINÁMICA.
Introducción al Lenguaje C (I) Tipos básicos, arrays y punteros Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Versión
Lenguaje de Programación II Prof. Rafael Montenegro B. Carrera: T.S.U en Informática Periodo: 2014-I.
Spanish-Months of the Year
Transcripción de la presentación:

TÉCNICAS DE PROGRAMACIÓN Lenguaje C Apuntadores y arreglos

Daniel Finol – ICA - LUZ 2 APUNTADORES Y ARREGLOS CAPÍTULO 5 DE KyR

Daniel Finol – ICA - LUZ 3 Apuntadores Un apuntador es una variable que contiene la dirección de otra variable. p = &c El operador & da la dirección en memoria de un objeto. –Sólo se aplica a variales y elementos de arreglos. –No se aplica a: expresiones, registros ni constantes.

Daniel Finol – ICA - LUZ 4 Operador unario * El operador unario * se aplica sólo a apuntadores. Da acceso al objeto al que señala el apuntador. Se llama "indirección" o "desreferencia". También se usa para declarar a una variable como apuntador. Ej: int x = 1, y = 2, z[10]; int *ip; /* ip es un apuntador a int */ ip = &x; /* ip ahora apunta a x */ y = *ip; /* y ahora es 1 */ *ip = 0; /* x ahora es 0 */ ip = &z[0]; /* ip ahora apunta a z[0] */

Daniel Finol – ICA - LUZ 5 Operador unario * El operador unario * se aplica sólo a apuntadores. Da acceso al objeto al que señala el apuntador. Se llama "indirección" o "desreferencia". También se usa para declarar a una variable como apuntador. Ej: int x = 1, y = 2, z[10]; int *ip; /* ip es un apuntador a int */ ip = &x; /* ip ahora apunta a x */ y = *ip; /* y ahora es 1 */ *ip = 0; /* x ahora es 0 */ ip = &z[0]; /* ip ahora apunta a z[0] */ *ip es un int

Daniel Finol – ICA - LUZ 6 Un apuntador está restringido a señalar a una clase particular de objeto. (Excepción void *). Ej: *ip = *ip + 10; y = *ip + 1 *ip += 1 ++*ip (*ip)++ iq = ip Los operadores unario como * y ++ se asocian de derecha a izquierda.

Daniel Finol – ICA - LUZ 7 Apuntadores y argumentos ¿Cómo hacer para que una función llamada altere una variable de la función que la llamó? Ej: swap(a, b); void swap(int x, int y) { int temp; temp = x; x = y; y = temp; }

Daniel Finol – ICA - LUZ 8 Apuntadores y argumentos ¿Cómo hacer para que una función llamada altere una variable de la función que la llamó? Ej: swap(a, b); void swap(int x, int y) { int temp; temp = x; x = y; y = temp; }

Daniel Finol – ICA - LUZ 9 Apuntadores y argumentos: Intercambio (swap) swap(&a, &b); void swap(int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; }

Daniel Finol – ICA - LUZ 10 getint int n, array[SIZE], getint(int *); for (n = 0; n < SIZE && getint(&array[n]) !=EOF; n++); int getint(int *pn) { int c, sign; while (isspace(c = getch())); if (!isdigit(c) && c != EOF && c != '+' && c != '-') { ungetch(c); return 0; } sign = (c == '-') ? -1 : 1; if (c == '+' || c == '-') c = getch(); for (*pn = 0; isdigit(c), c = getch()) *pn = 10 * *pn + (c - '0'); *pn *= sign; if (c != EOF) ungetch(c); return c; }

Daniel Finol – ICA - LUZ 11 Apuntadores y arreglos int a[10]; int *pa; pa = &a[0]; x = *pa /*copia el contenido de a[0] en x */

Daniel Finol – ICA - LUZ 12 Apuntadores y arreglos Si pa apunta a una elemento de un arreglo: pa + 1 ; apunta al siguiente elemento. pa + i ; apunta i elementos después de pa. pa - i ; apunta i elementos antes de pa. Si pa apunta a a[0] : *(pa + 1); se refiere al contenido de a[1]. pa + i; es la dirección de a[i]; *(pa + i); es el contenido de a[i]. Todo esto funciona independiente del tamaño de los elementos del arreglo a.

Daniel Finol – ICA - LUZ 13 Apuntadores y arreglos El nombre de un arreglo es un sinónimo de la dirección del primer elemento: pa = &a[0]; es equivalente a: pa = a; a[i] es equivalente a: *(a + i). &a[i] es equivalente a: a + i. Se pueden usar subíndices con un apuntador: pa[i] es equivalente a *(pa + i). Diferencia entre nombre de arreglo y apuntador: pa = a; pa++; son legales. a = pa; a++; son ilegales.

Daniel Finol – ICA - LUZ 14 Apuntadores, arreglos y argumentos. Cuando un nombre de arreglo se pasa a una función, lo que se pasa es la dirección del primer elemento: Los parámetros formales char s[] y char *s, son equivalentes. Ej: int strlen(char *s) { int n; for (n = 0; *s != '\0', s++) n++; return n; } strlen("hello, world"); /* string constant */ strlen(array); /* char array[100]*/ strlen(ptr); /* char *ptr; */

Daniel Finol – ICA - LUZ 15 Apuntadores, arreglos y argumentos Es posible pasar parte de un arreglo a una función, pasando un apuntador al inicio del subarreglo: f(&a[2]); f(a + 2); La declaración de f puede ser: f(int arr[ ]); f(int *arr); Para f es indiferente que lo que se le pase sea parte de un arreglo más grande.

Daniel Finol – ICA - LUZ 16 Aritmética de direcciones: alloc y afree #define ALLOCSIZE static char allocbuf[ALLOCSIZE]; static char *allocp = allocbuf; char *alloc(int n) { if (allocbuf + ALLOCSIZE - allocp >= n) { allocp += n; return allocp - n; } else return 0; } void afree(char *p) { if(p >= allocbuf && p < allocbuf + ALLOCSIZE) allocp = p; }

Daniel Finol – ICA - LUZ 17

Daniel Finol – ICA - LUZ 18 Aritmética de direcciones Si dos apuntadores apuntan a elementos del mismo arreglo pueden compararse con: ==, !=, =, etc. A un apuntador se le puede sumar o restar un entero: p + n. (n se escala). Dos apuntadores se pueden restar si apuntan al mismo arreglo. Si p < q, entonces: q – p + 1; es el número de elementos desde p a q inclusive. Un apuntador puede asignarse o compararse con el entero 0 (NULL).

Daniel Finol – ICA - LUZ 19 Aritmética de direcciones: strlen (nueva versión) int strlen(char *s) { char *p = s; while (*p != '\0') p++; return p - s; }

Daniel Finol – ICA - LUZ 20 Apuntadores a caracteres y funciones. char *pmensaje; pmensaje = "ya es tiempo"; /*No hay copia*/ char amessage[] = "now is the time"; char *pmessage = "now is the time"; ¿Qué se puede modificar y qué no?

Daniel Finol – ICA - LUZ 21 strcpy: v1 void strcpy(char *s, char *t) { int i; i = 0; while ((s[i] = t[i]) != '\0') i++; }

Daniel Finol – ICA - LUZ 22 strcpy: v2 void strcpy(char *s, char *t) { while ((*s = *t) != '\0') { s++; t++; }

Daniel Finol – ICA - LUZ 23 strcpy: v3 void strcpy(char *s, char *t) { while ((*s++ = *t++) != '\0') ; }

Daniel Finol – ICA - LUZ 24 strcpy: v4 void strcpy(char *s, char *t) { while (*s++ = *t++) ; }

Daniel Finol – ICA - LUZ 25 strcmp: v1 int strcmp(char *s, char *t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == '\0') return 0; return s[i] - t[i]; }

Daniel Finol – ICA - LUZ 26 strcmp: v2 int strcmp(char *s, char *t) { for ( ; *s == *t; s++, t++) if (*s == '\0') return 0; return *s - *t; }

Daniel Finol – ICA - LUZ 27 Quicksort void qsort(int v[], int left, int right) { int i, last; void swap(int v[], int i, int j); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left + 1; i <= right; i++) if (v[i] < v[left]) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); }

Daniel Finol – ICA - LUZ 28 swap void swap(int v[], int i, int j) { int temp; temp = v[i]; v[i] = v[j]; v[j] = temp; }

Daniel Finol – ICA - LUZ 29 Arreglos de apuntadores y apuntadores a apuntadores #include #define MAXLINES 5000 char *lineptr[MAXLINES]; int readlines(char *lineptr[], int nlines); void writelines(char *lineptr[], int nlines); void qsort(char *lineptr[], int left, int right); main() { int nlines; if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { qsort(lineptr, 0, nlines-1); writelines(lineptr, nlines); return 0; } else { printf("error: input too big to sort\n"); return 1; }

Daniel Finol – ICA - LUZ 30 readlines #define MAXLEN 1000 int getline(char *, int); char *alloc(int); /* readlines: read input lines */ int readlines(char *lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) if (nlines >= maxlines || p = alloc(len) == NULL) return -1; else { line[len-1] = '\0'; /* delete newline */ strcpy(p, line); lineptr[nlines++] = p; } return nlines; }

Daniel Finol – ICA - LUZ 31 writelines /* writelines: write output lines */ void writelines(char *lineptr[], int nlines) { int i; for (i = 0; i < nlines; i++) printf("%s\n", lineptr[i]); } void writelines(char *lineptr[], int nlines) { while (nlines-- > 0) printf("%s\n", *lineptr++); }

Daniel Finol – ICA - LUZ 32 Quicksort – Original Para Enteros void qsort(int v[], int left, int right) { int i, last; void swap(int v[], int i, int j); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left + 1; i <= right; i++) if (v[i] < v[left]) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); }

Daniel Finol – ICA - LUZ 33 Quicksort para cadenas void qsort(char *v[], int left, int right) { int i, last; void swap(char *v[], int i, int j); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left + 1; i <= right; i++) if (strcmp(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1); qsort(v, last+1, right); }

Daniel Finol – ICA - LUZ 34 swap void swap(char *v[], int i, int j) { char *temp; temp = v[i]; v[i] = v[j]; v[j] = temp; } Sería mucho más costoso en tiempo de ejecución y más engorroso en manejo del almacenamiento tener que mover las cadenas completas

Daniel Finol – ICA - LUZ 35 Arreglos multidimensionales static char daytab[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int day_of_year(int year, int month, int day) { int i, leap; leap = year%4 == 0 && year%100 != 0 || year%400==0; for (i = 1; i < month; i++) day += daytab[leap][i]; return day; } void diaMes(int year, int yearday, int* pmonth,int *pday) { int i, leap; leap = year%4 == 0 && year%100 != 0 || year%400 == 0; for (i = 1; yearday > daytab[leap][i]; i++) yearday -= daytab[leap][i]; *pmonth = i; *pday = yearday; }

Daniel Finol – ICA - LUZ 36 Inicialización de arreglos a apuntadores char *month_name(int n) { static char *name[] = { "Mes Ilegal", "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" }; return (n 12) ? name[0] : name[n]; }

Daniel Finol – ICA - LUZ 37 Apuntadores versus Arreglos Multidimensionales int a[10][20]; int *b[10]; Tanto a[3][4] como b[3][4] son válidas. Para a: se han reservado 200 localidades de memoria del tamaño de un int. esas localidades son contiguas. se almacenan por filas. para ubicar el elemento a[fila][col] se usa la fórmula: #columnas * fila + col Para b: sólo existen espacios para 10 apuntadores si cada elem. de b apunta a un arreglo de 20, habrá 200 ints reservados + 10 espacios para los apuntadores. La ventaja del arreglo de apuntadores es que cada fila puede ser de tamaño distinto.

Daniel Finol – ICA - LUZ 38 Apuntadores versus Arreglos Multidimensionales char *name[] = { "Illegal month", "Jan", "Feb", "Mar" }; char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };

Daniel Finol – ICA - LUZ 39 Argumentos de la línea de comandos echo hello, world hello, world main(int argc, char *argv[])

Daniel Finol – ICA - LUZ 40 Argumentos de la línea de comandos: echo main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) printf("%s%s", argv[i], (i < argc-1) ? " " : ""); printf("\n"); return 0; } main(int argc, char *argv[]) { while (--argc > 0) printf("%s%s", *++argv, (argc > 1) ? " " : ""); printf("\n"); return 0; } printf((argc > 1) ? "%s " : "%s", *++argv);

Daniel Finol – ICA - LUZ 41 #include #define MAXLINE 1000 int getline(char *line, int max); main(int argc, char *argv[]) { char line[MAXLINE]; int found = 0; if (argc != 2) printf("Usage: find pattern\n"); else while (getline(line, MAXLINE) > 0) if (strstr(line, argv[1]) != NULL) { printf("%s", line); found++; } return found; }

Daniel Finol – ICA - LUZ 42 main(int argc, char *argv[]) { char line[MAXLINE]; long lineno = 0; int c, except = 0, number = 0, found = 0; while (--argc > 0 && (*++argv)[0] == '-') while (c = *++argv[0]) switch (c) { case 'x': except = 1; break; case 'n': number = 1; break; default: printf("find: illegal option %c\n", c); argc = 0; found = -1; break; } /*······················CONTINÚA························*/

Daniel Finol – ICA - LUZ 43 if (argc != 1) printf("Usage: find -x -n pattern\n"); else while (getline(line, MAXLINE) > 0) { lineno++; if((strstr(line, *argv) != NULL) != except){ if (number) printf("%ld:", lineno); printf("%s", line); found++; } return found; }

Daniel Finol – ICA - LUZ 44 Ordenar líneas según opción #include #define MAXLINES 5000 char *lineptr[MAXLINES]; int readlines(char *lineptr[], int nlines); void writelines(char *lineptr[], int nlines); void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *)); int numcmp(char *, char *); /*······················CONTINÚA························*/

Daniel Finol – ICA - LUZ 45 Apuntadores a funciones main(int argc, char *argv[]) { int nlines; /* número de líneas leídas */ int numeric = 0; if (argc > 1 && strcmp(argv[1], "-n") == 0) numeric = 1; if((nlines = readlines(lineptr, MAXLINES)) >= 0) { qsort((void**) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ? numcmp : strcmp)); writelines(lineptr, nlines); return 0; } else { printf("input too big to sort\n"); return 1; }

Daniel Finol – ICA - LUZ 46 Quicksort – más genéral void qsort(void *v[], int left, int right, int (*comp)(void *, void *)) { int i, last; void swap(void *v[], int, int); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left+1; i <= right; i++) if ((*comp)(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); qsort(v, left, last-1, comp); qsort(v, last+1, right, comp); }

Daniel Finol – ICA - LUZ 47 int numcmp(char *s1, char *s2) { double v1, v2; v1 = atof(s1); v2 = atof(s2); if (v1 < v2) return -1; else if (v1 > v2) return 1; else return 0; } void swap(void *v[], int i, int j;) { void *temp; temp = v[i]; v[i] = v[j]; v[j] = temp; }