2010-10-18 25 views
1

例如:了解在方法定义在C使用星号的数目?

void DeleteLastNode(NodeType **L) 

如果** L表示变量L的地址,可以在不被&大号代替取代?另外,如果我要使用* L或者仅仅使用L,我是不是可以改变L的内容?如果是这样,如果L是指向它的指针,那么使用* L和L有什么区别?我只能通过发送L并在实际方法中使用* L来查看它的内容吗?

我想我还没有与指针太好。

+1

宾基将帮助你肯定的:http://www.youtube.com/watch?v=mnXkiAKbUPg – 2010-10-18 15:11:04

+0

宾基太棒了 – pmg 2010-10-18 15:21:44

回答

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。你可以使用全局指针来完成它,或者像你的情况那样,传递头指针的地址。

0

不,不是在C,在函数头部星号不能被用在函数体代替符号(&)代替。但在C++中,这是另一回事。当人们决定使用C++的功能时,人们想到了一些类似的想法并添加了这个功能。

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 */ 

功能可能会修改变量指向数组/列表,这就是为什么你必须通过的地址列表的功能。

但要说具体的话,我们需要更多关于DeleteLastNode()的信息。

0

东西可能有助于理解

NodeType **L 

装置L是指针的NodeType对象的指针。

例如,如果它是

NodeType *P 

那么P是一个指向的NodeType对象,并且如果P是0xE0101010,并且每个节点类型对象是80个字节,则P + 1将0xE0101060(0xE0101010加0x50 = 0xE0101060)。

然后我们来看看L,它是指向NodeType指针的指针。如果我们考虑一个指针是4字节,那么如果L是0xE0202020,并且L + 1将只是0xE0202024。

因此,每当涉及指针算术时,使用正确的类型非常重要。请注意,L [3]与*(L + 3)相同,因此L [3]涉及指针算术,因此指针类型需要非常精确,否则当您查看指针指向的内容时到by * L,这是调用解引用,然后可能发生分段错误(Unix/Linux)或GP错误(Windows)。

0
NodeType nt; 
NodeType *pnt = &nt; 

--------   ------ 
| pnt |-------->| nt | 
--------   ------ 

这里,pnt(的pnt含量)&nt; *pntnt

NodeType **L = &pnt; 

------  --------   ------ 
| L |------->| pnt |-------->| nt | 
------  --------   ------ 

现在L(的L含量)&pnt; *Lpnt;因此**L*pnt,即nt。请注意0​​彼此取消*L -> *&pnt -> pnt)。

0
如果** L表示变量L的地址,是否不能用&L替换?

**L表示在由L指向的位置所指向的位置处的。为了说明,假设下面的声明:

int  a = 1; 
int * pa = & a; // whitespace doesn't matter here 
int **ppa = &pa; 

ppapa,这反过来又指向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不允许在所述&声明符)。在表达式中,运算符产生其操作数的地址地址

所以,通过以上的存储器映射去,以下所有条件都为真:

 
    a == 1; 
* pa == 1; // again, whitespace doesn't matter here. 
**ppa == 1; 

    &a == 0x10008000; 
    pa == 0x10008000; 
*ppa == 0x10008000; 

    &pa == 0x10008004; 
    ppa == 0x10008004; 

&ppa == 0x10008008;