El archivo prog.f es el mismo de la carpeta 1_ProgramaFortran-SubrutinasFortran. El archivo subs.c es el mismo de la carpeta 2_ProgramaC-SubrutinasC. El archivo enlace.c permite enlazar el programa Fortran con las funciones C. Nótese que: - En Fortran la transferencia de argumentos se realiza por referencia (excepto en el caso de los argumentos de tipo character). - En C la transferencia de argumentos se realiza normalmente por valor salvo que se indique lo contrario (con el prefijo &), en cuyo caso se realiza por referencia. Se exceptúan los vectores, que se transfieren por referencia (ya que v, v[] y &v[0] son equivalentes). - Los compiladores Fortran no distinguen las mayúsculas de las minúsculas (salvo que contengan una opción de compilación que cambie esta forma de proceder). En particular, el compilador GFortran pasa a minúsculas los nombres de las subrutinas y les añade un guión bajo (carácter "_") al final. En otros compiladores el criterio puede ser diferente (puede que el nombre se pase a mayúsculas o que se añadan o no otros caracteres). - Los compiladores C distinguen las mayúsculas de las minúsculas. El compilador GCC conserva las mayúsculas y minúsculas en los nombres de las funciones. Por ello: - En el programa Fortran las llamadas call BubbleSort(n,v) call HeapSort(n,v) call QuickSort(n,v) se compilan de forma equivalente a las llamadas desde un programa C bubblesort_(&n,&v[0]); heapsort_(&n,&v[0]); quicksort_(&n,&v[0]); - Las funciones C void BubbleSort(int n , double *v) { ... } void HeapSort(int n , double *v) { ... } void QuickSort(int n , double *v) { ... } se compilan tal cual. - Por ello, el programa Fortran no se puede enlazar correctamente con las funciones C, ya que -- El nombre de la función a la que se llama no coincide con el de la función que recibe. -- El primer argumento se transfiere por referencia y se recibe por valor. Soluciones: 1) Modificar las funciones C, de forma que se definan como void bubblesort_(int *n , double *v) { ... /* donde antes aparecía la variable "n" ahora habrá que escribir "*n" */ } void heapsort_(int *n , double *v) { ... /* donde antes aparecía la variable "n" ahora habrá que escribir "*n" */ } void quicksort_(int *n , double *v) { ... /* donde antes aparecía la variable "n" ahora habrá que escribir "*n" */ } Puede ser necesario reprogramar la funcion C si en su interior se modifica el valor de *n, ya que de lo contrario se modificará el valor de n en el programa principal. 2) Añadir las funciones C auxiliares void bubblesort_(int *n , double *v) { void BubbleSort(int, double *); BubbleSort(*n, v); } void heapsort_(int *n , double *v) { void HeapSort(int, double *); HeapSort(*n, v); } void quicksort_(int *n , double *v) { void QuickSort(int, double *); QuickSort(*n, v); } que actuarán como enlace entre el programa Fortran y las funciones C. En esencia, estas funciones auxiliares reciben los dos argumentos (n, v) por referencia y pasan el primero (n) por valor y el segundo (v) por referencia a la función C. No será necesario reprogramar las funciones C aunque en su interior se modifique el valor de n, ya que los valores de n que se reciben serán copias de los valores de n en las funciones de enlace (que son los valores de n en el programa principal).