typedef structelt*Stack;为什么这里有一个*
typedef struct elt *Stack; why is there a * here
这是使用链表实现Stack的完整代码。这是詹姆斯·阿斯普内斯为耶鲁大学撰写的数据结构笔记(有什么好的吗?(
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct elt {
struct elt *next;
int value;
};
/*
* We could make a struct for this,
* but it would have only one component,
* so this is quicker.
*/
typedef struct elt *Stack;
#define STACK_EMPTY (0)
/* push a new value onto top of stack */
void
stackPush(Stack *s, int value)
{
struct elt *e;
e = malloc(sizeof(struct elt));
assert(e);
e->value = value;
e->next = *s;
*s = e;
}
int
stackEmpty(const Stack *s)
{
return (*s == 0);
}
int
stackPop(Stack *s)
{
int ret;
struct elt *e;
assert(!stackEmpty(s));
ret = (*s)->value;
/* patch out first element */
e = *s;
*s = e->next;
free(e);
return ret;
}
/* print contents of stack on a single line */
void
stackPrint(const Stack *s)
{
struct elt *e;
for(e = *s; e != 0; e = e->next) {
printf("%d ", e->value);
}
putchar('n');
}
int
main(int argc, char **argv)
{
int i;
Stack s;
s = STACK_EMPTY;
for(i = 0; i < 5; i++) {
printf("push %dn", i);
stackPush(&s, i);
stackPrint(&s);
}
while(!stackEmpty(&s)) {
printf("pop gets %dn", stackPop(&s));
stackPrint(&s);
}
return 0;
}
我能理解大部分代码。但我无法理解这部分typedef struct elt *Stack;
为什么Stack前面有一个*,它是什么意思?
我发现指针的概念很难理解,尤其是在函数的返回类型中。提前谢谢。
我能理解大部分代码。但我无法理解本部分typedef structelt*Stack;
那是使用typedef*。这只是意味着当你写
Stack x;
在你的代码中,它的意思是:
struct elt * x;
但是,如果您使用
Stack *s;
在您的代码中,它将意味着:
struct elt ** s;
我发现了指针的概念,尤其是在功能难以掌握。提前谢谢。
然后,我建议您在继续使用该代码之前,先了解指针和指向指针的指针。
*我认为C和C++中的typedef有一些细微的区别:请参阅此处
我发现指针的概念很难理解,尤其是在函数的返回类型中。提前谢谢。
这比这里所能涵盖的要多一些;给自己找一个好的教程(如果存在这样的东西的话(,然后从那里开始工作。然而,这里有一些事情需要记住:
- 在指针声明中,
*
运算符始终绑定到声明符,而不是类型说明符。例如,声明
被解析为int* x, y, z;
IOW,只有int (*x), y, z;
x
被声明为指针。如果您也想将y
和z
声明为指针,则必须编写int *x, *y, *z;
- 一元
*
和&
运算符的优先级低于后缀运算符(如[]
、()
和成员选择运算符(,因此:T *x[N]; // declares x as an N-element array of pointers to T T (*x)[N]; // declares x as a pointer to an N-element array of T T *f(); // declares f as a function returning pointer to T T (*f)(); // declares f as a pointer to a function returning T *a.b == *(a.b) // dereferences a.b *a->b == *(a->b) // dereferences a->b &a.b == &(a.b) // takes the address of a.b &a->b == &(a->b) // takes the address of a->b a->b == (*a).b // dereferences a, then accesses b
- 没有单一的指针类型;相反,有许多不同的指针类型,并且大多数指针类型彼此不兼容
;如果函数需要int *
类型的参数,那么如果您传递int **
(或int (*)[N]
、int **
或float *
等(类型的参数时,它会抱怨。void *
类型是"泛型"指针类型,但不能直接使用它(不能取消引用void *
,也不能对其进行指针运算(。在C中,可以将void *
值分配给任何指针对象,反之亦然,而无需强制转换;C++需要对all
指针类型转换进行强制转换。 - 一元
-
阵列不是指针
。数组下标运算是根据指针算术定义的:
我们从地址a[i] == *(a + i);
a
偏移i
元素(而不是字节(,并取消引用结果。但是,如果数组不是指针,这是如何工作的呢?除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则类型为"T
的N元素数组"的表达式将被转换("decay"(为类型为"指向T
的指针"的表达式,并且表达式的值将是数组第一个元素的地址。因此,当我们写入a[i]
时,数组表达式a
被转换为指针类型,并且我们从该指针偏移。请注意,对象a
未被转换;它始终是一个数组对象。
相关文章:
- 警告处理为错误这里有什么问题
- 有一个打印语句的函数是一种糟糕的编程实践吗
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 有没有可能有一个只有ADL才能找到的非好友功能
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 在学习数据结构之前对STL有一个了解是好的吗?
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 如何在 Gnuplot 中分别绘制 2 个文件数据?我有一个文件"sin.txt",另一个文件"cos.txt",我想将它们分别绘制在一个图表上
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 我的输出中有一个额外的 0,为什么会这样
- 节点是否为空,即使它有一个值?
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 这里有一个错误:"string subscript is out of range"
- "类"在这里有一个先前的声明
- 这是一个普遍的参考吗?std::forward在这里有意义吗?
- 为什么这里有一个端序问题
- typedef structelt*Stack;为什么这里有一个*