【问题标题】:How does the '--p' work in for(p=&(*L).elem[(*L).length-1];p>=q;--p)?'--p' 如何在 for(p=&(*L).elem[(*L).length-1];p>=q;--p) 中工作?
【发布时间】:2020-01-22 16:14:22
【问题描述】:

我正在尝试调试以下代码:

Status ListInsert_Sq(SqLIst *L, int i, LElemType_Sq e)
{
    LElemType_Sq *newbase;
    LElemType_Sq *p, *q;

    if(i<1 || i>(*L).length+1)
        return ERROR;                   
    if((*L).length >= (*L).listsize)
    {
        newbase = (LElemType_Sq*)realloc(LElemType_Sq *)realloc((*L).elem, ((*L).listsiz+LISTINCREMENT)*sizeof(LElemType_Sq));
        if(!newbase)
            exit(OVERFLOW);

        (*L).elem = newbase;
        (*L).listsize += LISTINCREMENT; 
     } 

     q = &(*L).elem[i-1];
     for(p=&(*L).elem[(*L).length-1];p>=q;--p)
        *(p+1) = *p;

    *q = e;
    (*L).length++;

    return OK;
} 

这里使用--p 正确吗? 具体来说,我想知道列表的最后一个元素是否会被前一个元素移动或覆盖?

谢谢!

【问题讨论】:

  • *(p+1) = *p 是一个错误,因为它后面没有分号。
  • 嵌套的realloc() 面目全非。
  • 像这样调试源代码是一种惩罚练习。请停止写'聪明',(不可调试),代码:(
  • 小的语法更正,使您的问题更清楚。添加了更多标签
  • 语言中存在-&gt; 是有原因的——你应该使用它,因为它使这样的代码更具可读性。虽然我猜这段代码实际上是某种其他语言的某种机器翻译的输出......

标签: c++ c loops for-loop decrement


【解决方案1】:

重写后,猜测的代码意图如下:


#include <stdlib.h>
#include <string.h>
#include "listmeuk.h"

Status ListInsert_Sq(SqLIst *lp, int index, LElemType_Sq elem)
{
    if(index<1 || index>lp->length+1) return ERROR; // this assumes 1-based indexing
    index--; // transform to zero-based indexing

    if(lp->length >= lp->listsize)
    {
        LElemType_Sq *newbase;
        newbase = realloc(lp->elem, (lp->listsiz+LISTINCREMENT) *sizeof *newbase);
        if(!newbase) exit(OVERFLOW);

        lp->elem = newbase;
        lp->listsize += LISTINCREMENT; 
     } 

    if(index < lp->length) memmove(&(lp->elem[index+1]), &(lp->elem[index]), (lp->length-index) * sizeof lp->elem[0] );

    lp->elem[index] = elem;
    lp->length++;

    return OK; 

} 

【讨论】:

    【解决方案2】:

    这段代码(我在其中添加了缺少的分号):

    for(p=&(*L).elem[(*L).length-1];p>=q;--p)
        *(p+1) = *p;
    

    p 设置为指向数组elem 中最后分配的元素。然后*(p+1) = *p; 将这个最后设置的元素复制到上面新分配的空间(使用realloc 分配)。 (“分配的元素”是指已分配值的元素。)

    然后--p 递减指针以指向前一个元素。 (对指针使用算术以数组元素为单位工作。)然后*(p+1) = *p; 将倒数第二个分配的元素复制到最后一个分配的元素的前一个空间。然后循环以这种方式继续,有效地将每个元素移动到数组的另一空间。

    最终,当索引为i-1 的元素被移动时,循环似乎打算停止,因为q 被设置为具有q = &amp;(*L).elem[i-1]; 的元素的地址。

    但是,它有缺陷。如果i 为1,则q 指向数组的第一个元素,p 最终将到达该元素,--p 将尝试递减p 以指向数组开头之前。 C 标准未定义此尝试的行为。 (这假定L 指向数组的开头。有可能L 指向超出其开头的数组,在这种情况下不会出现此问题。)

    【讨论】:

    • 代码确实与if (i&lt;1) return ERROR 测试,所以似乎有问题的点 i=0 是不可能的......
    • @ChrisDodd:谢谢。我的文字应该说“如果i 是一”而不是“如果i 是零”。我已经纠正了。如果i 是1,这是初始屏幕所允许的,那么q 指向数组的元素0,因为它是用i-1 设置的。那么p会在那个元素之前递减,这是个问题。
    猜你喜欢
    • 2015-08-20
    • 2017-06-01
    • 2013-01-31
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多