Declarar un prototipo de función en c. Creación de interfaces de biblioteca. Vea qué es un “Prototipo de Función” en otros diccionarios

Digamos que en algún punto de tu código hay una llamada función específica. Preguntémonos bajo qué condiciones el compilador no producirá un error al compilar esta sección de código. Hay una respuesta simple a esta pregunta. En algún lugar del mismo archivo en el que se realiza la llamada a la función, debe estar presente un prototipo o descripción de la función antes de la operación en la que se realiza la llamada. Además, los argumentos y el tipo de retorno en la llamada deben coincidir con los argumentos y el tipo de retorno en el prototipo y en la declaración de función.

Entonces, ¿qué es un prototipo de función? El prototipo se ve así:

// prototipo de función función nula (int arg1, double arg2); // al final de la definición siempre hay un punto y coma

Como puedes ver en el prototipo, el tipo de valor de retorno se indica en orden (en este ejemplo vacío), nombre de la función (en en este caso función) y una lista de parámetros entre paréntesis. La declaración del prototipo debe terminar con un punto y coma.

¿Para qué sirve un prototipo de función? El compilador utiliza el prototipo y la descripción de la función para realizar la llamada a la función. En el camino correcto. Para hacer esto, el compilador primero mira el nombre de la función que se llama y busca en el archivo un prototipo o descripción de esta función. Si se encuentra un prototipo o una descripción, se verifican los argumentos pasados ​​a la función en la llamada y el uso del valor de retorno.

¿Por qué exactamente se necesita un prototipo? ¿Por qué no podemos limitarnos a utilizar una descripción de función? El prototipo se hizo necesario después de que los estándares del lenguaje C cambiaran de tal manera que antes de llamar a una función en un archivo, es necesario describirla de alguna manera. El problema es que el nombre de la función tiene área global visibilidad (si su descripción está fuera de cualquier área local). Supongamos que la descripción de la función está en un archivo separado. archivo fuente. Supongamos también que necesitamos llamar a la misma función en varios otros archivos fuente. Si no hay un prototipo, entonces cada archivo fuente debe incluir Descripción completa funciones. El compilador interpretará esto como una anulación. Si utilizamos un prototipo, podemos incluir este prototipo en tantos archivos fuente como necesitemos.

Cómo utilizar mejor un prototipo de función. Es mejor incluir la descripción de la función en un archivo fuente separado. Después de esto, necesitas compilar este archivo y obtener un archivo objeto. El prototipo debe colocarse en archivo de cabecera e inclúyalo con la directiva #include en aquellos archivos fuente en los que la llamada a la función esté presente.

En lenguaje C, antes de la primera llamada a una función, debes decirle al programa el tipo de valor devuelto por la función, así como el número y tipos de sus argumentos. Mensaje similar llamado prototipo de función.

El prototipo de función se ve así

tipo<имя функции>(lista de parámetros)

Usar un prototipo también se llama declarar una función o simplemente declararla. El prototipo puede ser exactamente igual que el encabezado de la función, aunque al declarar una función, el compilador sólo necesita saber el nombre de la función, el número de argumentos y sus tipos, y el tipo de valor de retorno de la función. Por lo tanto, los nombres de los argumentos como nombres de parámetros formales no tienen significado y el compilador los ignora.

Por tanto, un prototipo de función puede ser uno de los siguientes:

int fun1(int x, int y, char* c); o int fun1(int, int, char*);

"Llamar a una función" es una expresión que pasa control y argumentos reales, si los hay, a una función. En una llamada de función, la "expresión" se evalúa para obtener la dirección de la función, y la "lista de expresiones" es una lista de expresiones separadas por comas. Los valores de estas expresiones son los argumentos reales pasados ​​a la función. Si una función no tiene argumentos, entonces la lista de expresiones puede estar vacía.

Pregunta 33

matrices es un grupo de elementos del mismo tipo (doble, flotante, int, etc.). De la declaración de la matriz, el compilador debe obtener información sobre el tipo de elementos de la matriz y su número. Una declaración de matriz tiene dos formatos:

descriptor de especificador de tipo [const - expresión];

descriptor de especificador de tipo;

El descriptor es el identificador de la matriz.

