--- title: Lenguaje C - Módulo 5 --- # Módulo 5 *** ## Indexado *** Se puede acceder a los elementos de un arreglo a través de su índice, pero también es posible tratarlo como un puntero. ```c= #include <stdio.h> int main() { int lista[10] = {10, 20, 30, 40, 50, 60, 70}; int i=3; //accediendo al arreglo a través del índice printf("\n%d", lista[i]); //accediendo al arreglo como si fuese un puntero printf("\n%d", *lista); printf("\n%d", *(lista + i)); return 0; } ``` Se puede trabajar los arreglos de caracteres. ```c= #include <stdio.h> int main() { char lista[10] = "Vampiro"; int i=3; //accediendo al arreglo a través del índice printf("\n%c", lista[i]); //accediendo al arreglo como si fuese un puntero printf("\n%c", *lista); printf("\n%c", *(lista + i)); return 0; } ``` ```c= #include <stdio.h> int main() { char lista[10] = "Vampiro"; // indice 0123456 int i = 3; // accediendo al arreglo a través del índice printf("\n%c", lista[i]); printf("\n%c", lista[6]); // accediendo al arreglo como si fuese un puntero printf("\n%c", *lista); printf("\n%c", *(lista + i)); printf("\n%c", *(lista + 6)); return 0; } ``` Recordar el uso de punteros: ```c= #include <stdio.h> int main() { int a = 15; int *p; p = &a; //p apunta a la variable "a" printf("\n %d %d", &a, a); printf("\n %d %d %d", &p, p, *p); } ``` Uso de punteros a arreglos ```c= #include <stdio.h> int main() { int lista[10] = {10, 20, 30, 40, 50, 60, 70}; int i = 3; int *p; // accediendo al arreglo a través del índice printf("\n%d", lista[i]); // accediendo al arreglo como si fuese un puntero printf("\n%d", *lista); printf("\n%d", *(lista + i)); // Utilizando punteros p = lista; // p=&lista[0]; // p = lista + 2; // p=&lista[2]; printf("\n%d", *p); printf("\n%d", *p + 1); printf("\n%d", *(p + 1)); return 0; } ``` ```c= #include <stdio.h> int main() { int lista[10] = {10, 20, 30, 40, 50, 60, 70}; int i = 3; int *p; // accediendo al arreglo a través del índice // printf("\n%d", lista[i]); // accediendo al arreglo como si fuese un puntero // printf("\n%d", *lista); // printf("\n%d", *(lista + i)); // Utilizando punteros // int lista[10] = {10, 20, 30, 40, 50, 60, 70}; // 0 1 2 3 4 5 6 // p // p = lista; // p = &lista[2]; p++; // desplazar el puntero // p = lista + 2; // p=&lista[2]; printf("\n%d", *p); printf("\n%d", *p + 2); printf("\n%d", *(p - 2)); return 0; } ``` ```c= #include <stdio.h> int main() { int lista[10] = {10, 20, 30, 40, 50, 60, 70}; int i = 3; int *p; // accediendo al arreglo a través del índice // printf("\n%d", lista[i]); // accediendo al arreglo como si fuese un puntero // printf("\n%d", *lista); // printf("\n%d", *(lista + i)); // Utilizando punteros // int lista[10] = {10, 20, 30, 40, 50, 60, 70}; // 0 1 2 3 4 5 6 // p p = lista + 2; // p=&lista[0] // p = &lista[2]; // p++; // desplazar el puntero // p = lista + 2; // p=&lista[2]; printf("\n%d", *p); printf("\n%d", *p + 2); printf("\n%d", *(p + 2)); return 0; } ``` >Describa la función de cada una de las siguientes sentencias utilizando las variables del ejercicio anterior. >Si i=3; >int lista[10] = {10, 20, 30, 40, 50, 60, 70}; >- lista[i] --> 40 >- *lista --> 10 >- *(lista + i) --> 40 >- *lista + i --> 13 >- i[lista] --> 40 >- *(i + lista) --> 40 Cadena de caracteres vs arreglo de caracteres: ```c= #include <stdio.h> int main() { char lista[8] = "Vampiro"; // string // 01234567 --> 0 '\0' char lista2[8] = {'V', 'a', 'm', 'p', 'i', 'r', 'o', '\0'}; // 0 1 2 3 4 5 6 int i = 3; printf("\n%s", lista); printf("\n%s", lista2); return 0; } ``` ```c= /* strcpy example */ #include <stdio.h> #include <string.h> int main() { char str1[] = "Sample string"; char str2[40]; char str3[40]; strcpy(str2, str1); strcpy(str3, "copy successful"); printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3); return 0; } ``` ```c= /* strcpy example */ #include <stdio.h> #include <string.h> int main() { char str1[] = "Sample string"; char str2[40]; char str3[40]; strcpy(str2, str1); strcpy(str3, "copy successful"); printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3); return 0; } ``` Algunos errores al utilizar arreglos de caracteres ```c= // ERROR #include <stdio.h> #include <string.h> int main(void) { char *ptr; strcpy(ptr, "you may get into trouble soon"); puts(ptr); return 0; } ``` ```c= // SOLUCION #include <stdio.h> #include <string.h> int main(void) { char *ptr; char cadena[30]; ptr = &cadena[0]; //ptr = cadena; strcpy(ptr, "you may get into trouble soon"); puts(ptr); return 0; } ``` ```c= //ERROR #include <stdio.h> int main(void) { char *ptr; *ptr = 'C'; printf("%c",*ptr); return 0; } ``` ```c= // SOLUCION #include <stdio.h> int main(void) { char *ptr; char m; ptr = &m; *ptr = 'C'; // m='C; printf("%c", *ptr); return 0; } ``` ```c= //ERROR #include <stdio.h> #include <string.h> int main(void) { char str[10]; strcpy(str,"Welcome to Troubleland!"); printf("%s",str); return 0; } ``` ```c= // SOLUCION #include <stdio.h> #include <string.h> int main(void) { char str[24]; strcpy(str, "Welcome to Troubleland!"); // 123456789012345678901234 printf("%s", str); return 0; } ``` ```c= //ERROR #include <stdio.h> #include <string.h> int main(void) { char str[10]; int i; strcat(str,"Bump!"); printf("%s",str); return 0; } ``` ```c= // SOLUCION #include <stdio.h> #include <string.h> int main(void) { char str[10]; int i; strcpy(str, "Bump!"); printf("%s", str); return 0; } ``` *** ## Arreglos de arreglos *** Declaración de arreglos para gestionar 64 enteros. ```c= //Arreglo de 8 enteros int fila[8]; //8 ints -- 32 bytes //8 arreglos de 8 enteros cada uno int fila1[8], fila2[8], fila3[8], fila4[8]; int fila5[8], fila6[8], fila7[8], fila8[8]; // Un arreglo de 64 enteros int tabla[8][8]; //8 filas, cada fila de 8 enteros tabla[0][0]; //1ra fila, 1ra col tabla[0][1]; //1ra fila, 2da col tabla[1][0]; //2da fila, 1ra col ``` Generación de números aleatorios. ```c= #include <stdio.h> #include <time.h> int main() { float v1, v2, v3; srand(time(NULL)); v1 = rand() % 100; // v1 in the range 0 to 99 (99-0=99) v2 = rand() % 100 + 1; // v2 in the range 1 to 100 (100-1=99) v3 = rand() % 30 + 1985; // v3 in the range 1985-2014 (2014-1985=29) printf("\n%f", v1); printf("\n%f", v2); printf("\n%f", v3); return 0; } ``` Demostrar el uso de los arreglos de 2 dimensiones. ```c= #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { float temp[31][24]; // Se llena de valores la tabla de temperaturas srand(time(NULL)); for (int i = 0; i < 31; i++) { temp[i][0] = rand() % 3 + 15; for (int j = 1; j < 14; j++) temp[i][j] = temp[i][j - 1] + (rand() % 2) + 1; for (int j = 14; j < 24; j++) temp[i][j] = temp[i][j - 1] - (rand() % 2) - 2; } // Se muestra la tabla de temperaturas for (int i = 0; i < 31; i++) { for (int j = 0; j < 24; j++) printf("%3.0f", temp[i][j]); printf("\n"); } // Mostrar la temperatura promedio a la media noche int suma = 0; for (int i = 0; i < 31; i++) suma += temp[i][0]; printf("\nPromedio de temperatura a la medianoche: %6.2f", suma / 31.0); // Mostrar los días más calientes (mayor a 33 grados al mediodia) for (int i = 0; i < 31; i++) // 0 hasta 30 --> total 31 if (temp[i][12] > 34) printf("\n Dia: %d tiene %5.2f grados", i, temp[i][12]); return 0; } ``` ### *Desafio* Dibujar un tablero de ajedrez, colocando un espacio en blanco para representar la casilla blanca y colocando un punto para representar una casilla negra. ### *Desafio* En el tablero anterior ubicar las fichas del ajedrez: - P: peón - T: Torre - C: Caballo - A: Alfil - R: Rey - Q: Reina LAs fichas deben estar en el lado de las negras y las blancas. T C A R Q A C T P P P P P P P P P P P P P P P P T C A Q R A C T *** ## Asignación de memoria *** - Todas las variables tienen asignados uno o más bytes de la memoria. - Todo puntero debe contener la dirección de uno o más bytes de la memoria. Si no apunta a una posición de memoria entonces su valor es NULL. ```c= #include <stdio.h> int main() { int *p; p = (int *)malloc(sizeof(int)); //asignación dinámica *p = 15; printf("\nP= %d %d %d", &p, p, *p); free(p); return 0; } ``` ```c= #include <stdio.h> int main() { int num = 15; int *p; printf("\n%d %d", &num, num); printf("\n%d %d %d", &p, p, *p); return 0; } ``` Asignación de un espacion de memoria para ser accedida por un puntero. - Malloc: asigna un número de bytes a un puntero - Free: libera la memoria asignada al puntero ```c= #include <stdio.h> #include <stdlib.h> int main(void) { int *ptr; printf("\n%d %d", &ptr, ptr); ptr = (int *)malloc(sizeof(int) * 10); // asigna espacio para 10 enteros if (ptr != NULL) { *ptr = 200; *(ptr + 1) = 300; *(ptr + 2) = 400; printf("\n%d %d %d %d", &ptr, ptr, *ptr, *(ptr + 1)); free(ptr); printf("\n%d %d %d %d", &ptr, ptr, *ptr, *(ptr + 1)); } else printf("allocation failed"); return 0; } ``` ```c= #include <stdio.h> int main() { int *p; p = (int *)malloc(sizeof(int) * 5); // asignación dinámica *p = 15; printf("\nP= %d %d %d\n", &p, p, *p); for (int i; i < 5; i++) { *(p + i) = (i + 1) * 10; printf("%4d", *(p + i)); } free(p); return 0; } ``` ```c= #include <stdio.h> #include <stdlib.h> int main(void) { int *tabptr, i, sum = 0; tabptr = (int *)malloc(5 * sizeof(int)); for (i = 0; i < 5; i++) tabptr[i] = i; sum = 0; for (i = 0; i < 5; i++) { sum += tabptr[i]; printf("%d ", tabptr[i]); } printf("\n%d", sum); free(tabptr); return 0; } ``` ```c= #include <stdio.h> #include <stdlib.h> int main(void) { int *numbers, how_many_numbers; int i, aux; int swapped; // Pide el número de enteros a ordenar printf("How many numbers are you going to sort?"); scanf("%d", &how_many_numbers); if (how_many_numbers <= 0 || how_many_numbers > 1000000) { printf("Are you kidding?\n"); return 1; } numbers = (int *)malloc(how_many_numbers * sizeof(int)); if (numbers == NULL) { printf("Allocation failed sorry.\n"); return 1; } // solicita al usuario que ingrese los números for (i = 0; i < how_many_numbers; i++) { printf("\nEnter the number #%i :", i + 1); scanf("%d", numbers + i); } // se procede a ordenarlos por el método de ordenamiento do { swapped = 0; for (i = 0; i < how_many_numbers - 1; i++) if (numbers[i] > numbers[i + 1]) { swapped = 1; aux = numbers[i]; numbers[i] = numbers[i + 1]; numbers[i + 1] = aux; } } while (swapped); // Muestra los números ordenados printf("\nThe sorted array:\n"); for (i = 0; i < how_many_numbers; i++) printf("%d ", numbers[i]); printf("\n"); free(numbers); // libera la memoria asignada al puntero return 0; } ``` *** ## Arreglo de punteros *** ```c= ptrtab = (int **) malloc (rows * sizeof (int*)); for (r = 0; r <rows; r++) ptrtab[r] = (int *) malloc (cols * sizeof (int)); ptrtab[2][1]=99; ``` Manejo de arreglos bidemnsionales con punteros y asginación dinámica ```c= #include <stdio.h> #include <stdlib.h> int main(void) { int **ptrtab; int rows = 5; int cols = 10; ptrtab = (int **)malloc(rows * sizeof(int *)); //ptrtab[0] = (int *)malloc(10*sizeof(int)); //ptrtab[1] = (int *)malloc(10*sizeof(int)); //ptrtab[2] = (int *)malloc(10*sizeof(int)); //ptrtab[3] = (int *)malloc(10*sizeof(int)); //ptrtab[4] = (int *)malloc(10*sizeof(int)); for (int r = 0; r < rows; r++) ptrtab[r] = (int *)malloc(cols * sizeof(int)); //int ptrtab[5][10]; ptrtab[0][0] = 15; //valor para la primera columna de la primera fila ptrtab[2][1] = 99; //2da columna de la 3ra fila return 0; } ``` ```c= int rows = 5, r; int **ptrab; ptrtab = (int **) malloc (rows * sizeof (int *)); for (r = 0; r <rows; r++) ptrtab[r] = (int *) malloc (sizeof (int) * (r + 1)); ``` ### *Desafio* Hacer un programa que pida el tamaño de una tabla de multiplicación y la generé según el siguiente modelo: Sample input 5 Expected output - 1 2 3 4 5 - 1 1 2 3 4 5 - 2 2 4 6 8 10 - 3 3 6 9 12 15 - 4 4 8 12 16 20 - 5 5 10 15 20 25 ```c= #include <stdio.h> #include <stdlib.h> int main(void) { int **ptrtab; int rows = 5; int cols = 10; printf("Ingrese numero:"); scanf("%d", &rows); cols = rows; //separa la memoria para el puntero ptrtab = (int **)malloc(rows * sizeof(int *)); for (int r = 0; r < rows; r++) ptrtab[r] = (int *)malloc(cols * sizeof(int)); printf("%4d"); for(int j = 0; j < cols; j++) printf("%4d", (j+1)); printf("\n"); for (int i = 0; i < rows; i++) { printf("%4d",i+1); for (int j = 0; j < cols; j++) { printf("%4d", (i+1) * (j+1)); } printf("\n"); } return 0; } ``` *** ## Funciones *** ```c= #include <stdio.h> void hello(void) { printf ("Hola Mundo!! \n"); return; } int main() { printf("Antes de la llamar a la funcion\n"); hello(); printf("Despues de llamar a la funcion\n"); return 0; } ``` ```c= #include <stdio.h> void hello(void); int main(void) { printf("Antes de la llamar a la funcion\n"); hello(); printf("Despues de llamar a la funcion\n"); return 0; } void hello(void) { printf ("Hola Mundo!! \n"); return; } ``` Una función puede devolver cualquier tipo de variable: int, float, char, arreglo, puntero, estructura, etc. Variables Locales y Globales ```c= #include <stdio.h> void hello(void) { int i; for (i = 0; i < 2; i++) printf("You've invoked me – what fun!\n"); return; } int main(void) { int i; printf("We are about to invoke hello()!\n"); for (i = 0; i < 3; i++) hello(); printf("We returned from hello()!\n"); return 0; } ``` ```c= #include <stdio.h> int global; void fun(void) { int local; local = 2; global++; printf("fun: local=%d global=%d\n", local, global); global++; } int main(void) { int local; local = 1; global = 1; printf("main: local=%d global=%d\n", local, global); fun(); printf("main: local=%d global=%d\n", local, global); return 0; } ``` Adpatar el siguiente código utilizando funciones: ```c= #include <math.h> #include <stdio.h> float square(float param) { return param * param; } int main(void) { float a, b, a_sqr, b_sqr, c; printf("A?\n"); scanf("%f", &a); a_sqr = square(a); printf("B?\n"); scanf("%f", &b); b_sqr = square(b); c = sqrt(a_sqr + b_sqr); printf("The length of the hypotenuse is: %f\n", c); return 0; } ``` *Deasafio* Hacer una función que reciba 3 enteros y devuelva el mayor de ellos. *Desafio* Hacer una función que reciba dos númmeros: un real y un entero, de tal manera que se devuelva el número real multiplicado tantas veces indique el número entero. *Desafio* Hacer una función que reciba dos cadenas y las compare de tal manera que devulva los siguientes valores: - 0 si son iguales - 1 si la primera es mayor (alfabeticamente) que la segunda. - '1 si la segunda es mayor.