【问题标题】:"Illegal use of selector" in CC中的“非法使用选择器”
【发布时间】:2015-01-30 18:27:21
【问题描述】:

作为一个更大项目的一部分,我正在尝试编写一个 C 函数,该函数在已实现的排序链表中搜索结构 olnode 中的值。但是,我收到了一些错误。我是 C 新手,我正在为指针和双指针以及何时使用什么而苦苦挣扎,所以我认为这是问题的一部分,但我不确定如何解决这个问题。包括所有必要的标题。这是在使用 cc 作为编译器的 Minix 2.0.4 上。

我可以提供任何额外的必要代码;因为我对 C 不熟悉,所以我不确定我需要展示多少,所以我提供我认为需要的内容,仅此而已。

全局代码(标题除外):

#define POOLSZ 53
struct olnode {
    int eventnr;
    int eventfq;
    struct olnode *next;
};
typedef struct olnode olnode;
olnode pool[POOLSZ];
olnode *avail;    /* points to first available node */

返回错误的函数(搜索传递的 int,完成后 *current 应该是保存当前值的 olnode):

void
srchfreq(olnode *list, int xfrequency, olnode **current)
{
    olnode *previous, *newnext;

    while(current->eventfq > xfrequency) {
        *previous = &current;
        *newnext = current->next;
        *current = *newnext;
    }
}

srchfreq() 的函数调用(在不同的函数中):

/* *list points to the first node in the list
   (*current).eventfq is the value being searched for
*/

srchfreq(*list, (*current).eventfq, &current);

错误(行号被编辑为相对于srchfreq() 中的行,如上所述):

line 6: illegal use of selector eventfq
line 7: cannot convert pointer to struct
line 8: illegal use of selector next
line 8: cannot convert pointer to struct
line 9: cannot convert struct to pointer

【问题讨论】:

    标签: c cc minix


    【解决方案1】:
    void
    srchfreq(olnode *list, int xfrequency, olnode **current)
    {
        olnode *previous, *newnext;
    
        while((*current)->eventfq > xfrequency) {
            previous = *current;
            newnext = (*current)->next;
            *current = newnext;
        }
    }
    

    第二部分取决于参数的类型。如果list 声明为olnode *list,则无需取消引用它,因为函数需要一个指针。第二个和第三个参数是错误的(其中一个 - 确定我们需要知道哪一个是如何声明 current 的)。

    【讨论】:

    • list最初声明为olnode *list;current被声明为olnode *current;
    • 那么最后一行应该是srchfreq(list, (*current)->eventfq, &current);。这意味着current 被正确设置为第一个元素,当然。
    • 声明*current后,下一行是*current = **list;olnode **list 是传递给调用srchfreq() 的函数(称为A())的内容,A() 是声明current 的内容。我试图理解指针的概念;我不太明白将*s 添加到参数中如何改变该参数在函数中的作用。如果current*current 而不是现有的**current 传递给srchfreq(),那将如何改变事情? (不一定在代码方面,但在概念上。)
    • 您的搜索结果必须保存在某处。搜索的结果是一个指针。出于某种原因,您选择使用输出参数而不是返回值 - 这很奇怪,但完全可以。但是在 C 中,所有参数都是按值传递的——这意味着你的函数可以修改它们,但调用方永远不会看到变化。要实际更改某些内容,请将指针传递到要保存结果的位置。您想要的结果类型是olnode*,因此指向olnode* 的指针将是olnode**。这里的一般建议是“除非你需要,否则不要添加额外的指针层(因此额外的 *)”。
    • 不,不是这样。您希望指针结果为current,因此其类型应为olnode*(因此传递给函数的&current 变为olnode**),因此函数可以更改此指针的值。但它也会在更改之前读取其值,因此您需要正确设置值。如果两种类型都是olnode*,则为current=list。基本上,&current 的类型是olnode**,但*current 的类型是olnode - * 运算符对于变量声明及其用法具有不同的含义。 cdecl 可以帮助你理解概念。
    【解决方案2】:

    current 的类型为olnode**,或指向oldnode 的指针。要获取指向 olnode 的指针,请取消引用该指针一次:

    *current;
    

    要获取 olnode 本身,请取消引用您从取消引用指向指针的指针中获得的指针

    **current;
    

    所以在你的情况下,抢占eventfq的字段

    (**current).eventfq
    

    C 还提供了一个快捷方式,其中操作(*ptr).field 完全等同于prt->field

    在你的情况下,你可以应用这个

    (*current)->eventfq
    

    【讨论】:

      【解决方案3】:

      错误,按出现顺序:

      • 由于current 是指向olnode 的指针到指针,它不能直接引用任何字段;但*current 可以。
      • *previous 是一个olnode&current 是一个指向一个指向olnode 的指针的指针。
      • 查看第一个错误
      • *newnextolnode
      • *current 是指向 olnode 的指针

      【讨论】:

      • 我来自 Python 和 Java;我试图围绕指针的概念来思考。 current**current 的形式传递给函数。因此,如果我理解正确,它有两个*s 使其成为指向指针的指针。那么为什么添加第三个* 会使其直接引用olnode?我认为这会使它成为指向指针的指针,尽管您说这就是 &current 的含义。 (我正在努力解决这个问题,如果这表明你错了,我深表歉意。我真的不知道,所以我不想那样做。)
      • * 是取消引用运算符:跟随指针。 (而且,正如您似乎意识到的那样,& 是相反的运算符,因此 *&xx 相同。)因此声明 clnode **current 应该读作“clnode 是你得到的在取消引用current 两次后”。
      猜你喜欢
      • 2013-06-03
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2015-06-10
      相关资源
      最近更新 更多