Está en la página 1de 22

NDICE

6.1 Introduccin..... 1 6.2 Funciones estndar.... 2 6.3 Entrada y salida de datos.. 4 6.4 Funciones definidas por el usuario... 10 6.5 Pasaje de parmetros por valor... 12 6.6 Pasaje de parmetros por referencia.. 13 6.7 Punteros.15

INTRODUCCIN

FUNCIONES ESTANDAR
Una funcin en C es un segmento de cdigo independiente que realiza completamente una determinada tarea de un programa. Ventajas del uso de funciones: Permite modularizar programas. Ahorra memoria y tiempo de desarrollo Oculta datos y procesos.

Elementos de una funcin: Nombre: Identificador por el que la funcin es invocada Argumentos: Datos que se le pasan a la funcin para que pueda operar Valor de retorno: resultado de ejecutarse la funcin.

Una declaracin de una funcin es la especificacin tipos de los parmetros formal (en C) del prototipo. tipo del resultado int suma (int , int ); Una definicin de una funcin es la implementacin de datos internos y sentencias que la forman. int suma ( int a , int b) { t su a t t int resultado; res= a+b; return resultado; } En C una funcin debe de ser declarada antes de ser invocada. Las funciones estndar de C son las que forman parte de las libreras que se incluyen con el compilador. Estas funciones realizan sentencias que el lenguaje no es capaz de realizar. Como todas las funciones en C deben de ser declaradas antes de poder ser utilizadas (el compilador debe de conocer el prototipo durante el proceso de traduccin.)

Las principales libreras estndar de C son:

Librera <errno.h> <locale.h> <math.h> <stddef.h> <stdio.h> <stdlib.h> <string.h> <time.h>

Funcionalidad for testing error codes reported by library functions for adapting to different cultural conventions for computing common mathematical functions for defining several useful types and macros for performing input and output for performing a variety of operations for manipulating several kinds of strings for converting between various time and date formats

Para poder usar una funcin de una librera estndar hay que incluir el fichero que contiene la definicin de prototipos y tipos que maneje esa funcin. Por ejemplo: un programa que calcule el seno de un ngulo necesitara: #include <math.h> #define PI 3.1416 void main (void) { double angulo; // valor del angulo expresado en grados double anguloRadianes; // valor del angulo expresado en radianes double resultado; // aqu ira la lectura del nmero anguloRadianes = angulo * PI /180; resultado = sin (anguloRadianes); // aqu se mostrara el resultado } printf printf() es lo que se denomina una funcin estndar de C, es decir, una funcin que est incluida con el compilador. Para poder usarla dentro de un programa hay que decir en el mismo como es su forma: eso se hace incluyendo la lnea #include <stdio.h> al principio. De momento dejaremos esto as y lo explicaremos dentro de ms sobre printf.

Para poder trabajar o llamar a una funcin estndar hay que conocer que necesita y qu hace. De la funcin printf hay que saber: Su nombre cada vez que se coloca printf en un programa le estamos diciendo al compilador de C que queremos usar esta funcin. Lo que se quiere imprimir, que ir entre los parntesis En general, la expresin (nmeros o texto) que va entre los parntesis de una funcin se llaman parmetros de la funcin. Por ejemplo, si en matemticas se quiere calcular el valor de Frmula en MathML: Logaritmo de tres equis al cuadrado , el parmetro de la funcin logaritmo sera Frmula en MathML: Tres equis al cuadrado . En lenguaje C, algunas funciones necesitan que le demos datos para poder hacer su trabajo y otras no. Por ejemplo, printf necesita el texto que hay que mostrar por pantalla (el cual se entrecomilla), pero para la funcin principal main no es obligatorio. Qu hace y cmo funciona printf() escribe texto en la pantalla del computador. Los detalles de funcionamiento aparecen en el manual del compilador que se est usando. El manual nos dice, por ejemplo, que si colocamos el cdigo \n dentro del parmetro de printf(), se imprimir un salto de lnea. Un compilador suele tener decenas de funciones estndar, aunque su nmero exacto y los detalles concretos de funcionamiento de las funciones estndar de C dependen de cada compilador.

ENTRADA Y SALIDA DE DATOS


