c - 为什么我需要双指针?
问题描述
我不明白为什么我需要在“结构图”中使用双指针。是因为它允许我访问我在函数 makeGraph() 中创建的节点之一吗?
如果我使用一个指针(结构节点 *adjList),那么我无法将节点设置为我在 makeGraph() 中创建的 NULL。
我从 programiz.com 获得了代码,在解释此代码的文章中它说:不要让 struct node** adjList 压倒你。我们所说的只是我们想要存储一个指向 struct node* 的指针。这是因为我们不知道图形将有多少个顶点,因此我们无法在编译时创建链接列表数组。
如果我这样做: graph->adjList[1] 它是转到第二个节点的地址还是转到节点内部?(我说的是我在 makeGraph() 中创建的节点)
我理解其余的代码。如果有人可以帮助我,将不胜感激。
#include <stdlib.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node **adjList; // <--- THIS ONE
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(sizeof(struct graph));
graph->numVertices = vertices;
graph->adjList = malloc(sizeof(struct node) * vertices); // creating the nodes
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
void addEdge(struct graph *graph, int src, int dest) // Add Edge
{
struct node *newNode = makeNode(dest);
newNode->next = graph->adjList[src];
graph->adjList[src] = newNode;
struct node *newNode2 = makeNode(src);
newNode2->next = graph->adjList[dest];
graph->adjList[dest] = newNode2;
return;
int main()
{
struct graph *graph1 = makeGraph(4);
addEdge(graph1, 0, 1);
addEdge(graph1, 0, 2);
addEdge(graph1, 0, 3);
}
解决方案
邻接表被表示为 的链表struct node
。通过指向列表第一个元素的指针访问列表。(指针将NULL
在列表为空时。)指针的类型为struct node *
。
该图具有在 的numVertices
成员中设置的多个顶点struct graph
。每个顶点都需要一个邻接表,每个邻接表都需要一个struct node *
. struct node *
所以图需要一个长度数组numVertices
。代码的作者选择动态分配数组作为成员指向的单独内存块adjList
。成员的类型adjList
是指向元素类型的指针。元素类型是struct node *
所以adjList
成员的类型是struct node **
。
还有另一种方法可以为struct graph
及其邻接表分配内存。adjList
通过将成员更改为灵活数组成员,可以将它们分配为单个块,如下所示:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
struct node
{
int vertex;
struct node *next;
};
struct graph
{
int numVertices;
struct node *adjList[]; // <--- FLEXIBLE ARRAY MEMBER
};
struct graph *makeGraph(int vertices) // Creating a Graph
{
struct graph *graph = malloc(offsetof(struct graph, adjList[vertices]));
graph->numVertices = vertices;
for (int i = 0; i < vertices; i++)
graph->adjList[i] = NULL; // Setting all nodes to NULL
return graph;
}
offsetof(struct graph, adjList[vertices])
是从 astruct graph
的地址到adjList[vertices]
数组成员元素的地址的偏移量,以字节为单位。分配该大小的内存块刚好足以容纳struct graph
指针数组的加号。另一种指定大小的方法是sizeof(struct graph) + vertices * sizeof(struct node *)
or sizeof(struct graph) + vertices * sizeof(graph->adjList[0])
,但我认为使用offsetof
宏是指定大小的更简洁的方法。
推荐阅读
- azure - While creating a yaml pipeline, can we commit yaml file to a branch other than master?
- android - (android) 当我在 xml 布局中声明一个片段时,我无法在片段中获取数据
- python - 有效地查找非零RGB像素python
- gtsummary - tbl_summary ( gtsummary) 转置 p 值
- python - Python 脚本使用 cron 作业运行了好几周,现在它给出了 KeyError
- java - 如何生成数组的 100 个随机排列以存储在 ArrayList 中
- c++ - libgsl.so.25:无法打开共享对象文件:没有这样的文件或目录 Google Colab 项目
- c - 如何检查socket绑定的IP地址是否还存在?
- python - 读取多个文件,搜索字符串并存储在列表中
- java - Java中的InputMismatchException替换while循环