El especificador de tipo especifica el tipo de elementos de la matriz declarada. Los elementos de la matriz no pueden ser funciones o elementos vacíos.

Expresión constante en corchetes Especifica el número de elementos de la matriz. Al declarar una matriz, se puede omitir una expresión constante siguientes casos:

Cuando se declara, la matriz se inicializa,

La matriz se declara como formal. parámetro de función,

Pregunta 34

matrices de caracteres es un grupo de elementos del mismo tipo (char)

La sintaxis de la declaración es:

donde ID es el identificador de la matriz, N es la longitud de la matriz y se asignan N bytes en la memoria para almacenar la cadena.

Por ejemplo, para variable de carácter A ST se le asignan 10 bytes en memoria, lo que permite formar una cadena de 9 caracteres. Para tales cadenas, se aplican todas las reglas para representar y procesar matrices.

Un identificador de matriz es una constante de puntero cuyo valor es igual a la dirección del primer elemento de la matriz.

La inicialización es posible de dos maneras:

· inicialización carácter por carácter char st=("y","e","s","\0");

sin embargo, los 6 puestos restantes no serán cubiertos;

inicialización basada en constante de cadena char st="Sí";

en este caso, se colocarán 3 caracteres en la memoria asignada para la cadena y se agregará un cuarto: el carácter "\0".

La inicialización y declaración son posibles sin especificar la longitud. matriz de caracteres st=("y","e","s","\0");

en este caso se creará una matriz de cuatro elementos.

Pregunta 35

SI define sólo matrices unidimensionales, pero dado que un elemento de una matriz puede ser una matriz, también se pueden definir matrices multidimensionales. Están formalizados mediante una lista de expresiones constantes que siguen al identificador de matriz, con cada expresión constante encerrada entre sus propios corchetes.

Cada expresión constante entre corchetes especifica el número de elementos en esta dimensión matriz, de modo que una declaración de matriz bidimensional contiene dos expresiones constantes, una matriz tridimensional contiene tres, etc. Tenga en cuenta que en SI, el primer elemento de una matriz tiene un índice de 0.

doble b; /* vector de 10 elementos de tipo doble */

intw = ((2, 3, 4),

Pregunta 36

Puntero es una variable que contiene la dirección de la variable.

matriz bidimensional es una variable indexada que está definida por dos índices. Su primer índice muestra número de serie filas, y el segundo índice muestra el número de columna. A continuación, en la tabla, ve la designación de cada elemento de una matriz bidimensional (matriz).

a a a a
a a a a
a a a a

La cantidad de bytes de memoria necesarios para almacenar la matriz se calcula mediante la fórmula:
Número de bytes =<размер типа данных> * <количество строк> * <количество столбцов>
Por ejemplo, si la matriz contiene números enteros de 1 a 255, cada uno de los cuales, como se sabe, ocupa 1 byte de memoria, luego una matriz que consta de tres filas y cuatro columnas ocupa 12 bytes (1 byte * 3 filas * 4 columnas) de memoria. En la tabla de la izquierda verá que se asignan 12 celdas para una matriz de tamaño: 3 filas por 4 columnas. Cada celda representa convencionalmente un byte. Preste atención a la designación de los elementos de la matriz. Aquí: a- este es el nombre de la matriz, y luego el primer índice entre corchetes es el número de fila, el segundo índice entre corchetes es el número de columna.
Recuerde que en C matriz multidimensional denotado de la siguiente manera: tipo<имя массива;>[tamaño1][tamaño2]...[tamañoN].
Por lo tanto, una matriz unidimensional tendrá siguiente descripción: tipo<имя массива;>[tamaño]. Por ejemplo: en un. Esta matriz contiene 100 números enteros. En C, los índices se numeran comenzando desde cero. Entonces aquí los elementos tienen códigos: una, una, ..., una.
En la memoria de la computadora, la matriz está ubicada continuamente a lo largo de líneas: la matriz bidimensional mencionada anteriormente es una línea continua extendida en una línea: a, a, a, a, a, a, a, a, a, a, un, un.

Pregunta 36

Punteros en el lenguaje de programación C. Operaciones con punteros, aritmética de direcciones. Relación entre matrices y punteros.

operador unario & da la dirección del objeto, por lo que la instrucción

asigna a una variable pag dirección celular C(ellos dijeron eso pag puntos a C). Operador & Se aplica sólo a objetos ubicados en la memoria: variables y elementos de matriz. Su operando no puede ser una expresión, una constante o una variable de registro.

operador unario * hay un operador acceso indirecto. Aplicado a un puntero produce el objeto al que este puntero indica. pretendamos que X Y y tener tipo En t, A IP- puntero a En t. Las siguientes líneas están diseñadas específicamente para mostrar cómo se declaran los punteros y cómo se utilizan los operadores. & Y * .

int x = 1, y = 2, z;

int *ip; /* ip - puntero a int */

ip = /* ahora ip apunta a x */

y = *ip; /* y ahora es 1 */

*ip = 0; /* x ahora es 0 */

ip = /* ip ahora apunta a z */

anuncios X, y Y z ya estamos familiarizados. Declaración de puntero IP

Si pag hay un puntero a algún elemento de la matriz, entonces p++ aumenta pag para que apunte al siguiente elemento, y p+=i lo amplía para que apunte a i El décimo elemento después del señalado anteriormente. Estos y diseños similares son los más ejemplos simples aritmética de punteros, también llamada aritmética de direcciones.

En C existe una relación entre punteros y matrices, y esta relación es tan estrecha que es mejor considerar estas herramientas juntas. Cualquier acceso a un elemento de la matriz mediante una operación de indexación se puede realizar mediante un puntero. Opción con punteros en caso general Funciona más rápido, pero es bastante difícil de entender, especialmente para los no iniciados.

Anuncio

Define una matriz a tamaño 10, es decir, un bloque de 10 objetos consecutivos con nombres a, a, ..., a.

Registro ai] nos refiere a i-ésimo elemento de la matriz. Si Pensilvania hay un indicador de En t, es decir, declarado como

