Funciones
## Objetivos de Aprendizaje
- Definir y llamar funciones
- Comprender parámetros y valores de retorno
- Dominar declaraciones de funciones
- Aprender recursión
## Definir Funciones
### Estructura Básica
```c
#include
void greet(void) {
printf("Hello!\n");
}
int main(void) {
greet();
return 0;
}
```
### Función con Tipo de Retorno
```c
int add(int a, int b) {
return a + b;
}
```
### Llamar Funciones
```c
#include
int add(int a, int b) {
return a + b;
}
int main(void) {
int sum = add(5, 3);
printf("%d\n", sum);
return 0;
}
```
## Parámetros y Argumentos
### Pasar Argumentos
```c
void printName(const char *name) {
printf("Name: %s\n", name);
}
int main(void) {
printName("Alice");
return 0;
}
```
### Múltiples Parámetros
```c
int calculateArea(int width, int height) {
return width * height;
}
int main(void) {
int area = calculateArea(5, 10);
printf("%d\n", area);
return 0;
}
```
### El Orden de Parámetros Importa
```c
// Orden correcto
int result = calculate(10, 5); // 10 - 5 = 5
int calculate(int a, int b) {
return a - b;
}
```
## Valores de Retorno
### void (Sin Retorno)
```c
void printHello(void) {
printf("Hello\n");
}
```
### Retornar Temprano
```c
char getGrade(int score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
return 'F';
}
```
### Múltiples Retornos (Cláusulas de Guardia)
```c
int validate(int age, const char *name) {
if (age < 0) return 0;
if (name == NULL) return 0;
return 1;
}
```
## Declaraciones de Funciones
### Prototipo
```c
// Declaración (prototipo)
int add(int a, int b);
int main(void) {
int sum = add(5, 3);
return 0;
}
// Definición
int add(int a, int b) {
return a + b;
}
```
### Archivo de Encabezado (math_utils.h)
```c
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
#endif
```
### Implementación (math_utils.c)
```c
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
if (b == 0) return 0;
return a / b;
}
```
## Paso por Valor
### Primitivos (Paso por Valor)
```c
void doubleIt(int x) {
x = x * 2; // Solo afecta la copia local
}
int main(void) {
int num = 5;
doubleIt(num);
printf("%d\n", num); // Todavía 5
return 0;
}
```
### Para Modificar, Usar Punteros
```c
void doubleIt(int *x) {
*x = *x * 2; // Modifica el original
}
int main(void) {
int num = 5;
doubleIt(&num);
printf("%d\n", num); // 10
return 0;
}
```
## Arreglos como Parámetros
### El Arreglo se Convierte en Puntero
```c
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main(void) {
int nums[] = {1, 2, 3, 4, 5};
printArray(nums, 5); // El nombre del arreglo es puntero
return 0;
}
```
### Con Sintaxis de Punteros
```c
void printArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]); // o *(arr + i)
}
printf("\n");
}
```
### Prevenir Modificación
```c
int sum(const int *arr, int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i]; // Puede leer, no puede modificar
}
return total;
}
```
## Funciones Estáticas
### Solo Alcance de Archivo
```c
static int helper(int x) {
return x * 2;
}
int publicFunction(int x) {
return helper(x); // Puede llamar a función estática
}
```
- Las funciones `static` solo son visibles dentro del archivo
- Se usan para funciones auxiliares que no se exportan
## Recursión
### Función que Se Llama a Sí Misma
```c
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
```
Secuencia de llamadas para `factorial(5)`:
```text
factorial(5) = 5 * factorial(4)
factorial(4) = 4 * factorial(3)
factorial(3) = 3 * factorial(2)
factorial(2) = 2 * factorial(1)
factorial(1) = 1
Resultado: 5 * 4 * 3 * 2 * 1 = 120
```
### Alternativa Iterativa
```c
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
```
### Fibonacci
```c
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
```
### Recursión de Cola
```c
int factorialTail(int n, int accumulator) {
if (n <= 1) return accumulator;
return factorialTail(n - 1, n * accumulator);
}
int factorial(int n) {
return factorialTail(n, 1);
}
```
## Punteros a Funciones
### Declaración
```c
int (*funcPtr)(int, int); // Puntero a función que retorna int
```
### Uso
```c
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main(void) {
int (*operation)(int, int);
operation = add;
printf("%d\n", operation(5, 3)); // 8
operation = multiply;
printf("%d\n", operation(5, 3)); // 15
return 0;
}
```
### Patrón de Callback
```c
void apply(int *arr, int size, int (*func)(int)) {
for (int i = 0; i < size; i++) {
arr[i] = func(arr[i]);
}
}
int square(int x) { return x * x; }
int main(void) {
int nums[] = {1, 2, 3, 4, 5};
apply(nums, 5, square);
// nums ahora es {1, 4, 9, 16, 25}
return 0;
}
```
## Argumentos Variables (varargs)
### stdarg.h
```c
#include
#include
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}
va_end(args);
return total;
}
int main(void) {
printf("%d\n", sum(3, 1, 2, 3)); // 6
printf("%d\n", sum(5, 1, 2, 3, 4, 5)); // 15
return 0;
}
```
## Resumen
- Funciones: `tipo_retorno nombre(parámetros) { }`
- Los prototipos de funciones declaran antes de usar
- Paso por valor para primitivos
- Usar punteros para modificar argumentos
- Los arreglos se convierten en punteros cuando se pasan
- Las funciones `static` son locales al archivo
- Recursión: asegurar que exista caso base
- `varargs` para argumentos variables
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →