数据结构作业复盘2:结构体&指针的小问题

数据结构第二次的作业的内容还是指针和结构体为主,有很多小细节想和大家分享。

致命的运算符位置与优先级

毫不夸张地说,作业的选择题基本上全是错的这个问题。++运算符的前与后虽然很小,但是在某些时候是致命的错误。来看几个例子:(大家可以不看答案先自己选)

若有以下定义,则数值不为3的表达式是
int x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, *p1;
(A) x[3]
(B) p1 = x + 3, *p1++
(C) p1 = x + 2, *(p1++)
(D) p1 = x + 2, *++p1

第一个题目的关键是就是这个++运算符在哪的问题,易错的可能会是B选项,以为p1++之后就变成了4,所以不对。其实挖的坑就在这里,错误原因其实是我们对++运算符前后位置关系的影响不清楚。

对于p++,虽然进行了++操作,但是当你再使用*来对其中的内容进行调用的时候,p其实没有变,也就是说怕p的值在你进行调用的时候还没变,只是有一个++的操作在里面,等到下一次,在不同的语句中你调用他的时候才会前移。大家可以想一想我们烂熟于心的for(int i=0;i<n;i++)语句,你有没有想过明明都进行++操作了,可是你在后面的循环中使用i的时候,i还是当前的位置,没有向前进?这就是++在变量后面的本质,当在同一个语句/一个循环中使用++并调用该变量时,使用时其值是没有改变的。

这样的话问题就好解释了,C选项最终的值其实还是2,而D选项,由于++是在前面,因此调用的时候,p的值就会按照向前移一位的值来进行调用,因此是对的。

总结一下,++在前面,调用时其值不会变化;++在后面,调用时,其值就会按照+1之后的值来进行使用。

下面再来看一下有关运算符优先级的一个问题。

若有以下说明和语句:
struct student{
  int age;
  int num;
}std, *p;
p = &std;
则以下对结构变量 std 中成员 age 的引用方式不正确的是
(A) std.age
(B) p->age
(C) (*p).age
(D) *p.age

主要问题还是在D选项上,其实说实话我也对优先级的问题一直不知道,下面这篇文章很详细地给出了优先级表以及结合顺序(也很重要)。

原文链接:C语言运算符优先级(超详细)

针对上面的问题,D选项中我们可以知道,"."这个运算符是优先级最高的,而*这个运算符是在第二级的,因此如果不加括号,就会先是p与age结合,这很明显是错的。

在结构体和指针相关的问题里面,可以记下面几个顺序:"."和"->"以及() 大于   "*"(作为取值符),''&"(作为取址符)”++和--“  大于  加减乘除。

当处于同一级的运算符在一起的时候,需要考虑他们结合的方向。比如*和++是处于一级的,而且结合顺序是从右向左,因此*p++(p是一个指针),代表的是先把指针进行++操作,再进行取值,而不是先对p指针进行取值,然后再把这个值进行+1的操作。

谢谢大家阅读,希望我遇到的问题也能给你一点帮助哦~~~

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用结构指针完成数据结构2中线性表的基本操作的示例代码: ```c #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #define MAXSIZE 100 typedef struct { int data[MAXSIZE]; int length; } SqList; // 初始化线性表 void InitList(SqList *L) { L-&gt;length = 0; } // 插入元素 int ListInsert(SqList *L, int pos, int elem) { if (pos &lt; 1 || pos &gt; L-&gt;length + 1 || L-&gt;length &gt;= MAXSIZE) { return 0; } for (int i = L-&gt;length; i &gt;= pos; i--) { L-&gt;data[i] = L-&gt;data[i - 1]; } L-&gt;data[pos - 1] = elem; L-&gt;length++; return 1; } // 删除元素 int ListDelete(SqList *L, int pos) { if (pos &lt; 1 || pos &gt; L-&gt;length) { return 0; } for (int i = pos - 1; i &lt; L-&gt;length - 1; i++) { L-&gt;data[i] = L-&gt;data[i + 1]; } L-&gt;length--; return 1; } // 查找元素 int GetElem(SqList *L, int pos, int *elem) { if (pos &lt; 1 || pos &gt; L-&gt;length) { return 0; } *elem = L-&gt;data[pos - 1]; return 1; } // 输出线性表 void PrintList(SqList *L) { for (int i = 0; i &lt; L-&gt;length; i++) { printf(&quot;%d &quot;, L-&gt;data[i]); } printf(&quot;\n&quot;); } int main() { SqList L; InitList(&amp;L); ListInsert(&amp;L, 1, 1); ListInsert(&amp;L, 2, 2); ListInsert(&amp;L, 3, 3); ListInsert(&amp;L, 4, 4); printf(&quot;插入元素后:&quot;); PrintList(&amp;L); ListDelete(&amp;L, 2); printf(&quot;删除元素后:&quot;); PrintList(&amp;L); int elem; GetElem(&amp;L, 2, &amp;elem); printf(&quot;查找到的元素为:%d\n&quot;, elem); return 0; } ``` 该代码定义了一个结构SqList,包括一个整型数组data和一个整型变量length,用于存储线性表的元素和长度。 然后定义了InitList()、ListInsert()、ListDelete()、GetElem()和PrintList()等函数,分别对应线性表的初始化、插入元素、删除元素、查找元素和输出线性表等基本操作。这些函数中,参数L是一个指向SqList结构指针,使用指针来操作结构中的数据。 最后,在main函数中,创建了一个SqList类型的变量L,并调用各个函数来进行基本操作,并输出结果。 需要注意的是,在插入和删除元素时,需要检查插入或删除的位置是否合法,以及线性表是否已满或为空。在查找元素时,也需要检查查找的位置是否合法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值