练习5-13

前面的声明先暂时不提.
主代码块首先判断参数数量.
如果参数数量为1则是默认的.
else if多路判定,参数数量为2并且第二个参数首字符((++argv)[0]这个之前也说过.首先取值++argv就是第二参数的地址,引用运算符,对++argv地址的值进行引用,然后[0]数组下标零,第一个元素.),是负号,那么将之后的数值赋值给n.(这里这个很绕啊,这里argv已经在判断式那里进行了自增,所以这里的argv直接指向的就是参数那里,先argc是参数的值,[0]是参数的第一个参数负号-这里有个问题就是为什么不直接用[1]而用的是+1,+1是将当前指针向下一个位置.当前那个argv肯定是参数-开头.因为判断式中已经自增到那并且判断为真才进行的操作.)
最后那个是错误情况,
然后是处理错误参数情况.
将lineptr数组初始化.
分配缓冲区 ,并将起始地址赋值给buf和p,如果等于空字符NULL的话(表示错误)则输出错误信息.
计算得出空间结束地址bufend.
初始化两个变量,
读取输入行,如果大于0(有效行).
首先判断缓冲区是否有足够的空间存放输入行.
如果没有则将指针p重新指到缓冲区的开头.
linrptr是指针数组,数组的每个元素都是字符串首字符的地址.因此将指针p保存到lineptr中.
然后将数组line(读取的输入行),复制给以指针p为开头的空间(这个解释起来有点麻烦,直接去看strcpy函数的说明比较好)
因为LINES是最大处理行数,所以lineptr指针数组的元素超过LINES的话,就需要将记录下标的变量last归零重新计数,这样就会将从最开始的输入行开始覆盖。而一直保留最后输入的100行(LINES)。
当前指针的位置p,加上当前的输入字符数len,(+1是因为要指向下一个起点。否则指向的则是当前行的最后一个字符。)指针p指向下一个起始点。
记录总输入行的变量自增。
参数的值不应该大于总输入行,这是肯定的。如果大于则将其值改为总输入行的数量。
计算得到需要输出的最开始的那一行的下标。因为总输入行减去需要输出的行数,那么得到的就是剩余的行数,从这个剩余的行开始输出就可以。
因为last会被清零,所以会得到个负数,而last虽然被清零但是也还在计数,相当于100+之后的,所以将当前这个负数加上100就是需要输出的行的起点了。
然后是输出,这里前面不重要,都很正常,后面那个对LINES取模是因为如果输入行超出了最大行LINES,那么将从嘴开头覆盖,取模的话会同步从最开头输出。这将完美解决不能从头打印的问题。

你可能感兴趣的:(练习5-13)