例如:
void DeleteLastNode(NodeType **L)
如果** L代表变量L的地址,那么它是否可以不用& L代替?另外,如果我使用* L或只是L,我是否能够改变L'的内容?如果是这样,使用* L和L的区别是什么,如果L是指向它的指针呢?我是否只能通过发送L并在实际方法中使用* L来查看它的内容?
我想我的指针仍然不太好。
答案 0 :(得分:5)
据我所知,一个星号表示C中的普通指针。例如,您可以分配内存并使指针指向新分配的区域。您还可以指向堆栈中的变量,如:
int x = 10;
int *p = &x;
但是在某些情况下,您希望将指针传递给函数,并使该函数能够将指针更改为指向另一个地址。现在我们不是在谈论通过指针改变变量的内容,也不是通过它指向的内存来改变变量的内容,但是文学会改变指针信息(这是一个mem。地址)来指向另一个地方。在这种情况下,我们使用指向由双星号表示的指针的指针。
int x, y;
int *p;
int **pp;
pp = &p; //pp points to pointer p
*pp = &x; //pp changes pointer p to point to variable x
*p = 10; //p (now points to x) assigns value 10 to x
*pp = &y; //pp changes pointer p again assigning the address of y
*p = 20; //p assigns 20 to y;
**pp = 25;// that's tricky, the first * give access to the address pointed by p (&y) the second changes the content of that address to 25. so now y ends with 25
最后x = 10且y = 25
现在特别针对您的情况,该函数调用看起来像一个将从链表中删除节点的函数。这是有道理的,因为你有一个指向列表头部的外部指针。删除最后一个元素时,函数必须能够将指针从当前地址更改为null。您可以使用全局指针或在您的情况下传递头指针的地址。
答案 1 :(得分:1)
让我们清楚一些事情。从技术上讲,L是指向NodeType实例的指针。但是,函数的名称提供了不同的解释:可能L是指向数组的指针的地址或NodeType实例的链接列表(您必须参考函数的文档来验证这一点)。
如果是这种情况,那么函数通常会像这样使用:
NodeType *list = malloc (5 * sizeof(NodeType));
/* do something with the list, e.g. put entries into it */
DeleteLastNode (&list); /* delete last node in list */
该函数可能会修改指向数组/列表的变量,这就是为什么你必须将 list 的地址传递给函数。
但是要说具体的话,我们需要有关DeleteLastNode()的更多信息。
答案 2 :(得分:0)
不,不在C中,函数体中的星号不能替换为函数体中的&符号(&
)。在C ++中,它是另一回事。人们认为有些类似的想法,并在决定C ++的功能时添加了这个功能。
答案 3 :(得分:0)
可能有助于理解的东西
NodeType **L
表示L是指向NodeType对象的指针。
例如,如果是
NodeType *P
然后P是指向NodeType对象的指针,如果P是0xE0101010,并且每个NodeType对象是80字节,则P + 1将是0xE0101060(0xE0101010加0x50 = 0xE0101060)。
然后让我们看看L,它指向NodeType的指针。如果我们认为指针是4个字节,那么如果L是0xE0202020,而L + 1将只是0xE0202024。
因此,只要涉及指针算术,使用正确的类型就很重要。注意L [3]与*(L + 3)相同,因此L [3]涉及指针算术,因此指针类型需要非常精确,否则当你查看指针所指向的内容时通过* L,即调用解除引用,然后可能发生分段错误(Unix / Linux)或GP错误(Windows)。
答案 4 :(得分:0)
NodeType nt;
NodeType *pnt = &nt;
-------- ------
| pnt |-------->| nt |
-------- ------
此处pnt
(pnt
的内容)为&nt
; *pnt
为nt
。
NodeType **L = &pnt;
------ -------- ------
| L |------->| pnt |-------->| nt |
------ -------- ------
现在L
(L
的内容)为&pnt
; *L
是pnt
;因此**L
为*pnt
,即nt
。请注意,*&
相互取消(*L -> *&pnt -> pnt
)。
答案 5 :(得分:0)
如果** L代表变量L的地址,那么它不能被& L代替吗?
**L
表示L
指向的位置所指向的位置处的值。为了说明,假设以下声明:
int a = 1;
int * pa = & a; // whitespace doesn't matter here
int **ppa = &pa;
ppa
指向pa
,a
又指向1
,其值为*
。这是一个假设的记忆图,显示了它们之间的关系(假设是32位整数,大端):
Object Address 0x00 0x01 0x02 0x03 ------ ------- ---------------------- a 0x10008000 0x00 0x00 0x00 0x01 pa 0x10008004 0x10 0x00 0x80 0x00 ppa 0x10008008 0x10 0x00 0x80 0x04
在声明符中,*
运算符表示此变量是指针并保存另一个变量的地址。在表达式中,&
运算符生成指针指向的值。在 C ++ 声明符中,&
运算符表示此变量是引用并且是同义词对于另一个变量(它不一定与指针相同; C不允许声明符中的&
)。在表达式中,{{1}}运算符生成其操作数的地址。
因此,按照上面的内存映射,以下所有内容都是正确的:
a == 1; * pa == 1; // again, whitespace doesn't matter here. **ppa == 1; &a == 0x10008000; pa == 0x10008000; *ppa == 0x10008000; &pa == 0x10008004; ppa == 0x10008004; &ppa == 0x10008008;