Attention! Your ePaper is waiting for publication!
By publishing your document, the content will be optimally indexed by Google via AI and sorted into the right category for over 500 million ePaper readers on YUMPU.
This will ensure high visibility and many readers!
✐ ✐ ✐ “Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 128 — #166 ✐ Capítulo 3. C <strong>en</strong> <strong>C++</strong> Para repasar, «empezar <strong>en</strong> el medio» («funcPtr es un ...», va a la derecha (nada aquí - pare <strong>en</strong> el paréntesis derecho), va a la izquierda y <strong>en</strong>cu<strong>en</strong>tra el * («... puntero a ...»), va a la derecha y <strong>en</strong>cu<strong>en</strong>tra la lista de argum<strong>en</strong>tos vacía («... función que no ti<strong>en</strong>e argum<strong>en</strong>tos ...») va a la izquierda y <strong>en</strong>cu<strong>en</strong>tra el void («funcPtr es un puntero a una función que no ti<strong>en</strong>e argum<strong>en</strong>tos y retorna void»). Quizá se pregunte porqué *funcPtr necesita paréntesis. Si no los usara, el compilador podría ver: void *funcPtr(); Lo que corresponde a la declaración de una función (que retorna un void*) <strong>en</strong> lugar de definir una variable. Se podría p<strong>en</strong>sar que el compilador sería capaz distinguir una declaración de una definición por lo que se supone que es. El compilador necesita los paréntesis para «t<strong>en</strong>er contra qué chocar» cuando vaya hacia la izquierda y <strong>en</strong>cu<strong>en</strong>tre el *, <strong>en</strong> lugar de continuar hacia la derecha y <strong>en</strong>contrar la lista de argum<strong>en</strong>tos vacía. 3.10.2. Declaraciones y definiciones complicadas Al marg<strong>en</strong>, una vez que <strong>en</strong>ti<strong>en</strong>da cómo funciona la sintáxis de declaración de C y <strong>C++</strong> podrá crear elem<strong>en</strong>tos más complicados. Por ejemplo: //: V1C03:ComplicatedDefinitions.cpp /* 1. */ void * (*(*fp1)(int))[10]; /* 2. */ float (*(*fp2)(int,int,float))(int); /* 3. */ typedef double (*(*(*fp3)())[10])(); fp3 a; /* 4. */ int (*(*f4())[10])(); int main() {} Estudie cada uno y use la regla derecha-izquierda para <strong>en</strong>t<strong>en</strong>derlos. El número 1 dice «fp1 es un puntero a una función que toma un <strong>en</strong>tero como argum<strong>en</strong>to y retorna un puntero a un array de 10 punteros void». El 2 dice «fp2 es un puntero a función que toma tres argum<strong>en</strong>tos (int, int y float) de retorna un puntero a una función que toma un <strong>en</strong>tero como argum<strong>en</strong>to y retorna un float» Si necesita crear muchas definiciones complicadas, debería usar typedef. El número 3 muestra cómo un typedef ahorra t<strong>en</strong>er que escribir una descripción complicada cada vez. Dice «Un fp3 es un puntero a una función que no ti<strong>en</strong>e argum<strong>en</strong>tos y que retorna un puntero a un array de 10 punteros a funciones que no ti<strong>en</strong><strong>en</strong> argum<strong>en</strong>tos y retornan doubles». Después dice «a es una variable de ese tipo fp3». typedef es útil para construir descripciones complicadas a partir de otras simples. El 4 es una declaración de función <strong>en</strong> lugar de una definición de variable. Dice «f4 es una función que retorna un puntero a un array de 10 punteros a funciones que retornan <strong>en</strong>teros». 128 ✐ ✐ ✐ ✐
✐ ✐ ✐ “Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 129 — #167 ✐ 3.10. Direcciones de función Es poco habitual necesitar declaraciones y definiciones tan complicadas como éstas. Sin embargo, si se propone <strong>en</strong>t<strong>en</strong>derlas, no le desconcertarán otras algo m<strong>en</strong>os complicadas pero que si <strong>en</strong>contrará <strong>en</strong> la vida real. 3.10.3. Uso de un puntero a función Una vez que se ha definido un puntero a función, debe asignarle la dirección de una función antes de poder usarlo. Del mismo modo que la dirección de un array arr[10] se obti<strong>en</strong>e con el nombre del array sin corchetes (arr), la dirección de una función func() se obti<strong>en</strong>e con el nombre de la función sin lista de argum<strong>en</strong>tos (func). También puede usar una sintáxis más explícita: &func(). Para invocar la función, debe derefer<strong>en</strong>ciar el puntero de la misma forma que lo ha declarado (recuerde que C y <strong>C++</strong> siempre int<strong>en</strong>tan hacer que las definiciones se parezcan al modo <strong>en</strong> que se usan). El sigui<strong>en</strong>te ejemplo muestra cómo se define y usa un puntero a función: //: C03:PointerToFunction.cpp // Defining and using a pointer to a function #include using namespace std; void func() { cout