El lenguaje C (y consecuentemente tambin C++) dispone de una librera para entrada salida: Standard Input-Output Library que permite ejecutar operaciones bsicas de E/S. Las declaraciones requeridas por esta librera estn contenidas en el archivo de encabezado stdio.h, que debe inclurse con la directiva correspondiente:

#include <stdio.h> Este archivo define tres streams estndar: stdin, stdout y stderr, que utilizan entrada y salida basada en caracteres y son abiertas automticamente. Por defecto stdin y stderr estn direccionadas a la pantalla, y stdin al teclado. 2. E/S bsica en C Estas operaciones se hacen mediante las funciones getchar() y putchar(): int getchar() lee un carcter desde stdin int putchar(char c) escribe el carcter 'c' en stdout Se dispone tambin de otras funciones, tales como getline(), etc. 3. E/S formateada en C Las funciones printf() y scanf() permiten aplicar formato a los datos de E/S, como por ejemplo, cantidad de decimales, justificacin de texto, conversin a maysculas/minsculas, numeracin hexadecimal, etc. Ambas funciones toman al menos dos argumentos (pueden ser ms): 1. La cadena de formato 2. Los datos a enviar a la salida, en el caso de printf() o a recibir de la entrada, en el caso de scanf() La cadena de formato es un literal encerrado ente comillas dobles ( y ) precedida de un smbolo '%'. La tabla siguiente muestra especificadores frecuentemente utilizados: Especificador c i,d x,X Significado Un carcter (char) Nmero entero (int o double) Nmero hexadecimal (0-9 A-F)

Especificador s f m.n k

Significado Cadena de caracteres (char *) Nmero de punto flotante (float o double) M cifras enteras y n decimales Ajuste de texto a la izquierda Nmero de cifras de un nmero entero

La cadena de formato puede incluir literales y caracteres especiales tales como '\n' '\t' '\0' 4. Ejemplos printf() printf(%-1.3f\n, 3.1415927); 3.141 printf(IVA: 21,5%%\n); IVA: 21,5% 5. Ejemplos scanf() En esta funcin, el primer argumento es la cadena de formato, al igual que en printf(), y el segundo la direccin de las variables que recibirn los datos: char string[80]; scanf(``%s'',string); 6. 3. Entrada/salida con Streams en C++ 1. Definicin: un stream en C++ es un objeto mediante el cual un programa puede insertar o extraer datos utilizando los operadores de insercin << y de extraccin >> o funciones. Los datos pueden ser tipos fundamentales (int, char, double, etc.), o cadenas de caracteres. 2. Streams predefinidos Por defecto, la salida asignada a un programa es la pantalla, y en C++ est representada por el stream cout a la que se denomina salida estndar. Las definiciones necesarias para su uso estn contenidas en el archivo de encabezamiento iostream. Caracteres, nmeros y variables pueden insertarse en cout mediante el operador de insercin <<. Ejemplo: cout << Hola!; // muestra una cadena de texto en la pantalla cout << 120; // muestra un nmero en pantalla cout << x; // muestra el valor de la variable x en pantalla Nueva lnea Tabulacin Carcter nulo (fin de cadena)

El operador de insercin << puede concatenarse: cout << Nombre: << nom << Edad: << ed; Suponiendo que la variable nom contenga la cadena Carla y la variable ed contenga el entero 23, la salida en pantalla ser: Nombre: Carla Edad: 23 Para separar las lneas en pantalla pueden usarse dos mtodos: agregar \n o usar el manipulador endl: cout << Nombre: << nom << \n << Edad: << ed; o cout << Nombre: << nom << endl << Edad: << ed; En ambos casos la salida ser: Nombre: Carla Edad: 23 La entrada estndar de un programa C++ es el teclado, y est representado por el stream cin. El operador de extraccin >> permite obtener caracteres o nmeros desde el teclado: int temperatura; cin >> temperatura; Es importante recordar que cin slo procesa la entrada desde el teclado una vez que el usuario puls la tecla Enter. El tipo de la variable que recibe datos determina cmo se interpretan los datos ingresados por teclado. El operador de insercin puede concatenarse, por ejemplo: cin >> a; cin >> b; es equivalente a: cin >> a >> b; La librera iostream provee dos streams predefinidas ms: cerr, que es la salida estndar de errores y clog, la salida estndar de registro o logging.

