今天一天的时候都耗在了单链表的操作函数的编写上了,其实本来应该是一件很简单的事情,但是由于一个优先级的错误,导致了我调试了很久
先说下结论,结构体的二级指针在调用时,必须加上括号,因为*(取值)运算优先级是比->来的低的。
再来说下发现过程,写了很久的程序,产生了各种编译错误,排除好多粗心和手误的错误外,还有一个错误让我百思不得解,代码及错误提示为:
错误代码: *L->Node = NULL;
错误提示: [Error] request for member 'next' in something not a structure or union
当然这只是n多同类型错误中的一个,一开始我以为是函数调用的问题,就先将所有函数体都注释掉了,然后将一些涉及到这些错误的语句单独复制到主函数里,结果错误依旧存在。
后来各种查阅资料,无果,当然这里可能是我搜索的关键字不太对,因为我当时的目光一直盯在二级指针的内容上,我一开始始终认为是我的二级指针可能和某个一级指针弄混了,但现在想想,编译器并没有报这类的错误。
然后吃过晚饭,我尝试着将所有的二级指针单独拿出来,就是先定义一个一级指针,再把二级指针的内容赋给一级指针,再去操作一级指针,就像下面这样:
struct Node *n;
n = *L; //L为二级指针
n->data = 0;
奇迹出现了,我这样写了之后,错误提示竟然消失了,这时我才意识到,可能是我在二级指针的调用上出了问题,于是去百度了“结构体二级指针的调用”,在CSDN的论坛的一个帖子里看到了这样的一行代码:
(*ppA)->name = "ddddddd"
我恍然大悟,去查了一下C语言运算符的优先级列表,发现 * 的优先级果然没有 -> 高,顿觉自己像个白痴。。。。。。
经过这件事,我学到了以下几点:
1. * 的优先级没有 -> 高。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuUWei9CX0xWdhZWZk9CX09Wbl9lcvRXakVGa49CXy9GdpRWZoh3LcRXZu5ibkN3Yuc2bsJmLjlGdhR3cvw1LcpDc0RHaiojIsJye.gif)
2.对于不知道优先级的运算,要加上括号才保险。
3.要多阅读他人的代码。
最后,附上C语言运算符优先级表:
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | 后置++ | 后置自增运算符 | 变量名++ | 左到右 | |
后置-- | 后置自减运算符 | 变量名-- | |||
[ ] | 数组下标 | 数组名[整型表达式] | |||
( ) | 圆括号 | (表达式)/函数名(形参表) | |||
. | 成员选择(对象) | 对象.成员名 | |||
-> | 成员选择(指针) | 对象指针->成员名 | |||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | (数据类型)表达式 | |||
前置++ | 前置自增运算符 | ++变量名 | 单目运算符 | ||
前置-- | 前置自减运算符 | --变量名 | 单目运算符 | ||
* | 取值运算符 | *指针表达式 | 单目运算符 | ||
& | 取地址运算符 | &左值表达式 | 单目运算符 | ||
! | 逻辑非运算符 | !表达式 | 单目运算符 | ||
~ | 按位取反运算符 | ~表达式 | 单目运算符 | ||
sizeof | 长度运算符 | sizeof 表达式/sizeof(类型) | |||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | 双目运算符 | ||
% | 余数(取模) | 整型表达式%整型表达式 | 双目运算符 | ||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 表达式<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 表达式>>表达式 | 双目运算符 | ||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | 双目运算符 | ||
< | 小于 | 表达式<表达式 | 双目运算符 | ||
<= | 小于等于 | 表达式<=表达式 | 双目运算符 | ||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | 双目运算符 | ||
8 | & | 按位与 | 整型表达式&整型表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 整型表达式^整型表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 整型表达式|整型表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
/= | 除后赋值 | 变量/=表达式 | |||
*= | 乘后赋值 | 变量*=表达式 | |||
%= | 取模后赋值 | 变量%=表达式 | |||
+= | 加后赋值 | 变量+=表达式 | |||
-= | 减后赋值 | 变量-=表达式 | |||
<<= | 左移后赋值 | 变量<<=表达式 | |||
>>= | 右移后赋值 | 变量>>=表达式 | |||
&= | 按位与后赋值 | 变量&=表达式 | |||
^= | 按位异或后赋值 | 变量^=表达式 | |||
|= | 按位或后赋值 | 变量|=表达式 | |||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | 从左向右顺序运算 |