luego como resultado de la tarea

Pensilvania apuntará al elemento nulo a, en otras palabras, Pensilvania contendrá la dirección del elemento a.

Ahora la tarea

copiará el contenido a V X.

Si Pensilvania apunta a algún elemento de la matriz, entonces pa+1 por definición apunta al siguiente elemento, pa+i- en iº elemento después Pensilvania, a pa-i- en iº elemento antes Pensilvania. Así, si Pensilvania puntos a a, Eso

hay contenido a, a+yo- DIRECCIÓN ai], a *(pa+yo)- contenidos ai].

Pregunta 37

Opciones para describir matrices en el lenguaje de programación C. Argumentos de la función principal.

ent a; /* representado como una matriz

flotador b; /* vector de 10 elementos de tipo doble */

intw = ((2, 3, 4),

En el último ejemplo, se declara la matriz w. Las listas entre llaves corresponden a cadenas de matriz; si no hay llaves, la inicialización no se realizará correctamente.

El lenguaje C tiene dos argumentos integrados para la función principal: argc y argv.

Se parece a esto:

int principal(int argc, char *argv)

Argumento argc escribe int eger contiene el número de argumentos línea de comando.

argumento argv tipo char- puntero a una serie de cadenas. Cada elemento de la matriz apunta a argumentos de la línea de comando. Un parámetro está separado de otro por espacios.

argv- nombre completo programa en ejecución

argv: la primera línea escrita después del nombre del programa

argv: la segunda línea escrita después del nombre del programa

argv: la última línea escrita después del nombre del programa

argv-NULO

Pregunta 38

Especificaciones básicas para entrada/salida formateada (para las funciones printf y scanf) en la biblioteca stdio del lenguaje de programación C.

Símbolo Datos de entrada; tipo de argumento
d entero decimal: int *
i int: int*. El número entero puede ser octal (con 0 a la izquierda) o hexadecimal (con 0x o 0X a la izquierda)
oh entero octal (con o sin cero a la izquierda); En t *
tu entero decimal sin signo; entero sin firmar *
X entero hexadecimal (con o sin 0x o 0X a la izquierda); En t *
C símbolos; carácter *. Los siguientes caracteres de entrada (uno por defecto) se colocan en ubicación especificada. Se suprime la omisión normal de caracteres delimitadores; para leer el siguiente carácter que no sea el carácter delimitador, use %1s
s Cadena de caracteres (sin comillas); char * apunta a una matriz de caracteres lo suficientemente grande como para agregar la cadena y un carácter final "\0"
mi, f, sol número de coma flotante, posiblemente firmado; se requiere la presencia de un punto decimal o una parte exponencial, y posiblemente ambas juntas; flotar *
% el signo % en sí, no se realiza ninguna asignación
Símbolo Tipo de argumento; tipo de impresión
d, yo En t; entero decimal
oh entero sin firmar; octal sin firmar ( octal) entero (sin cero a la izquierda)
x, x entero sin firmar; entero hexadecimal sin signo (sin 0x o 0X a la izquierda), para 10...15 use abcdef o ABCDEF
tu entero sin firmar; entero decimal sin signo
C En t; carácter único
s carbón *; imprime caracteres hasta el carácter \0, o hasta un número especificado por la precisión
F doble; [-]m.dddddd, donde el número de dígitos d se especifica mediante la precisión (el valor predeterminado es 6 )
mi, mi doble; [-]m.ddddddde±xx o [-]m.ddddddE±xx, donde el número de dígitos d se especifica mediante la precisión (el valor predeterminado es 6 )
gramo, gramo doble; usa %e o %E si el orden es menor que -4 o mayor o igual a la precisión; de lo contrario usa %f. Los ceros finales y el punto decimal final no se imprimen
pag vacío *; puntero (la representación depende de la implementación)
% El argumento no se convierte; El signo % está impreso.

Pregunta 39

Funciones básicas utilizadas al trabajar con archivos de texto(abrir, cerrar, leer, escribir, etc.) en la biblioteca stdio del lenguaje de programación C.

Apelar a abrir el programa podría verse así:

fp = fopen(nombre, modo);

El primer argumento es una cadena que contiene el nombre del archivo. El segundo argumento contiene información sobre el modo. Esto también es una cadena: indica cómo el usuario pretende utilizar el archivo. Son posibles los siguientes modos: lectura ( leer- "r"), grabar ( escribir- "w") y añadiendo ( adjuntar- “a”), es decir escribir información hasta el final ya archivo existente. Algunos sistemas diferencian entre texto y archivos binarios; en el caso de este último, deberás agregar la letra “b” a la línea de modo ( binario- binario).

Lo siguiente que debemos saber es cómo leer un archivo o escribir en un archivo una vez abierto. Hay varias formas de hacer esto, la más sencilla es utilizar las funciones getc Y putc. Función getc devuelve el siguiente carácter del archivo; es necesario indicarle el puntero del archivo para que sepa de dónde obtener el símbolo.

int getc(ARCHIVO *fp);

Función getc devuelve el siguiente carácter de la secuencia apuntada *fp; en caso de agotamiento del archivo o error, devuelve EOF.

Función putc escribe un símbolo C archivar fp

int putc(int c, ARCHIVO *fp);

y devuelve el carácter escrito o EOF en caso de error

Al iniciar un programa en C Sistema operativo siempre abre tres archivos y les proporciona tres enlaces de archivos. Estos archivos son: entrada estándar, salida estándar y archivo de error estándar; sus punteros correspondientes se llaman entrada estándar, salida estándar Y stderr; se describen en . Generalmente entrada estándar correlacionado con el teclado, y salida estándar Y stderr- con una pantalla. Mediante el uso getc, putc, entrada estándar Y salida estándar funciones obtenerchar Y putchar ahora se puede definir de la siguiente manera:

#definir getchar() getc(stdin)

#definir putchar(c) putc((c), salida estándar)

La entrada/salida de archivos de formato se puede construir en funciones fscaf Y fprintf. son identicos escanear Y imprimirf la única diferencia es que su primer argumento es un puntero al archivo para el cual se está realizando la E/S, y el formato lo indica el segundo argumento.

int fscanf(ARCHIVO *fp, char *formato, ...)

int fprintf(ARCHIVO *fp, char *formato, ...)

Pregunta 40

Las funciones principales utilizadas cuando se trabaja con cadenas en la biblioteca string, stdio, stlib del lenguaje de programación C.

La biblioteca estándar stdio tiene un programa de entrada fgets, similar al programa obtener línea, que utilizamos en capítulos anteriores.

char *fgets(char *línea, int maxline, ARCHIVO *fp)

Función fgets está leyendo Proxima linea entrada (incluido el carácter nueva línea) desde el archivo fp a una matriz de caracteres línea y ella no puede leer más MAXLINE-1 caracteres. A la cadena reescrita se le añade el carácter "\0". Generalmente fgets devoluciones línea, y cuando el archivo está agotado o en caso de error - NULL. (Nuestro obtener línea devolvió la longitud de la cadena que luego usamos, y cero en caso del final del archivo).

Función de salida salidas escribe una línea (que puede no terminar con un carácter de nueva línea) en un archivo.

int fputs(char *línea, ARCHIVO *fp)

Esta función devuelve EOF si se produjo un error y valor no negativo de lo contrario.

Funciones de biblioteca obtiene Y pone similar a funciones fgets Y salidas. Se diferencian en que operan sólo archivos estándar entrada estándar Y salida estándar, y además, obtiene descarta el último carácter "\n", un pone lo agrega.

carácter *stracpy(s,ct) copia la linea Connecticut alinear s, incluido "\0"; devoluciones s
carácter *strncpy(s,ct,n) no más copias norte caracteres de la cadena Connecticut V s; devoluciones s. Completa el resultado con caracteres "\0" si hay caracteres en Connecticut menos norte
carácter *strcat(s,ct) atributos Connecticut A s; devoluciones s
carácter *strncat(s,ct,n) atributos no más norte caracteres Connecticut A s, completando s el carácter "\0"; devoluciones s
carácter strcmp(cs,st) compara cs Y Connecticut; devoluciones<0, если cs0 si cs>ct ( I.B.: en realidad la función devuelve int)
char strncmp(cs,ct) no se compara más norte caracteres cs Y Connecticut; devoluciones<0, если cs0 si cs>ct ( IB: int también debería regresar)
carácter *strchr(cs,c) C V cs
carácter *strrchr(cs,c) devuelve un puntero a la última aparición C V cs o, si no hay ninguno, NULL
tamaño_t strspn(cs,ct) cs, que consta de caracteres incluidos en la cadena Connecticut
tamaño_t strcspn(cs,ct) devuelve la longitud del segmento inicial cs, que consta de caracteres no incluidos en la cadena Connecticut
carácter *strpbrk(cs,ct) devuelve un puntero a cs al primer carácter que coincida con uno de los caracteres incluidos en Connecticut, o, si no hay ninguno, NULL
carácter *strstr(cs, ct) devuelve un puntero a la primera aparición Connecticut V cs o, si no hay ninguno, NULL
tamaño_t strlen(cs) longitud de retorno cs
char * strerror(n) devuelve un puntero a una cadena dependiente de la implementación correspondiente al número de error norte
carbón * strtok(s, ct) strtok mirando en s token limitado a personajes de Connecticut; más Descripción detallada para esta función ver más abajo

Funciones mem... están diseñados para manipular objetos como matrices de caracteres; su propósito es obtener interfaces para programas efectivos. En la siguiente tabla s Y t pertenecen al tipo vacío *; cs Y Connecticut- tipo constante nula *; norte- tipo tamaño_t; A C tiene un valor de tipo En t fundido a tipo carbonizarse.

doble strtod(const char *s, char **endp)

strtod s V doble *fin(Si final no NULL), si se desborda imprime HUGE_VAL con el signo adecuado, si el resultado es menor que lo que puede representar este tipo, se devuelve 0; en ambos casos en errno esta instalado RANGO.

strtol largo(const char *s, char **endp, int base)

strtol convierte los primeros caracteres de una cadena s V largo, ignorando los caracteres delimitadores iniciales; recuerda un puntero al final no convertido en *fin(Si final no nulo). Si base está en el rango de 2 a 36, ​​entonces la conversión se realiza bajo el supuesto de que la entrada es un número escrito en base base. Si base es igual a cero, entonces se considera que la base del número es 8, 10 o 16; un número que comienza con el dígito 0 se considera octal, mientras que un número que comienza con 0x o 0X se considera hexadecimal. Números del 10 al base-1 escrito con las letras iniciales del alfabeto latino en cualquier caso. Con una base de 16, puedes colocar 0x o 0X al principio del número. En caso de desbordamiento, la función devuelve LONG_MAX o LONG_MIN (según el signo), y en errno Se establece ERANGE.

strtoul largo sin firmar (const char *s, char **endp, int base)

strtoul funciona igual que strtol, con la única diferencia de que devuelve un resultado de tipo largo sin firmar, y en caso de desbordamiento - ULONG_MAX.

Gracias Grisha por las últimas 4 preguntas.


Información relacionada.


Si necesita llamar a una función antes de que esté definida en el archivo en cuestión, o la definición de la función está en un archivo fuente diferente, entonces la llamada a la función debe estar precedida por una declaración de esa función. La declaración de función (prototipo) tiene el siguiente formato:

[Especificador de clase de memoria] [Especificador de tipo] Nombre de función ([Lista de parámetros formales]) [, Lista de nombres de funciones];

A diferencia de una definición de función, en un prototipo, el encabezado va seguido inmediatamente de un punto y coma y no hay cuerpo de función. si varios diferentes funciones devuelven valores del mismo tipo y tienen las mismas listas de parámetros formales, entonces estas funciones se pueden declarar en un prototipo, especificando el nombre de una de las funciones como nombre de función, y todas las demás se pueden colocar en la Lista de nombres de funciones. , y cada función debe ir acompañada de una lista de parámetros formales. Las reglas para usar otros elementos de formato son las mismas que cuando se define una función. Al declarar una función, no es necesario especificar los nombres de los parámetros formales y, si se especifican, su alcance se extiende sólo hasta el final de la declaración.

Un prototipo es una declaración de función explícita que precede a la definición de la función. El tipo de retorno de una declaración de función debe coincidir con el tipo de retorno de la definición de función.

Si no se especifica un prototipo de función, pero se encuentra una llamada a función, entonces se construye un prototipo implícito a partir de un análisis de la forma de la llamada a función. El tipo de valor de retorno del prototipo creado es int, y la lista de tipos y número de parámetros de función se forma en función de los tipos y número. parámetros reales, utilizado en esta llamada.

Así, se debe especificar un prototipo de función en los siguientes casos:

1. La función devuelve un valor de tipo distinto de int.

2. Es necesario inicializar algún puntero a una función antes de definir esta función.

Disponibilidad en prototipo Lista llena Los tipos de argumentos de parámetros le permiten verificar si los tipos de parámetros reales al llamar a una función corresponden a los tipos de parámetros formales y, si es necesario, realizar las conversiones apropiadas.

En un prototipo, puede especificar que el número de parámetros de la función sea variable o que la función no tenga parámetros.

Si el prototipo se especifica con una clase de memoria estática, entonces la definición de función también debe tener una clase de memoria estática. Si no se especifica el especificador de clase de memoria, se asume la clase de memoria externa.

C++ no requiere que una definición de función preceda su llamada. Las definiciones de las funciones utilizadas pueden seguir a la definición de la función principal, antes de ella, o estar en otro archivo.

Una característica del estándar de lenguaje ANSI C es que para crear el lenguaje correcto codigo de maquina Antes de llamar a una función por primera vez, se debe informarle el tipo de retorno, así como el número y tipos de argumentos. Para ello, C utiliza el concepto de prototipo de función.

Sintaxis del prototipo de función:

tipo<имя функции>(lista de parámetros);

Usar un prototipo de función es una declaración de función. La mayoría de las veces, el prototipo de la función es exactamente el mismo que el título en la descripción de la función, aunque no siempre es así. Al declarar una función, es importante que el compilador conozca el nombre de la función, el número y tipo de parámetros y el tipo del valor de retorno. En este caso, los nombres de los parámetros formales de la función no desempeñan ningún papel y el compilador los ignora. Entonces un prototipo de función podría verse así

o así: int func(int a, float b, char* c);

o así: int func(int, float, char*);

Estos dos anuncios son absolutamente equivalentes.

si functsSi no tiene argumentos, entonces al declarar el prototipo de dicha función, debes escribir la palabra clave en lugar de argumentos.vacío.

Esto también debería aplicarse a la función main(). Su declaración debería verse así:

vacíometroes(void)o metroainorte(void).

Los prototipos de funciones estándar se encuentran en archivos de encabezado. Ejemplos de dichos archivos de encabezado son los archivos stdio.h, string.h. Además, los archivos de encabezado contienen definiciones individuales que utilizan las funciones.

Punteros de tipo void

La palabra clave void en los encabezados y prototipos de funciones significa que las funciones no toman ningún argumento ni devuelven valores.

Un puntero nulo es un puntero sin tipo:

El puntero ptr apunta a algún objeto de memoria de un tipo temporalmente indefinido.

El uso más común de punteros nulos es declarar parámetros de función cuando necesita crear una función que necesita manejar argumentos de diferentes tipos.

Ejemplo.

Suponga que necesita escribir una función que tome un número como argumento, lo divida entre dos y devuelva la respuesta en el argumento mismo. Como es necesario modificar el argumento, lo pasamos a la dirección. También queremos poder trabajar con cualquiera de los tipos de datos numéricos de C, por lo que definimos el argumento de la función como un puntero vacío:

mitad vacía (void *val);

Sin embargo, PAGAntes de realizar operaciones en un objeto utilizando un puntero, debe determinar su tipo. Esto se hace usando un tipo de conversión.

Sea pval un puntero de tipo void. Luego, la conversión de su tipo se realiza de la siguiente manera:

(tipo *) pag vale

tipo – el tipo de datos al que se convierte el puntero. Por ejemplo, para lanzar un puntero pval para escribir int escribimos lo siguiente: (int *)pval.

Para hacer referencia a un puntero pval para un valor int, utilice la siguiente expresión:

Por lo tanto, para utilizar un puntero, la función debe tener información sobre a qué tipo de valor apunta. Aquellos. necesitas decirle a la función el tipo de variable entre cuatro posibles: int, long, float, double.

La definición de la función se puede cambiar, por ejemplo, de la siguiente manera:

Mitad vacía (void *pval, tipo char);

Se llama declaración de función, que no contiene el cuerpo de la función, pero especifica el nombre de la función, la aridad, los tipos de argumentos y el tipo de datos de retorno. Mientras que una definición de función describe lo que hace una función, un prototipo de función puede considerarse como una descripción de su interfaz.

En el prototipo, los nombres de los argumentos son opcionales; sin embargo, el tipo debe especificarse junto con cualquier modificador (por ejemplo, si es un puntero o un argumento constante).

Ejemplo [ | ]

Como ejemplo, considere el siguiente prototipo de función:

int foo(int n);

Este prototipo declara una función llamada "foo" que toma un argumento "n" de tipo entero y devuelve un número entero. La definición de una función puede aparecer en cualquier parte de un programa, pero solo se requiere una declaración cuando se usa.

Uso [ | ]

Aviso del compilador[ | ]

Si una función no ha sido declarada previamente y su nombre aparece en una expresión inmediatamente seguida de un paréntesis de apertura, entonces se declara implícitamente como una función de retorno int y no se asume nada sobre sus argumentos. En este caso, el compilador no podrá realizar la verificación del tipo de argumento y de la aridad cuando se llame a la función con algunos argumentos. Este fuente potencial problemas. El siguiente código ilustra una situación en la que el comportamiento de una función declarada implícitamente no está definido.

#incluir /* * Al implementar este prototipo, el compilador generará un mensaje de error * en principal(). Si se omite, no aparecerá ningún mensaje de error.*/ int foo (int n ); /* Prototipo de función */ int principal (vacío) /* Llamar a una función */( printf( "%d \n ", foo ()); /* ERROR: ¡a foo le falta un argumento! */ devolver 0; ) int foo(int n) /* Función a llamar */(si (n == 0) devuelve 1; en caso contrario, devuelve n * foo (n - 1);)

La función "foo" espera un argumento de tipo entero que esté en la pila cuando se llama. Si se omite el prototipo, el compilador no puede manejarlo y "foo" completará la operación en algunos otros datos de la pila (probablemente el valor de una variable que no sea de la pila). Al incluir un prototipo de función, informa al compilador que la función "foo" toma un único argumento de tipo entero y permite que el compilador maneje este tipo de errores.




Arriba