0

我正在编写一个函数来查找链表的长度。我的问题特定于指针的声明。

int lengthOfLinkedList(Node *head) 
{ 
Node* current = head; 
}

vs. 

int lengthOfLinkedList(Node *head) 
{
Node* current = NULL; 
current = head; 
}

所以这是我的理解:在第一个示例中,声明了一个指向 Node 对象的指针,并且它取消了对头指针的地址的引用。


| 内存地址 | <--- 当前


这不是我想做的。相反,我想推迟指针,以便我可以访问它指向的节点(这是我在第二个代码片段中所做的):


|数据| *下一个| <--- 当前


所以现在我认为指针在初始化它们时会有所不同 - 当您使用 ('*') 运算符初始化它时,您可以直接声明指向内存地址的指针,但在初始化后您不能再这样做了。这很奇怪。。

我是对的还是有其他事情发生?

4

4 回答 4

8

这两个片段是完全等价的;在这两种情况下*都不解引用运算符(就像它出现在表达式中一样),但它只是用于声明指针的标记。换句话说,这里*逻辑上1Node(指定类型Node*,即“指向Node2的指针),而不是与current

(对于两个完全不同的事物(声明中的指针说明符,表达式3中的一元运算符)这种令人困惑的重用相同字符来自于 C 具有“声明应该模仿用法”的想法,因此,因为要访问您使用的指针*,它甚至用于声明它们。)

在第一种情况下,current从头开始具有相同的值head,在第二种情况下,首先将其初始化为NULL,然后更改为具有相同的值head; 在这两种情况下,函数结束时的结果完全相同。


  1. 可悲的是,在语法上它与current,因为在声明中“指针类型说明符”绑定到特定变量;即,如果您编写int * ptr1, ptr2;,ptr1将是 type int *,而ptr2将是 plain int

  2. 指针声明最好从右向左阅读(const char *:指向字符常量的指针;char * const:指向字符的常量指针;等等);更一般的声明(例如函数指针)更加混乱

  3. 此外,二元乘法运算符,但通常不会混淆(它适用于不同的类型并放在两个操作数之间)。

于 2013-09-13T15:57:51.360 回答
1

在这两个示例中都没有取消引用。两者都只是将传递的指针分配给一个新变量,然后在函数退出时将其丢弃。

考虑这个序列

int x = 0;
x = 2;

对比

int x = 2;
于 2013-09-13T15:56:37.977 回答
0

初始化赋值不是一回事;您没有在初始化中取消引用current*仅表示具有指针类型,仅此current而已。

C 和 C++ 声明语法基于表达式的类型,而不是对象。例如,如果您有一个指向整数的指针,并且想要获取该整数值,则必须使用一元运算符取消引用该指针*

x = *p;

表达式 的类型*pint,所以它的声明p

int *p;

在声明中,*令牌只是用来提供额外的类型信息;即,这p是一个指向的指针int。需要注意的是,对于指针声明T *p*绑定到声明符,而不是类型说明符。IOW,T *p;被解析为T (*p);. 因此,如果要在单个声明中声明多个指针,则必须编写

T *p, *q, *r;

在这种情况下,每个pqr都是指向 type 的指针T

很多 C++ 程序员都使用这种T* p;风格,因为他们觉得强调对象的类型更重要p,而且有时它会使代码的意图更加清晰。但是,它将始终被解析为T (*p);.

于 2013-09-13T19:51:22.907 回答
-1

为了帮助将指针声明与取消引用分开,请考虑在取消引用时使用箭头运算符->。例如,*current.data等价于current->data; current->next会给你当前的下一个指针指向的节点。

于 2013-09-13T16:23:46.550 回答