Golang代码重写:如何将Go代码转换为C语言

Golang代码重写:如何将Go代码转换为C语言 目前正在将用Go语言编写的加权有向无环图转换为C代码,该图已经过拓扑排序。作为Go语言的初学者,我遗漏了部分代码,如下所示。在topoSort函数中,我不理解"visit"声明是什么。这是在一个函数内部声明另一个函数吗?另一个部分是在main函数中(如下所示),不理解循环过程中"rowIndex, row, number"变量的作用,它们如何获取值,以及循环中的range关键字。如果能粗略地转换成C语法(可能是伪代码)或简要说明,将非常有帮助。

func (g *graph) topoSort() []int {
    result := make([]int, g.size())
    marks := make([]bool, g.size())
    resultIndex := g.size() - 1

    var visit func(int)
    visit = func(u int) {
        for _, item := range g.adjList[u] {
            if !marks[item.vertex] {
                visit(item.vertex)
            }
        }

        marks[u] = true
        result[resultIndex] = u
        resultIndex--
    }

    for u := range g.adjList {
        if !marks[u] {
            visit(u)
        }
    }

    return result
}
func sampleInput() [][]int{
	return [][]int{
		[]int{1},
		[]int{8, 4},
		[]int{2, 6, 9},
		[]int{8, 5, 9, 3},
	}
}
input := sampleInput()
i := 0
	for rowIndex, row := range input {
		for _, number := range row {
			if rowIndex+1 >= len(input) { // Last row.
				g.addEdge(i, vertexesQuantity, number)
			} else { // Not the last row.
				g.addEdge(i, i + rowIndex + 1, number)
				g.addEdge(i, i + rowIndex + 2, number)
			}

			i++
		}
	}

更多关于Golang代码重写:如何将Go代码转换为C语言的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

感谢您的贡献。我想请问,您是否有可能在main()方法中用C代码可视化"for循环"?如果您能实现的话就太好了。

更多关于Golang代码重写:如何将Go代码转换为C语言的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


可能是:

	#include <stdbool.h> 
	#include <stdlib.h> 

	struct _item {
		int vertex;	
	};

	struct graph {
		int size;
		struct _item**adjList;
	};

	int* topoSort (struct graph* g ){
		int* result = (int*) malloc(g->size*sizeof(int));
		bool* marks = (bool*) malloc(g->size*sizeof(bool));
		int resultIndex = g->size-1;

		void visit(int u){
			for (int i;i<(sizeof g->adjList[u] / sizeof g->adjList[u][0]);i++) {
				struct _item item = g->adjList[u][i];
				if (!marks[item.vertex]) {
					visit(item.vertex);

				}
			}
			marks[u]=true;
			result[resultIndex] = u;
			resultIndex--;
		}
		for (int u;u<(sizeof g->adjList / sizeof g->adjList[0]);u++) {
			if (!marks[u]) {
				visit(u);
			}
		}

		return result;

	}

在Go中,visit确实是在函数内部声明的另一个函数,这称为闭包(closure)。它捕获了外部作用域的变量(resultmarksresultIndexg)。在C语言中,由于不支持嵌套函数,需要通过结构体和显式传递参数来模拟这种行为。

以下是topoSort函数的C伪代码实现:

#include <stdbool.h>

typedef struct {
    int vertex;
    // other edge properties if needed
} Edge;

typedef struct {
    Edge** adjList;
    int size;
} Graph;

void visit(Graph* g, int u, bool* marks, int* result, int* resultIndex) {
    for (int i = 0; i < g->adjList[u].length; i++) {
        int vertex = g->adjList[u][i].vertex;
        if (!marks[vertex]) {
            visit(g, vertex, marks, result, resultIndex);
        }
    }
    
    marks[u] = true;
    result[*resultIndex] = u;
    (*resultIndex)--;
}

int* topoSort(Graph* g) {
    int* result = malloc(g->size * sizeof(int));
    bool* marks = calloc(g->size, sizeof(bool));
    int resultIndex = g->size - 1;
    
    for (int u = 0; u < g->size; u++) {
        if (!marks[u]) {
            visit(g, u, marks, result, &resultIndex);
        }
    }
    
    free(marks);
    return result;
}

对于循环部分,Go的range关键字在C中对应传统的for循环:

// Go的 range input 循环转换为C
int input[4][4] = {
    {1, -1, -1, -1},        // 用-1填充未使用的位置
    {8, 4, -1, -1},
    {2, 6, 9, -1},
    {8, 5, 9, 3}
};
int inputSizes[4] = {1, 2, 3, 4};  // 每行的实际长度

int i = 0;
for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
    for (int colIndex = 0; colIndex < inputSizes[rowIndex]; colIndex++) {
        int number = input[rowIndex][colIndex];
        
        if (rowIndex + 1 >= 4) { // Last row
            g_addEdge(i, vertexesQuantity, number);
        } else { // Not the last row
            g_addEdge(i, i + rowIndex + 1, number);
            g_addEdge(i, i + rowIndex + 2, number);
        }
        
        i++;
    }
}

在Go的range循环中:

  • rowIndex是切片/数组的索引(0, 1, 2, 3…)
  • row是对应索引处的元素值
  • number是内层循环中当前行的每个元素值

C语言实现需要显式管理数组边界,因为C数组没有内置的长度信息。

回到顶部