mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 17:41:41 +00:00
Changed c-es to utf8
This commit is contained in:
parent
aef1608362
commit
c10f6a6888
@ -4,23 +4,23 @@ filename: learnc.c
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Adam Bard", "http://adambard.com/"]
|
- ["Adam Bard", "http://adambard.com/"]
|
||||||
translators:
|
translators:
|
||||||
- ["Francisco García", "http://flaskbreaker.tumblr.com/"]
|
- ["Francisco García", "http://flaskbreaker.tumblr.com/"]
|
||||||
lang: es-es
|
lang: es-es
|
||||||
---
|
---
|
||||||
|
|
||||||
¡Ah!, C. Aun hoy en día sigue siendo el lenguaje por excelencia de la
|
¡Ah!, C. Aun hoy en día sigue siendo el lenguaje por excelencia de la
|
||||||
computación moderna de alto rendimiento.
|
computación moderna de alto rendimiento.
|
||||||
|
|
||||||
C es el lenguaje de más bajo nivel que la mayoría de los programadores
|
C es el lenguaje de más bajo nivel que la mayoría de los programadores
|
||||||
llegarán a usar, pero lo compensa de sobra con pura velocidad. Solo
|
llegarán a usar, pero lo compensa de sobra con pura velocidad. Solo
|
||||||
ten en cuenta el manejo manual de memoria y te llevará tan lejos como
|
ten en cuenta el manejo manual de memoria y te llevará tan lejos como
|
||||||
necesites.
|
necesites.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Los comentarios de una sola línea comienzan con //
|
// Los comentarios de una sola línea comienzan con //
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Los comentarios multilínea tienen este aspecto.
|
Los comentarios multilínea tienen este aspecto.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Importa cabeceras con #include
|
// Importa cabeceras con #include
|
||||||
@ -33,12 +33,12 @@ Los comentarios multil
|
|||||||
void function_1();
|
void function_1();
|
||||||
void function_2();
|
void function_2();
|
||||||
|
|
||||||
// El punto de entrada de tu programa es una función llamada main con
|
// El punto de entrada de tu programa es una función llamada main con
|
||||||
// retorno de tipo entero (integer).
|
// retorno de tipo entero (integer).
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
// Muestra la salida usando printf, para el "formato print"
|
// Muestra la salida usando printf, para el "formato print"
|
||||||
// %d es un entero, \n es una nueva línea
|
// %d es un entero, \n es una nueva línea
|
||||||
printf("%d\n", 0); // => Muestra 0
|
printf("%d\n", 0); // => Muestra 0
|
||||||
// Todas las sentencias deben terminar con un punto y coma.
|
// Todas las sentencias deben terminar con un punto y coma.
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ printf("%d\n", 0); // => Muestra 0
|
|||||||
// Tipos
|
// Tipos
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
// Tienes que declarar una variable antes de usarla. La declaración de una
|
// Tienes que declarar una variable antes de usarla. La declaración de una
|
||||||
// variable necesites que especifiques su tipo; el tipo de una variable
|
// variable necesites que especifiques su tipo; el tipo de una variable
|
||||||
// determina su tamaño en bytes.
|
// determina su tamaño en bytes.
|
||||||
|
|
||||||
// 'ints' (enteros) son normalmente de 4 bytes
|
// 'ints' (enteros) son normalmente de 4 bytes
|
||||||
int x_int = 0;
|
int x_int = 0;
|
||||||
@ -65,53 +65,53 @@ char y_char = 'y'; // Los caracteres literales se entrecomillan con ''
|
|||||||
long x_long = 0;
|
long x_long = 0;
|
||||||
long long x_long_long = 0;
|
long long x_long_long = 0;
|
||||||
|
|
||||||
// 'floats' son normalmente números de coma flotante de 32 bits
|
// 'floats' son normalmente números de coma flotante de 32 bits
|
||||||
float x_float = 0.0;
|
float x_float = 0.0;
|
||||||
|
|
||||||
// 'doubles' son normalmente números de coma flotante de 64 bits
|
// 'doubles' son normalmente números de coma flotante de 64 bits
|
||||||
double x_double = 0.0;
|
double x_double = 0.0;
|
||||||
|
|
||||||
// Todos los tipos enteros pueden ser 'unsigned'. Esto significa que no
|
// Todos los tipos enteros pueden ser 'unsigned'. Esto significa que no
|
||||||
// pueden ser negativos, pero el valor máximo de una variable 'unsigned'
|
// pueden ser negativos, pero el valor máximo de una variable 'unsigned'
|
||||||
// es mayor que el de una no 'unsigned' del mismo tamaño.
|
// es mayor que el de una no 'unsigned' del mismo tamaño.
|
||||||
unsigned char ux_char;
|
unsigned char ux_char;
|
||||||
unsigned short ux_short;
|
unsigned short ux_short;
|
||||||
unsigned int ux_int;
|
unsigned int ux_int;
|
||||||
unsigned long long ux_long_long;
|
unsigned long long ux_long_long;
|
||||||
|
|
||||||
// Todos menos 'char', que es siempre de 1 byte, varían el tamaño
|
// Todos menos 'char', que es siempre de 1 byte, varían el tamaño
|
||||||
// dependiendo de tu máquina. sizeof(T) te dice el tamaño de una variable
|
// dependiendo de tu máquina. sizeof(T) te dice el tamaño de una variable
|
||||||
// de tipo T en bytes por lo que podemos expresar el tamaño de estos tipos
|
// de tipo T en bytes por lo que podemos expresar el tamaño de estos tipos
|
||||||
// portatilmente.
|
// portatilmente.
|
||||||
// Por ejemplo,
|
// Por ejemplo,
|
||||||
printf("%lu\n", sizeof(int)); // => 4 (en máquinas con 'words' de 4 bytes)
|
printf("%lu\n", sizeof(int)); // => 4 (en máquinas con 'words' de 4 bytes)
|
||||||
|
|
||||||
// Los arrays deben ser inicializados con un tamaño concreto.
|
// Los arrays deben ser inicializados con un tamaño concreto.
|
||||||
char my_char_array[20]; // Este array ocupa 1 * 20 = 20 bytes
|
char my_char_array[20]; // Este array ocupa 1 * 20 = 20 bytes
|
||||||
int my_int_array[20]; // Este array ocupa 4 * 20 = 80 bytes
|
int my_int_array[20]; // Este array ocupa 4 * 20 = 80 bytes
|
||||||
// (suponiendo que tenemos 'words' de 4-byte)
|
// (suponiendo que tenemos 'words' de 4-byte)
|
||||||
|
|
||||||
|
|
||||||
// Puedes inicializar un array a 0 así:
|
// Puedes inicializar un array a 0 así:
|
||||||
char my_array[20] = {0};
|
char my_array[20] = {0};
|
||||||
|
|
||||||
// Indexar un array es como en otros lenguajes -o, más bien, otros
|
// Indexar un array es como en otros lenguajes -o, más bien, otros
|
||||||
// lenguajes son como C-
|
// lenguajes son como C-
|
||||||
my_array[0]; // => 0
|
my_array[0]; // => 0
|
||||||
|
|
||||||
// Los arrays varían; ¡son sólo memoria!
|
// Los arrays varían; ¡son sólo memoria!
|
||||||
my_array[1] = 2;
|
my_array[1] = 2;
|
||||||
printf("%d\n", my_array[1]); // => 2
|
printf("%d\n", my_array[1]); // => 2
|
||||||
|
|
||||||
// Las cadenas (strings) son sólo arrays de 'chars' (caracteres)
|
// Las cadenas (strings) son sólo arrays de 'chars' (caracteres)
|
||||||
// terminados en un byte NUL (0x00), representado en las cadenas como el carácter especial '\0'.
|
// terminados en un byte NUL (0x00), representado en las cadenas como el carácter especial '\0'.
|
||||||
// (No tenemos porqué añadir el byte nulo en cadenas literales; el
|
// (No tenemos porqué añadir el byte nulo en cadenas literales; el
|
||||||
// compilador lo añade al final por nosotros.)
|
// compilador lo añade al final por nosotros.)
|
||||||
char a_string[20] = "Esto es una cadena";
|
char a_string[20] = "Esto es una cadena";
|
||||||
printf("%s\n", a_string); // %s se sutituye por una cadena.
|
printf("%s\n", a_string); // %s se sutituye por una cadena.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Te habrás dado cuenta de que a_string es solo de 18 caracteres.
|
Te habrás dado cuenta de que a_string es solo de 18 caracteres.
|
||||||
El 'char' #19 es el byte nulo.
|
El 'char' #19 es el byte nulo.
|
||||||
El 'char' #20 es de valor indefinido.
|
El 'char' #20 es de valor indefinido.
|
||||||
*/
|
*/
|
||||||
@ -122,22 +122,22 @@ printf("%d\n", a_string[18]); // => 0
|
|||||||
// Operadores
|
// Operadores
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
int i1 = 1, i2 = 2; // Forma corta de declaración múltiple
|
int i1 = 1, i2 = 2; // Forma corta de declaración múltiple
|
||||||
float f1 = 1.0, f2 = 2.0;
|
float f1 = 1.0, f2 = 2.0;
|
||||||
|
|
||||||
// La aritmética es sencilla
|
// La aritmética es sencilla
|
||||||
i1 + i2; // => 3
|
i1 + i2; // => 3
|
||||||
i2 - i1; // => 1
|
i2 - i1; // => 1
|
||||||
i2 * i1; // => 2
|
i2 * i1; // => 2
|
||||||
i1 / i2; // => 0 (0.5, pero es truncado tras el 0)
|
i1 / i2; // => 0 (0.5, pero es truncado tras el 0)
|
||||||
|
|
||||||
f1 / f2; // => 0.5, más o menos épsilon
|
f1 / f2; // => 0.5, más o menos épsilon
|
||||||
// Módulo está también
|
// Módulo está también
|
||||||
11 % 3; // => 2
|
11 % 3; // => 2
|
||||||
|
|
||||||
// Los operadores de comparación te resultaran familiares, pero no hay
|
// Los operadores de comparación te resultaran familiares, pero no hay
|
||||||
// booleanos en C. Usamos enteros (ints) en su lugar. 0 es falso,
|
// booleanos en C. Usamos enteros (ints) en su lugar. 0 es falso,
|
||||||
// cualquier otra cosa es verdadero. (Los operadores de comparación
|
// cualquier otra cosa es verdadero. (Los operadores de comparación
|
||||||
// siempre devuelven 0 o 1)
|
// siempre devuelven 0 o 1)
|
||||||
3 == 2; // => 0 (Falso)
|
3 == 2; // => 0 (Falso)
|
||||||
3 != 2; // => 1 (Verdadero)
|
3 != 2; // => 1 (Verdadero)
|
||||||
@ -146,16 +146,16 @@ f1 / f2; // => 0.5, m
|
|||||||
2 <= 2; // => 1
|
2 <= 2; // => 1
|
||||||
2 >= 2; // => 1
|
2 >= 2; // => 1
|
||||||
|
|
||||||
// La lógica funiona en enteros
|
// La lógica funiona en enteros
|
||||||
!3; // => 0 (not lógico)
|
!3; // => 0 (not lógico)
|
||||||
!0; // => 1
|
!0; // => 1
|
||||||
1 && 1; // => 1 (and lógico)
|
1 && 1; // => 1 (and lógico)
|
||||||
0 && 1; // => 0
|
0 && 1; // => 0
|
||||||
0 || 1; // => 1 (or lógico)
|
0 || 1; // => 1 (or lógico)
|
||||||
0 || 0; // => 0
|
0 || 0; // => 0
|
||||||
|
|
||||||
// ¡Operadores de bits!
|
// ¡Operadores de bits!
|
||||||
~0x0F; // => 0xF0 (Negación)
|
~0x0F; // => 0xF0 (Negación)
|
||||||
0x0F & 0xF0; // => 0x00 (AND)
|
0x0F & 0xF0; // => 0x00 (AND)
|
||||||
0x0F | 0xF0; // => 0xFF (OR)
|
0x0F | 0xF0; // => 0xFF (OR)
|
||||||
0x04 ^ 0x0F; // => 0x0B (XOR)
|
0x04 ^ 0x0F; // => 0x0B (XOR)
|
||||||
@ -177,7 +177,7 @@ if (0) {
|
|||||||
// Mientras el bucle exista
|
// Mientras el bucle exista
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
while (ii < 10) {
|
while (ii < 10) {
|
||||||
printf("%d, ", ii++); // ii++ incrementa ii en uno, después de usar su valor.
|
printf("%d, ", ii++); // ii++ incrementa ii en uno, después de usar su valor.
|
||||||
} // => muestra "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
|
} // => muestra "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -190,7 +190,7 @@ do {
|
|||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// Bucles 'for' también
|
// Bucles 'for' también
|
||||||
int jj;
|
int jj;
|
||||||
for (jj=0; jj < 10; jj++) {
|
for (jj=0; jj < 10; jj++) {
|
||||||
printf("%d, ", jj);
|
printf("%d, ", jj);
|
||||||
@ -207,13 +207,13 @@ printf("\n");
|
|||||||
|
|
||||||
int x_hex = 0x01; // Puedes asignar hexadecimales a variables
|
int x_hex = 0x01; // Puedes asignar hexadecimales a variables
|
||||||
|
|
||||||
// El cambio de tipos intentará mantener sus valores numéricos
|
// El cambio de tipos intentará mantener sus valores numéricos
|
||||||
printf("%d\n", x_hex); // => Muestra 1
|
printf("%d\n", x_hex); // => Muestra 1
|
||||||
printf("%d\n", (short) x_hex); // => Muestra 1
|
printf("%d\n", (short) x_hex); // => Muestra 1
|
||||||
printf("%d\n", (char) x_hex); // => Muestra 1
|
printf("%d\n", (char) x_hex); // => Muestra 1
|
||||||
|
|
||||||
// Los tipos se desbordan sin aviso
|
// Los tipos se desbordan sin aviso
|
||||||
printf("%d\n", (char) 257); // => 1 (El valor máximo de un 'char' es 255)
|
printf("%d\n", (char) 257); // => 1 (El valor máximo de un 'char' es 255)
|
||||||
|
|
||||||
// Los tipos enteros puden cambiarse a tipos de coma flotante, y viceversa
|
// Los tipos enteros puden cambiarse a tipos de coma flotante, y viceversa
|
||||||
printf("%f\n", (float)100); // %f se sustituye por un 'float'
|
printf("%f\n", (float)100); // %f se sustituye por un 'float'
|
||||||
@ -224,28 +224,28 @@ printf("%d\n", (char)100.0);
|
|||||||
// Punteros
|
// Punteros
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
// Un puntero es una variable declarada para almacenar una dirección de
|
// Un puntero es una variable declarada para almacenar una dirección de
|
||||||
// memoria. Su declaración además nos dirá el tipo de dato al que apunta.
|
// memoria. Su declaración además nos dirá el tipo de dato al que apunta.
|
||||||
// Puedes obtener la dirección de memoria de tus variables, y después
|
// Puedes obtener la dirección de memoria de tus variables, y después
|
||||||
// enlazarlas con ellos.
|
// enlazarlas con ellos.
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
printf("%p\n", &x); // Usa & para obtener la dirección de una variable.
|
printf("%p\n", &x); // Usa & para obtener la dirección de una variable.
|
||||||
// (%p se sustituye por un puntero)
|
// (%p se sustituye por un puntero)
|
||||||
// => Muestra alguna dirección de memoria;
|
// => Muestra alguna dirección de memoria;
|
||||||
|
|
||||||
// Los tipos de puntero terminan con * en su declaración
|
// Los tipos de puntero terminan con * en su declaración
|
||||||
int* px; // px es un puntero a un 'int'
|
int* px; // px es un puntero a un 'int'
|
||||||
px = &x; // Almacena la dirección de x en px
|
px = &x; // Almacena la dirección de x en px
|
||||||
printf("%p\n", px); // => Muestra alguna dirección de memoria
|
printf("%p\n", px); // => Muestra alguna dirección de memoria
|
||||||
|
|
||||||
// Para obtener el valor de la dirección a la que apunta un puntero, pon
|
// Para obtener el valor de la dirección a la que apunta un puntero, pon
|
||||||
// * delante para desreferenciarle.
|
// * delante para desreferenciarle.
|
||||||
printf("%d\n", *px); // => Muestra 0, el valor de x y de la dirección a la
|
printf("%d\n", *px); // => Muestra 0, el valor de x y de la dirección a la
|
||||||
// que apunta px
|
// que apunta px
|
||||||
|
|
||||||
// También puedes cambiar el valor al que está apuntando el puntero.
|
// También puedes cambiar el valor al que está apuntando el puntero.
|
||||||
// Tenemos que meter la desreferencia entre paréntesis porque ++ tiene
|
// Tenemos que meter la desreferencia entre paréntesis porque ++ tiene
|
||||||
// prioridad frente a *.
|
// prioridad frente a *.
|
||||||
(*px)++; // Incrementa el valor al que apunta px en 1
|
(*px)++; // Incrementa el valor al que apunta px en 1
|
||||||
printf("%d\n", *px); // => Muestra 1
|
printf("%d\n", *px); // => Muestra 1
|
||||||
@ -267,24 +267,24 @@ int* x_ptr = x_array;
|
|||||||
printf("%d\n", *(x_ptr)); // => Muestra 20
|
printf("%d\n", *(x_ptr)); // => Muestra 20
|
||||||
printf("%d\n", x_array[0]); // => Muestra 20
|
printf("%d\n", x_array[0]); // => Muestra 20
|
||||||
|
|
||||||
// Los punteros aumentan y disminuyen en función de su tipo.
|
// Los punteros aumentan y disminuyen en función de su tipo.
|
||||||
printf("%d\n", *(x_ptr + 1)); // => Muestra 19
|
printf("%d\n", *(x_ptr + 1)); // => Muestra 19
|
||||||
printf("%d\n", x_array[1]); // => Muestra 19
|
printf("%d\n", x_array[1]); // => Muestra 19
|
||||||
|
|
||||||
// Puedes también asigner dinamicamente bloques contiguos de memoria con
|
// Puedes también asigner dinamicamente bloques contiguos de memoria con
|
||||||
// la función malloc de la librería estándard, que toma un entero como
|
// la función malloc de la librería estándard, que toma un entero como
|
||||||
// argumento representando el número de bytes a asignar de la pila.
|
// argumento representando el número de bytes a asignar de la pila.
|
||||||
int* my_ptr = (int*) malloc(sizeof(int) * 20);
|
int* my_ptr = (int*) malloc(sizeof(int) * 20);
|
||||||
for (xx=0; xx<20; xx++) {
|
for (xx=0; xx<20; xx++) {
|
||||||
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx funcionaría también aquí
|
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx funcionaría también aquí
|
||||||
} // Inicializa la memoria a 20, 19, 18, 17... 2, 1 (como 'ints')
|
} // Inicializa la memoria a 20, 19, 18, 17... 2, 1 (como 'ints')
|
||||||
|
|
||||||
// Desreferenciando la memoria que no has asignado te dará resultados
|
// Desreferenciando la memoria que no has asignado te dará resultados
|
||||||
// impredecibles
|
// impredecibles
|
||||||
printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what?
|
printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what?
|
||||||
|
|
||||||
// Cuando hallas acabado con el bloque de memoría malloc, necesitas
|
// Cuando hallas acabado con el bloque de memoría malloc, necesitas
|
||||||
// liberarlo o sino nadie más podrá usarlo hasta que tu programa se cierre
|
// liberarlo o sino nadie más podrá usarlo hasta que tu programa se cierre
|
||||||
free(my_ptr);
|
free(my_ptr);
|
||||||
|
|
||||||
// Las cadenas pueden ser 'arrays' de chars, pero normalmente se
|
// Las cadenas pueden ser 'arrays' de chars, pero normalmente se
|
||||||
@ -294,13 +294,13 @@ char* my_str = "This is my very own string";
|
|||||||
printf("%c\n", *my_str); // => 'T'
|
printf("%c\n", *my_str); // => 'T'
|
||||||
|
|
||||||
function_1();
|
function_1();
|
||||||
} // fin de la función main
|
} // fin de la función main
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Funciones
|
// Funciones
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
// Sintexis de la declaración de funciones:
|
// Sintexis de la declaración de funciones:
|
||||||
// <tipo de retorno> <nombre>(<argumentos>)
|
// <tipo de retorno> <nombre>(<argumentos>)
|
||||||
|
|
||||||
int add_two_ints(int x1, int x2){
|
int add_two_ints(int x1, int x2){
|
||||||
@ -315,13 +315,13 @@ valores.
|
|||||||
Ejemplo: invertidor de cadenas in-situ
|
Ejemplo: invertidor de cadenas in-situ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Una función 'void' no retorna valor
|
// Una función 'void' no retorna valor
|
||||||
void str_reverse(char* str_in){
|
void str_reverse(char* str_in){
|
||||||
char tmp;
|
char tmp;
|
||||||
int ii=0, len = strlen(str_in); // Strlen es parte de la librería
|
int ii=0, len = strlen(str_in); // Strlen es parte de la librería
|
||||||
for(ii=0; ii<len/2; ii++){ // estándard
|
for(ii=0; ii<len/2; ii++){ // estándard
|
||||||
tmp = str_in[ii];
|
tmp = str_in[ii];
|
||||||
str_in[ii] = str_in[len - ii - 1]; // ii-th último 'char'
|
str_in[ii] = str_in[len - ii - 1]; // ii-th último 'char'
|
||||||
str_in[len - ii - 1] = tmp;
|
str_in[len - ii - 1] = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,14 +333,14 @@ printf("%s\n", c); // => ".abeurp anu se otsE"
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Definición de tipos y estructuras
|
// Definición de tipos y estructuras
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
// Los 'Typedefs' pueden ser utilizados para crear alias de tipos.
|
// Los 'Typedefs' pueden ser utilizados para crear alias de tipos.
|
||||||
typedef int my_type;
|
typedef int my_type;
|
||||||
my_type my_type_var = 0;
|
my_type my_type_var = 0;
|
||||||
|
|
||||||
// Las estructuras son sólo grupos de datos.
|
// Las estructuras son sólo grupos de datos.
|
||||||
struct rectangle {
|
struct rectangle {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
@ -365,7 +365,7 @@ void function_1(){
|
|||||||
my_rec_ptr->height = 10; // Lo mismo que (*my_rec_ptr).height = 10;
|
my_rec_ptr->height = 10; // Lo mismo que (*my_rec_ptr).height = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Puedes aplicar un 'typedef' a una estructura por conveniencía.
|
// Puedes aplicar un 'typedef' a una estructura por conveniencía.
|
||||||
typedef struct rectangle rect;
|
typedef struct rectangle rect;
|
||||||
|
|
||||||
int area(rect r){
|
int area(rect r){
|
||||||
@ -376,26 +376,26 @@ int area(rect r){
|
|||||||
// Punteros a Funciones
|
// Punteros a Funciones
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
En tiempo de ejecución, las funciones se localizan en unas direcciones de
|
En tiempo de ejecución, las funciones se localizan en unas direcciones de
|
||||||
memoria concretas. Los punteros a funciones son como cualquier otro
|
memoria concretas. Los punteros a funciones son como cualquier otro
|
||||||
puntero (almacenan una dirección de memoria), pero pueden ser usados para
|
puntero (almacenan una dirección de memoria), pero pueden ser usados para
|
||||||
utilizar funciones directamente, o para pasar 'handlers' (o funciones
|
utilizar funciones directamente, o para pasar 'handlers' (o funciones
|
||||||
'callback') por todos lados.
|
'callback') por todos lados.
|
||||||
Sin embargo, la sintaxis de definición parecera confusa al principio.
|
Sin embargo, la sintaxis de definición parecera confusa al principio.
|
||||||
|
|
||||||
Ejemplo: usar str_reverse desde un puntero
|
Ejemplo: usar str_reverse desde un puntero
|
||||||
*/
|
*/
|
||||||
void str_reverse_through_pointer(char * str_in) {
|
void str_reverse_through_pointer(char * str_in) {
|
||||||
// Define un puntero a una función, llamado f.
|
// Define un puntero a una función, llamado f.
|
||||||
void (*f)(char *); // La armadura debe coincidir exactamente con al función objetivo.
|
void (*f)(char *); // La armadura debe coincidir exactamente con al función objetivo.
|
||||||
f = &str_reverse; // Assigna la dirección de la función (determinado en tiempo de ejecuión)
|
f = &str_reverse; // Assigna la dirección de la función (determinado en tiempo de ejecuión)
|
||||||
(*f)(str_in); // Llamando la función desde el puntero
|
(*f)(str_in); // Llamando la función desde el puntero
|
||||||
// f(str_in); // Esta es una alternativa para llamarla pero con una sintaxis igual de válida.
|
// f(str_in); // Esta es una alternativa para llamarla pero con una sintaxis igual de válida.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tanto tiempo como las armaduras de las funciones coincidan, podrás asignar
|
Tanto tiempo como las armaduras de las funciones coincidan, podrás asignar
|
||||||
cualquier función al mismo puntero.
|
cualquier función al mismo puntero.
|
||||||
Los punteros a funciones son normalmente envueltos en 'typedef' para
|
Los punteros a funciones son normalmente envueltos en 'typedef' para
|
||||||
simplificar su legibilidad, como sigue:
|
simplificar su legibilidad, como sigue:
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user