3. Streams especiales: archivos C++ provee tres streams especficas para leer y escribir caracteres desde y hacia un archivo en disco: 1. ifstream para leer caracteres desde un archivo 2. ofstream para escribir caracteres en un archivo 3. fstream para leer y escribir caracteres en un archivo Estas clases derivan de istream y ostream, las clases bsicas de entrada/salida definidas en iostream, y estn especialmente diseadas para interactuar con archivos en almacenamiento no voltil (disco, pen drive, etc.). 4. Utilizacin Un ejemplo sencillo de uso de ofstream: #include <iostream> #include <fstream> using namespace std; int main () { ofstream myfile; myfile.open ("salida.txt"); myfile << "Escribiendo en archivos.\n"; myfile.close(); return 0; } Este programa crea (o abre, si existe) un archivo llamado salida.txt y escribe una cadena de texto en su interior. 5. Apertura de un archivo Para utilizar un objeto ifstream, ofstream o fstream debe llevarse a cabo la vinculacin del stream al archivo fsico mediante una operacin de apertura mediante la funcin open(), que toma dos argumentos: nombre del archivo y modo de apertura. El primer parmetro es una cadena de caracteres (const char *) terminada en '\0' y opcionalmente el segundo, que una constante que determinar el uso que pretendemos hacer del archivo segn la siguiente tabla: Modo ios::in Significado El archivo se abre para operaciones de lectura (slo extraccin de

caracteres) ios::out ios::binary ios::app ios::trunc El archivo se abre para operaciones de escritura (slo insercin de caracteres) El archivo se abre en modo binario (su contenido no es texto sino bytes) Las operaciones de insercin tienen lugar al final del archivo, esto es, preservando su contenido inicial Si el archivo abierto existe, se descarta la totalidad de datos que contiene al momento de la apertura

