Estoy tratando de escribir una función recursiva ( printPath
) dentro de otra función ( dijkstraSSSP
), pero me da un error de compilación.
Cuando ejecuto gcc dijkstra.c WGraph.c PQueue.c
, se compila perfectamente. Sin embargo, cuando ejecuto dcc -Wall -Werror -std=c11 -o dijkstra dijkstra.c WGraph.c PQueue.c
. Recibí este error:
dijkstra.c:48:38: error: function definition is not allowed here void printPath (int currentNode) {
Lo cual creo que es porque defino una función dentro de otra función. Si este es el caso, ¿cómo debo modificar el código? ¡Muchas gracias!
void dijkstraSSSP(Graph g, Vertex source) { int dist[MAX_NODES]; int pred[MAX_NODES]; bool vSet[MAX_NODES]; // vSet[v] = true <=> v has not been processed int s, t; PQueueInit(); int nV = numOfVertices(g); for (s = 0; s < nV; s++) { joinPQueue(s); dist[s] = VERY_HIGH_VALUE; pred[s] = -1; vSet[s] = true; } dist[source] = 0; int relaxWeight; for (s = 0; s < numOfVertices(g); s++) { s = leavePQueue(dist); //printf("iterating with s = %d\n", s); //printf("updating vSet[%d] = false\n", s); vSet[s] = false; for (t = 0; t < numOfVertices(g); t++) { //printf("iterating with t = %d\n", t); //printf("checking if s = %d is adj to t = %d and vSet[%d] = true\n", s, t, t); if (adjacent(g, s, t) != 0 && vSet[t] == true) { //printf("YES\n"); relaxWeight = adjacent(g, s, t); if (dist[t] > dist[s] + relaxWeight) { //printf("updating dist[%d] = dist[%d] + adjWeight[%d]\n", t, s, relaxWeight); dist[t] = dist[s] + adjacent(g, s, t); //printf("updating pred[%d] = %d\n", t, s); pred[t] = s; } } } } void printPath (int currentNode) { if (pred[currentNode] == -1) { printf("%d", currentNode); return; } else { printPath (pred[currentNode]); printf("-%d", currentNode); } } for (int i = 0; i < numOfVertices(g); i++) { if (dist[i] == VERY_HIGH_VALUE) { printf("%d: no path\n", i); } else{ printf("%d: distance = %d, shortest path: ", i, dist[i]); printPath(i); printf("\n"); } } }
La definición de una función dentro de otra función no está definida en el Estándar C. gcc lo permite como una extensión, pero la mayoría de los compiladores no lo hacen.
Debe mover la definición de printPath
fuera del cuerpo de la función dijkstraSSSP
, antes de ella en el código fuente, y pasar pred
como argumento adicional:
void printPath(const int *pred, int currentNode) { if (pred[currentNode] == -1) { printf("%d", currentNode); } else { printPath(pred, pred[currentNode]); printf("-%d", currentNode); } } void dijkstraSSSP(Graph g, Vertex source) { int dist[MAX_NODES]; int pred[MAX_NODES]; bool vSet[MAX_NODES]; // vSet[v] = true <=> v has not been processed int s, t; PQueueInit(); int nV = numOfVertices(g); for (s = 0; s < nV; s++) { joinPQueue(s); dist[s] = VERY_HIGH_VALUE; pred[s] = -1; vSet[s] = true; } dist[source] = 0; int relaxWeight; for (s = 0; s < numOfVertices(g); s++) { s = leavePQueue(dist); //printf("iterating with s = %d\n", s); //printf("updating vSet[%d] = false\n", s); vSet[s] = false; for (t = 0; t < numOfVertices(g); t++) { //printf("iterating with t = %d\n", t); //printf("checking if s = %d is adj to t = %d and vSet[%d] = true\n", s, t, t); if (adjacent(g, s, t) != 0 && vSet[t] == true) { //printf("YES\n"); relaxWeight = adjacent(g, s, t); if (dist[t] > dist[s] + relaxWeight) { //printf("updating dist[%d] = dist[%d] + adjWeight[%d]\n", t, s, relaxWeight); dist[t] = dist[s] + adjacent(g, s, t); //printf("updating pred[%d] = %d\n", t, s); pred[t] = s; } } } } for (int i = 0; i < numOfVertices(g); i++) { if (dist[i] == VERY_HIGH_VALUE) { printf("%d: no path\n", i); } else{ printf("%d: distance = %d, shortest path: ", i, dist[i]); printPath(pred, i); printf("\n"); } } }
Mueva la definición de printPath
fuera del cuerpo de dijkstraSSSP
y, para darle acceso a pred
, cámbiela para aceptar dos parámetros en lugar de uno. El parámetro adicional debe tener el tipo int *
y debe apuntar al primer elemento de pred
.
En la llamada, pase pred
para ese nuevo parámetro. La matriz pred
se convertirá automáticamente en un puntero a su primer elemento.