[英]How to access values from pointers to pointers in C?
我正在编写一个试图在 C 中实现哈希表的程序。它必须使用指向指针的指针作为结构数据类型中的属性。 这是相关结构的代码。
struct node {
char * data;
struct node * next;
};
struct hashtable {
int size;
struct node ** table;
};
问题的第一部分:
我一直在做很多研究来弄清楚指向指针的指针是如何工作的,但我似乎仍然无法理解它。 我发现的每个示例都为第一个和第二个指针分配了两个不同的指针名称。 例如
x = 5;
*p = &x;
**q = &p;
上面的例子“struct node ** table;”怎么样? 在这种情况下,** 表是否与 **q 相同? 在这种情况下 q 、 *q 和 **q 的值是什么? 是 q = 5 然后 *q 和 **q 返回地址还是 **q = 5 和 *q 和 q 存储地址?
问题的第二部分:
如何访问指向另一个函数内的指针的指针? 这是我现在拥有的代码。
struct hashtable * hashtable_new(int size){
struct hashtable *newTable;
if ( size < 1 )
{
return NULL;
printf("Its returning Null.");
}
else
{
newTable = malloc(sizeof(struct hashtable));
newTable -> size = size;
newTable -> table = malloc(sizeof(struct node) * size);
int i;
for (i = 0; i < size; i++ )
{
newTable -> table[i] = NULL;
}
fprintf(stderr, "Table has been created.");
return newTable;
}
};
我不确定我是否理解如何通过 -> 符号访问指针或指向指针的指针。 是“newtable -> table”还是“newtable -> -> table”?
该表的目标本质上是一个 2d 表,其中列表主要是 1D 并且可以扩展到 2D 以处理散列中的冲突。
尾注:
希望我已经提供了足够的信息来使提出这个问题的上下文有意义。 这是我第一次在 stackoverflow 上提问,所以随时问我额外的问题,提供 CC 或标记我在问这个问题时犯的任何错误。
谢谢!
有几种方法可以查看指向指针的指针。 一种方法是如您所描述的
int x = 5;
int *p = &x;
int **q = &p;
毕竟,以下都是正确的:
**q == *p == x == 5
*q == p == &x
q == &p
但是,另一种查看指向指针的指针的方式是将指针视为数组。 例如,假设声明:
int *arr[10];
除非它是sizeof
或一元&
操作数的操作数,否则表达式arr
将从类型“ int *
10 元素数组”转换(“衰减”)到“指向int *
指针”或int **
。
如果你想动态分配一个N
元素的指针数组到struct node
,你会写
struct node **arr = malloc( sizeof *arr * N );
您可以像访问普通数组一样使用[]
下标运算符访问arr
元素。 由于arr
类型为struct node **
,每个arr[i]
类型为struct node *
,因此您可以像这样访问结构的成员:
arr[i]->data = "foo"; // use -> when the LHS is a pointer to a struct or union
arr[i]->next = NULL;
struct hashtable
允许您创建多个哈希表实例,每个实例都有一个size
成员和一个在运行时分配的struct node *
数组,如下所示:
struct hashtable h1;
h1.size = 512;
h1.table = calloc( h1.size, sizeof h1.table ); // calloc initializes all elements of
// h1.table to NULL
if ( !h1.table )
{
// calloc call failed, handle as appropriate
}
您可以像这样在表中插入一个新元素:
/**
* Assumes we know that the string data points to is not already in
* the table. hashfunc is a pointer to the hashing function.
*/
void insert( struct hashtable *h, const char *data, size_t (*hashfunc)(const char *))
{
/**
* Create a new table entry. Remember that table is an array of
* *pointers* to struct node, and that each array element is initially
* NULL. We still need to allocate something for that table entry
* to point *to*.
*/
struct node *newNode = malloc( sizeof *newNode );
if ( !newNode )
{
/**
* Memory allocation for new node failed, handle as appropriate
*/
}
newNode->data = malloc( strlen( data ) + 1 );
strcpy( newNode->data, data );
/**
* Get the table index by computing the hash and modding against the
* table size.
*/
size_t idx = hashfunc( data ) % h->size;
/**
* Insert newNode at the head of the list starting at
* h->table[idx]. In reality you'd probably want to insert
* strings in order, but for a toy example this is good enough.
*/
newNode->next = h->table[idx]; // newNode->next points to the previous head of list
h->table[idx] = newNode; // newNode becomes new head of list.
}
完成后,您的哈希表如下所示:
+---+
h1: | | size
+---+ +---+ +---+---+ +---+---+
| | table ----> | | --> | | | --> | | |
+---+ +---+ +---+---+ +---+---+
| |
+---+ +---+---+
| | --> | | |
+---+ +---+---+ +---+---+ +---+---+
| | --> | | | --> | | | --> | | |
+---+ +---+---+ +---+---+ +---+---+
...
table
指向一个struct node *
数组,每个数组可能指向一个struct node
实例,每个都可能指向另一个struct node
实例。 在上图中,两个字符串散列到table[0]
,一个散列到table[2]
,三个散列到table[3]
。
这是一个可能对您有所帮助的小程序,它可能值得玩一会儿指针并检查它们,输出地址等。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char *p1 = "String of text.";
char **p2;
/**
* We can print the avtual address of *p1 and **p2...
*/
fprintf(stdout, "p1 = %p\n", p1);
fprintf(stdout, "p2 = %p\n", p2);
/**
* Now if we point p2 at p1 we can then check what address
* *p2 points at...
*/
p2 = &p1;
fprintf(stdout, "*p2 = %p\n", *p2);
/**
* So if you think about it, *p2 should be the same at p1
* if we print it as a string:
*/
fprintf(stdout, "p1 is %s\n*p2 is %s\n", p1, *p2);
exit(EXIT_FAILURE);
}
希望这可以帮助。
至于从另一个函数引用结构,如果您将指针传递给该结构,则使用单个 -> 来引用结构的任何成员……但是您正在结构中分配另一个结构 - 使用指针。
说我有
struct one {
char *string;
}
struct two {
struct *one a;
struct one b;
char *whatever;
}
如果有一个指向结构二的指针:
结构二 *t;
并且它的成员 a 分配了一个结构体...然后我会引用一个 using ->
t -> a -> string;
但 b 不是指针,所以你会这样做:
t -> b.string;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.