Los modos pueden combinarse utilizando el operador OR '|': ofstream arch; arch.open( datos.txt, ios::out | ios::app | ios::binary); En este caso, datos.txt se abre para escribir datos binarios, preservando su contenido actual. En todos los casos, la funcin is_open() permite verificar si un archivo est disponible para operar sobre el: if( arch.is_open(){ // se puede operar } else cout << Archivo cerrado; 6. Cierre de un archivo Para garantizar que las operaciones realizadas efectivamente se reflejen en el archivo en disco, cuando se termina de trabajar sobre l debe ejecutar una operacin de cierre mediante la funcin close(): arch.close(); 4. Manipuladores La librera estndar iostream provee un conjunto de funciones llamadas manipuladores que, utilizados en conjunto con los operadores << y >> permiten modificar el comportamiento de los streams. La tabla siguiente muestra algunas frecuentemente utilizadas: Manipulador endl ends flush skipws Propsito Nueva lnea (Enter) Inserta un carcter de fin de cadena (\0) Vaca el buffer de un stream Salta espacios y tabulaciones

uppercase

Transforma a maysculas

FUNCIONES DEFINIDAS POR EL USUARIO


Las funciones de usuario son, como su nombre indica, las que el propio usuario declara, de igual manera que declara procedimientos. Las funciones nacen con el propsito de ser subprogramas que siempre tienen que devolver algn valor. Las dos principales diferencias entre procedimientos y funciones son: Las funciones siempre devuelven un valor al programa que las invoc. Para llamar a un procedimiento se escribe su nombre en el cuerpo del programa, y si los necesita, se incluyen los parmetros entre parntesis. Para invocar una funcin es necesario hacerlo en una expresin. Las funciones de usuario vienen definidas por un nombre, seguidas de dos parntesis () entre los que puede haber o no argumentos. Los argumentos son valores que se le pasan a la funcin cuando se llama. Un ejemplo de una funcin sin argumentos: #include <stdio.h> main () { printf (\nEste mensaje lo muestra la funcin main()); MiFuncion (); } /* Definicin de la funcin MiFuncion() */ MiFuncion () { printf (\nEste otro lo muestra MiFuncion()); } En este ejemplo se utiliza la funcin MiFuncion() para mostrar en pantalla una frase. Como se ve, MiFuncion() se invoca igual que printf() o scanf(), es decir, simplemente se escribe el nombre de la funcin y los parntesis. La definicin de MiFuncion() tiene el mismo aspecto que main(): el nombre de la funcin con los parntesis y, seguidamente, el cuerpo de la funcin encerrado entre llaves. Un ejemplo de una funcin con argumentos. El programa visualiza el cuadrado de un nmero entero por medio de una funcin que recibe dicho nmero como argumento.

10

#include <stdio.h> main () { int num; printf (\nTeclee un nmero entero: ); scanf (%d, &num); cuadrado (num); } /* Definicin de la funcin cuadrado() */ cuadrado (int x) { printf (\nEl cuadrado de %d es %d\n, x, x * x); } Es la declaracin de la funcin cuadrado(). Dentro de los parntesis se pone la variable que recibir el valor pasado a cuadrado() y de qu tipo es. As, si se teclea el valor 6, se almacena en num y al hacer la llamada cuadrado (num), la variable num se copia en la variable x, que es con la que trabaja internamente la funcin cuadrado(). Es importante mantener claros dos trminos: 1. El trmino Argumento se refiere a la variable usada al llamar la funcin. 2. El trmino Parmetro Formal se refiere a la variable de una funcin que recibe el valor de los argumentos. Tambin es importante tener claro que la copia de variables se hace slo en una direccin: del argumento al parmetro formal. Cualquier modificacin del parmetro formal realizado dentro de la funcin no tiene ninguna influencia en el argumento. Hay que tener en cuenta es que el tipo de argumento que se utiliza para llamar a una funcin debe ser el mismo que el del parmetro formal que recibe el valor. As, no debe llamarse a la funcin cuadrado con un argumento de tipo float. Un ejemplo que utiliza una funcin que devuelve un valor. El siguiente programa lee dos nmeros enteros del teclado y muestra su producto en pantalla. Para el clculo se usa una funcin que recibe los dos nmeros y devuelve el producto de ambos. #include <stdio.h> main () {

11

int a, b, producto; printf (\nTeclee dos nmeros enteros: ); scanf (%d %d, &a, &b); producto = multiplica (a, b); printf (\nEl resultado es %d, producto); } /* Definicin de la funcin multiplica() */ multiplica (int x, int y) { return (x * y); }

PASAJE DE PARMETROS POR VALOR


En C++ el paso por valor significa que al compilar la funcin y el cdigo que llama a la funcin, sta recibe una copia de los valores de los parmetros que se le pasan como argumentos. Las variables reales no se pasan a la funcin, slo copias de su valor. ste es el pasaje referente a funciones. Al realizar la definicin de la funcin colocamos los parmetros que sta recibe especificando el tipo de dato de los mismos. Luego, cuando hacemos el llamado y especificamos los argumentos, estos se evalan y se le pasa a la funcin una copia de los mismos. A esto es lo que llamamos paso por valor ya que la funcin trabajar con los valores de esas copias. Si pasramos variables como argumento, stas no se modificaran por este sistema de copias. Veamos esto con un ejemplo simple en que tenemos la siguiente funcin void que intercambia los valores de dos enteros x e y:

Declaramos dos variables de tipo int en el main, mostramos sus valores, llamamos a la funcin y volvemos a mostrarlos de la siguiente manera:

12

Y veramos en pantalla:

Donde vemos que, en efecto no se modificaron los valores. Pero agreguemos un printf al final de la funcin para ver si se haban modificado o no los valores:

Y obtenemos:

Donde vemos que, en efecto se modificaron los valores de x e y dentro de la funcin pero que no se modificaron las variables originales ya que al hacer el pasaje por valor se trabaja con la copia de las mismas.

13

PASAJE DE PARMETROS POR REFERENCIA


Cuando una funcin debe modificar el valor de la variable pasada como parmetro y que esta modificacin retorne a la funcin llamadora, se debe pasar el parmetro por referencia. En este mtodo, el compilador no pasa una copia del valor del argumento; en su lugar, pasa una referencia, que indica a la funcin dnde existe la variable en memoria. En el pasaje por referencia se pasa a la funcin las direcciones de memoria de las variables en cuestin en lugar de su valor. A diferencia del paso por valor, aqu no se realizan copias de las variables sino que se trabaja sobre la direccin de memoria que pasamos, lo que nos permite modificar el valor de la variable en cuestin. Veamos esto con el mismo ejemplo que usamos antes, pero usando punteros:

Luego hacemos el llamado a la funcin de la misma manera, pero pasando las direcciones de memoria de x e y:

Obteniendo lo siguiente al compilar el programa y ejecutarlo:

Donde vemos que esta vez s se modific el contenido de las variables en cuestin.

14

PUNTEROS
Cmo se organiza la memoria asociada a un programa? Como una coleccin de posiciones de memoria consecutivas. En ellas se almacenan los distintos tipos de datos, que ocupan, por ejemplo: 1 char = 1 byte 1 int = 2 bytes 1 float = 4 bytes Un puntero no es ms que una variable esttica cuyo contenido es una direccin de memoria. Los punteros, por lo tanto, guardan en dos o cuatro posiciones de memoria, la direccin de un conjunto de celdas.

p donde: pc es un puntero a carcter char *pc; c es una variable de tipo carcter char c;

Inicialmente un puntero no apunta a ningn sitio. En C el valor NULL se reserva para indicar que el puntero est vaco (equivalente al nil de la teora). Operadores asociados a punteros &: me da la direccin de un objeto en la memoria. Slo sirve para posiciones de memoria (puede apuntar a variables o a vectores, pero no a constantes o expresiones). Ejemplo: /* prog1.c*/ pc = &c; printf (\nNo tiene lo mismo %c que %d, c, pc); /* Ojo, %d para pc*/ *: me da el contenido de una posicin de memoria (generalmente almacenada en un puntero). Se le llama tambin operador indireccin. Por lo tanto es equivalente: printf (\nTiene lo mismo %d que %d, &c, pc); /* Direcciones */ printf (\nTiene lo mismo %c que %c, c, *pc); /* Caracteres */
15

Un puntero siempre est asociado a objetos de un tipo slo puede apuntar a objetos (variables o vectores) de ese tipo. int *ip; /* Slo puede apuntar a variables enteras */ char *c; /* Slo puede apuntar a variables carcter */ double *dp, /* dp slo puede apuntar a variables reales */ atof (char *); /* atof es una funcin que devuelve un real dada una cadena que se le pasa como puntero a carcter*/ Los operadores * y & son unarios y tienen ms prioridad a la hora de evaluarlos que los operadores binarios. /* prog2.c */ int y, *ip; y = 12; printf (\nValor de y %d, de ip %d, y, ip); /*sin asignar ip */ ip = &y; *ip = *ip + 10; printf (\nValor de y %d, de *ip %d y de ip %d, y, *ip, ip); y = *ip + 10; printf (\nValor de y %d, de *ip %d, y, *ip); *ip += 1; printf (\nValor de y %d, de *ip %d, y, *ip); Es necesario utilizar parntesis cuando aparecen en la misma expresin que otros operadores unarios como ++ o --, ya que en ese caso se evaluaran de izquierda a derecha. ++*ip; (*ip)++; Dado que los punteros son variables, tambin pueden usarse como asignaciones entre direcciones. As: int *ip, *iq; iq = ip; /* Indica que iq apunta a donde apunte el puntero ip. */ 2 Los punteros y los argumentos a funciones Recordemos la equivalencia: Cdigo Algortmico parmetro dato Equivalente C paso por valor Ejemplo en C int scanf (%d, &entero)

16

parmetro resultado parmetro dato-resultado

paso por referencia/ valor int scanf (%d, &entero) devuelto por una funcin paso por referencia int scanf (%d, &entero)

En C, por defecto, todos los parmetros a las funciones se pasan por valor (la funcin recibe una copia del parmetro, que no se ve modificado por los cambios que la copia sufra dentro de la funcin). Ejemplo: Intercambio de dos valores {VERSION ERRONEA} intercambia (int a, int b) { int tmp; tmp = a; a = b; b = tmp } {VERSION CORRECTA} intercambia (int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp }

Para que un parmetro de una funcin pueda ser modificado, ha de pasarse por referencia, y en C eso slo es posible pasando la direccin de la variable en lugar de la propia variable. Si se pasa la direccin de una variable, la funcin puede modificar el contenido de esa posicin (no as la propia direccin, que es una copia). 3 Punteros y vectores En C los punteros y los vectores estn fuertemente relacionados, hasta el punto de que el nombre de un vector es en s mismo un puntero a la primera (0-sima) posicin del vector. Todas las operaciones que utilizan vectores e ndices pueden realizarse mediante punteros. int v[10]; 1 v[0] 3 v[1] 5 v[2] 7 v[3] 9 v[4] 11 v[5] 13 v[6] 15 v[7] 17 v[8] 19 v[9]

v: designa 10 posiciones consecutivas de memoria donde se pueden almacenar enteros. int *ip; Designa un puntero a entero, por lo tanto puede acceder a una posicin de memoria. Sin embargo, como se ha dicho antes v tambin puede considerarse

17

como un puntero a entero, de tal forma que las siguientes expresiones son equivalentes: ip = &v[0] x = *ip; *(v + 1) v+I 4 Aritmtica de punteros El compilador C es capaz de adivinar cul es el tamao de una variable de tipo puntero y realiza los incrementos/decrementos de los punteros de la forma adecuada. As: int v[10], *p; p = v; /* p Apunta a la posicin inicial del vector*/ /* p + 0 Apunta a la posicin inicial del vector*/ /* p + 1 Apunta a la segunda posicin del vector*/ /* p + i Apunta a la posicin i+1 del vector*/ p = &v[9]; /* p apunta ahora a la ltima posicin (dcima) del vector */ /* p - 1 Apunta a la novena posicin del vector*/ /* p - i Se refiere a la posicin 9 - i en v*/ Ejemplo de recorrido de un vector utilizando ndices y punteros. /* prog3.c*/ main(){ int v[10]; int i, *p; for (i=0; i < 10; i++) v[i] = i; for (i=0; i < 10; i++) printf ("\n%d", v[i]); p = v; for (i=0; i < 10; i++) printf ("\n%d", *p++); /* Tras cada p++ el puntero seala a la siguiente posicin en v */ } C realiza las mismas operaciones con independencia del tipo de la variable. De esta forma, si tenemos dos variables que son punteros: int *ip, vi[10]; /* Necesita dos posiciones para representar un entero */ ip = v x = v[0]; v[1] &v[i]

18

char *cp, vc[10]; /* Necesita una posicin para representar un carcter */ ip = &vi[0]; cp = &vc[0]; Las expresiones: ip + 1, ip++ Apunta al siguiente elemento (dos posiciones): vi[1] cp + 1, cp++ Apunta al siguiente elemento (una posicin): vc[1] Diferencia entre puntero y nombre de vector: Mientras que un puntero es una variable y puede intervenir en asignaciones o incrementos, el nombre del vector no es una variable, por lo tanto, no pueden realizarse operaciones del tipo: int v[10], *a; v = a; v++; Dado que el nombre del vector es un puntero, puede utilizarse para pasar un vector como parmetro de una funcin (lo que permite modificar el contenido de esas posiciones de memoria adyacentes, o lo que es lo mismo, los elementos del vector). char palabra[10]; scanf (%s, palabra); /* Modifica las posiciones de memoria */ sort (palabra, 0, strlen(palabra)); /* sort va a modificar el contenido del vector, por lo tanto se pasar la direccin del primer elemento = palabra = &palabra[0]. strlen es una funcin de la librera estndar, cuyo macro es: (int strlen (char *)) La funcin nos devuelve la longitud de un vector de caracteres */ Recordatorio: Los vectores de caracteres terminan en el carcter \0. Ejemplo 1: Realizar una funcin que sea equivalente a strlen. int longitud (char *) char cadena[20]; gets(cadena); printf (\nLa longitud de la cadena %s es %d, cadena, longitud(cadena)); Ejemplo 2: Realizar una funcin equivalente que permita realizar a := b, cuando ambas son cadenas. copia (char *, char *) char cadena[20], *copiada;

19

printf (\nDame la primera cadena); gets (cadena); copia (cadena, copiada); printf (\nLa segunda cadena es %s, copiada); Solucin a 1): main(){ char cadena[20]; int longitud(); printf ("\nDame una cadena (maximo 20): "); gets(cadena); printf ("\nLa cadena %s mide %d ", cadena, longitud(cadena)); } int longitud(char *s){ int l; l = 0; while (*s++ != '\0') l++; return l; } Solucin a 2): main(){ char uno[20], dos[20]; printf ("\nDame una cadena:"); gets(uno); copia(uno, dos); printf ("\nLa copia de %s\n es %s\n", uno, dos); } copia (char *s, char *p) { while (*s) *p++ = *s++; *p = '\0'; }

20

También podría gustarte